/[drupal]/contributions/modules/radioactivity/radioactivity.inc
ViewVC logotype

Contents of /contributions/modules/radioactivity/radioactivity.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Thu Aug 28 20:23:29 2008 UTC (14 months, 4 weeks ago) by skiminki
Branch: MAIN
CVS Tags: DRUPAL-5--1-2-RC2, DRUPAL-5--1-2, HEAD
Branch point for: DRUPAL-5, DRUPAL-6--1
Changes since 1.1: +11 -4 lines
File MIME type: text/x-php
Fix for issue #301241
1 <?php
2 /*
3 * Some radioactivity functions that may be called from other modules, even when the main radioactivity
4 * is not loaded. For instance, radioactivity_node utilizes this in radioactivity_node_exit.
5 */
6
7 /**
8 * Returns target object classes. Objects of target classes may receive energy.
9 */
10 function radioactivity_get_radioactivity_info($reset_cache=FALSE) {
11 static $info;
12
13 if ($reset_cache || !isset($info)) {
14 $info = array('targets' => array(), 'sources' => array());
15 foreach (module_implements('radioactivity_info') as $name) {
16 $function = $name .'_radioactivity_info';
17 $result = $function();
18 if (isset($result) && is_array($result)) {
19 $info = array_merge_recursive($info, $result);
20 }
21 }
22 }
23
24 return $info;
25 }
26
27 /**
28 * Retrieves decay profiles in array. The array key is decay profile id (positive int) and the value is the decay
29 * profile. The profile is array as follows:
30 * "label" -> The profile label
31 * "description -> The profile description
32 * "half_life" -> The radioactivity half-life (in seconds)
33 */
34 function _radioactivity_get_decay_profiles() {
35 $decay_profiles=variable_get("radioactivity_profiles", array());
36
37 return $decay_profiles;
38 }
39
40 function _radioactivity_possibly_remap_id($oid, $oclass) {
41 static $map=array();
42 if (!isset($map[$oclass][$oid])) {
43 $info=radioactivity_get_radioactivity_info();
44 $function=$info['targets'][$oclass]['id_mapper'];
45 if ($function) {
46 $new_oid=$function($oid, $oclass);
47 } else {
48 $new_oid=$oid;
49 }
50 $map[$oclass][$oid]=$new_oid;
51 }
52 return $map[$oclass][$oid];
53 }
54
55 /**
56 * Resolve full class name for a specific object. This utilizes subclass resolver if defined.
57 */
58 function _radioactivity_resolve_classname($oid, $oclass) {
59 static $map=array();
60
61 if (!isset($map[$oclass][$oid])) {
62 $info=radioactivity_get_radioactivity_info();
63 $function=$info['targets'][$oclass]['subclass_resolver'];
64 if ($function) {
65 $subclass=$function($oid, $oclass);
66 if ($subclass) {
67 $classname=$oclass.':'.$subclass;
68 } else {
69 $classname=$oclass;
70 }
71 } else {
72 $classname=$oclass;
73 }
74 $map[$oclass][$oid]=$classname;
75 }
76 return $map[$oclass][$oid];
77 }
78
79 /**
80 * Return energies for source action.
81 * @param $oid
82 * @param $oclass Base class, e.g. 'node'. Subclass will be resolved by subclass_resolver hook if necessary
83 * @param $source Energy source, e.g. 'view'
84 * @return array of dpid to energy, e.g, array(1 => 3.4, 2 => 5.6);
85 */
86 function radioactivity_get_energies_for_source($oid, $oclass, $source) {
87 $ret=array();
88 foreach (_radioactivity_get_decay_profiles() as $dpid => $decay_profile) {
89 $classname=$oclass; // the default class name
90
91 // check if we need to resolve full classname
92 if (is_array($decay_profile['energy'][$oclass]['subclasses'])) {
93 foreach ($decay_profile['energy'][$oclass]['subclasses'] as $subsources) {
94 if (isset($subsources[$source])) {
95 // there is subclass specific energy value for the source, so
96 // resolve subclass
97 $classname=_radioactivity_resolve_classname($oid, $oclass);
98 break;
99 }
100 }
101 }
102
103 // resolve energy amount
104 $energy=$decay_profile['energy'];
105 $value=0;
106 $classparts=explode(':', $classname);
107
108 foreach ($classparts as $part) {
109 if (!is_array($energy[$part])) break;
110 $energy=$energy[$part];
111 $value_cand=$energy[$source];
112 if (strlen($value_cand)>0) $value=(double)$value_cand;
113 $energy=$energy['subclasses'];
114 }
115
116 $ret[$dpid]=$value;
117 }
118 return $ret;
119 }
120
121 // this is the MySQL optimized version
122 function _radioactivity_add_energy_mysql($oid, $oclass, $dpid, $amount, $timestamp) {
123 db_query("INSERT INTO {radioactivity} (id, class, decay_profile, energy, last_emission_timestamp) ".
124 "VALUES (%d, '%s', %d, %f, %d) ON DUPLICATE KEY UPDATE energy=energy+%f",
125 $oid, $oclass, $dpid, $amount, $timestamp, $amount);
126 }
127
128 // standards compliant version
129 function _radioactivity_add_energy_std($oid, $oclass, $dpid, $amount, $timestamp) {
130 db_query("UPDATE {radioactivity} SET energy=energy+%f ".
131 "WHERE id=%d AND class='%s' AND decay_profile=%d", $amount, $oid, $oclass, $dpid);
132
133 if (db_affected_rows()==0) {
134 // No new rows, try update again and insert one if necessary.
135 // Note that we do the second update inside lock table to be certain that there wasn't insert
136 // after the last update.
137
138 db_lock_table("radioactivity");
139 $result=db_query("UPDATE {radioactivity} SET energy=energy+%f ".
140 "WHERE id=%d AND class='%s' AND decay_profile=%d", $amount, $oid, $oclass, $dpid);
141
142 if (db_affected_rows()==0) {
143 db_query("INSERT INTO {radioactivity} (id, class, decay_profile, energy, last_emission_timestamp) ".
144 "VALUES (%d, '%s', %d, %f, %d)",
145 $oid, $oclass, $dpid, $amount, $timestamp);
146 }
147 db_unlock_tables();
148 }
149 }
150
151 /**
152 * Add energy to nodes.
153 * @param $oid Object id
154 * @param $oclass Object base class, e.g. 'node'. Subclass will be resolved if necessary
155 * @param $source Energy source, e.g. 'view'
156 * @return TRUE if successful
157 */
158 function radioactivity_add_energy($oid, $oclass, $source) {
159 $db_type=$GLOBALS['db_type'];
160 $timestamp=time();
161
162 $energies=radioactivity_get_energies_for_source($oid, $oclass, $source);
163
164 foreach ($energies as $dpid => $amount) {
165
166 if ($amount==0) continue;
167
168 // remap id if necessary
169 $oid=_radioactivity_possibly_remap_id($oid, $oclass);
170
171 switch ($db_type) {
172 case 'mysql':
173 case 'mysqli':
174 _radioactivity_add_energy_mysql($oid, $oclass, $dpid, $amount, $timestamp);
175 break;
176
177 case 'pgsql':
178 _radioactivity_add_energy_std($oid, $oclass, $dpid, $amount, $timestamp);
179 break;
180
181 default:
182 watchdog('radioactivity', t('Unsupported database: @db_type', array('@db_type' => $db_type)), WATCHDOG_ERROR);
183 break;
184 }
185 }
186
187 return TRUE;
188 }

  ViewVC Help
Powered by ViewVC 1.1.2