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

Contents of /contributions/modules/radioactivity/radioactivity.module

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


Revision 1.18 - (show annotations) (download) (as text)
Thu Aug 28 19:46:47 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.17: +2 -173 lines
File MIME type: text/x-php
Move radioactivity_add_energy and related functions from radioactivity.module
to radioactivity.inc. Utilize radioactivity.inc in radioactivity_node.module.
This is a fix for issue #301230.
1 <?php
2 /*
3 * Advanced node popularity by radioactivity model
4 */
5
6 DEFINE('RADIOACTIVITY_PERM_ADMIN', 'administer radioactivity');
7
8 require_once 'radioactivity.inc';
9
10
11 function radioactivity_perm() {
12 return array(RADIOACTIVITY_PERM_ADMIN);
13 }
14
15 function radioactivity_help($section='') {
16
17 $output = '';
18
19 switch ($section) {
20 case "admin/help#radioactivity":
21 $output = '<p>'. t("This module makes nodes radioactive! User activity increases radioactivity of a node ".
22 "while time decays the radioactivity. The radioactivity is halved after a half-life period. The radioactivity is suitable for ".
23 "better node activity metrics. Views support is built-in."). '</p>';
24 break;
25 }
26
27 return $output;
28 }
29
30 function radioactivity_menu($may_cache) {
31 $items = array();
32 if ($may_cache) {
33 $items[] = array('path' => 'admin/settings/radioactivity',
34 'title' => t('Radioactivity'),
35 'description' => t('Configure settings for radioactivity.'),
36 'callback' => 'drupal_get_form',
37 'callback arguments' => array('radioactivity_admin_general_form'),
38 'access' => user_access(RADIOACTIVITY_PERM_ADMIN),
39 'type' => MENU_NORMAL_ITEM);
40 $items[] = array('path' => 'admin/settings/radioactivity/general',
41 'title' => t('General'),
42 'description' => t('Configure settings for radioactivity.'),
43 'callback' => 'drupal_get_form',
44 'callback arguments' => array('radioactivity_admin_general_form'),
45 'access' => user_access(RADIOACTIVITY_PERM_ADMIN),
46 'weight' => 0,
47 'type' => MENU_DEFAULT_LOCAL_TASK);
48 $items[] = array('path' => 'admin/settings/radioactivity/list_profiles',
49 'title' => t('Decay profiles'),
50 'description' => t('List of decay profiles.'),
51 'callback' => 'drupal_get_form',
52 'callback arguments' => array('radioactivity_admin_profile_list'),
53 'access' => user_access(RADIOACTIVITY_PERM_ADMIN),
54 'weight' => 1,
55 'type' => MENU_LOCAL_TASK);
56 $items[] = array('path' => 'admin/settings/radioactivity/profile_new',
57 'title' => t('New profile'),
58 'description' => t('Add new decay profile.'),
59 'callback' => 'drupal_get_form',
60 'callback arguments' => array('radioactivity_admin_profile_form', 0),
61 'access' => user_access(RADIOACTIVITY_PERM_ADMIN),
62 'weight' => 2,
63 'type' => MENU_LOCAL_TASK);
64 } else {
65 // decay profile edit pages, cannot be cached
66 if (arg(0)=='admin' && arg(1)=='settings' && arg(2)=='radioactivity' &&
67 substr(arg(3),0,8)=='profile_' && is_numeric(substr(arg(3),8))) {
68 $decay_profile_id=substr(arg(3),8);
69 $decay_profiles=_radioactivity_get_decay_profiles();
70 $decay_profile=$decay_profiles[$decay_profile_id];
71
72 $items[] = array('path' => 'admin/settings/radioactivity/profile_'.$decay_profile_id,
73 'title' => t('Edit decay profile @label', array('@label'=>$decay_profile["label"])),
74 'description' => t('Configure settings for decay profile @label.', array('@label'=>$decay_profile["label"])),
75 'callback' => 'drupal_get_form',
76 'callback arguments' => array('radioactivity_admin_profile_form', $decay_profile_id),
77 'access' => user_access(RADIOACTIVITY_PERM_ADMIN),
78 'weight' => 3,
79 'type' => MENU_LOCAL_TASK);
80 $items[] = array('path' => 'admin/settings/radioactivity/profile_'.$decay_profile_id.'/delete',
81 'title' => t('Delete profile'),
82 'callback' => 'drupal_get_form',
83 'callback arguments' => array('radioactivity_admin_delete_profile_form', $decay_profile_id),
84 'access' => user_access(RADIOACTIVITY_PERM_ADMIN),
85 'type' => MENU_CALLBACK);
86 }
87
88 }
89
90 return $items;
91 }
92
93 function _radioactivity_set_decay_profiles($decay_profiles) {
94 // invalidate views cache (if views-module exists on this site)
95 if (function_exists('views_invalidate_cache')) {
96 views_invalidate_cache();
97 }
98
99 return variable_set("radioactivity_profiles", $decay_profiles);
100 }
101
102 function _radioactivity_get_decay_granularity() {
103 $granularity=(int)variable_get('radioactivity_decay_granularity', 0);
104 if ($granularity<=0) $granularity=600;
105 return $granularity;
106 }
107
108 function radioactivity_admin_general_form() {
109
110 $form=array();
111
112 $form['radioactivity_decay_granularity']=
113 array('#type' => 'textfield',
114 '#title' => t('Decay granularity (in seconds)'),
115 '#description' => t('This setting determines how often at most the radioactivity is decreased by the decay formula. '.
116 'The shorter the time, the more accurate the modeling will be, but the more database '.
117 'activity is required. The default (10 minutes) should be good starting point.'),
118 '#size' => 10,
119 '#required' => TRUE,
120 '#default_value' => _radioactivity_get_decay_granularity());
121
122 return system_settings_form($form);
123 }
124
125 function radioactivity_admin_profile_list() {
126 $form=array();
127
128 $decay_profiles=_radioactivity_get_decay_profiles();
129
130 $profile_rows=array();
131 foreach ($decay_profiles as $dpid => $decay_profile) {
132 $profile_rows[]=array('data' => array($dpid, check_plain($decay_profile["label"]),
133 '<a href="'.url('admin/settings/radioactivity/profile_'.$dpid).'">'.t("Edit").'</a>'));;
134 }
135
136 $profiles_table=theme('table',
137 array(t('Id'), t('Label'), t('Actions')),
138 $profile_rows);
139
140 $form['profiles_table']=array('#value' => $profiles_table);
141
142 return $form;
143 }
144
145 function _radioactivity_oclassdef_to_form($oclass, $name, $def, $sources, $energy, $level=0) {
146 $form=array('#type' => 'fieldset',
147 '#tree' => TRUE,
148 '#collapsible' => TRUE,
149 '#title' => t('Energy settings for @oclass', array('@oclass' => $name)));
150 $collapsed=TRUE;
151
152 if (count($sources)==0) {
153 $form['no_sources']=
154 array('#type' => 'item',
155 '#value' => t('You must enable at least one plug-in that provides an energy source for this target class.'));
156 }
157
158 if ($level==0 && is_array($def['subclasses'])) {
159 $form[]=array('#type' => 'item',
160 '#value' => t('The default settings for #type.',
161 array('#type' => $name)));
162 } elseif ($level>0) {
163 $form[]=array('#type' => 'item',
164 '#value' => t('Specific settings for #type. Empty field uses setting from parent.',
165 array('#type' => $name)));
166 }
167
168 foreach ($sources as $source => $sdef) {
169 $energy_value=$energy[$source];
170 $form[$source]=
171 array('#type' => 'textfield',
172 '#title' => t('Incident energy from %s', array('%s' => $sdef['title_placeholder'])),
173 '#default_value' => $energy_value);
174 if (strlen($energy_value)>0) $collapsed=FALSE;
175 }
176
177 if (is_array($def['subclasses'])) {
178 foreach ($def['subclasses'] as $subclass => $subclassdef) {
179 $form['subclasses'][$subclass]=_radioactivity_oclassdef_to_form($subclass, $name.' / '.$subclass, $subclassdef, $sources,
180 $energy['subclasses'][$subclass], $level+1);
181 if (!$form['subclasses'][$subclass]['#collapsed']) $collapsed=FALSE;
182 }
183 }
184
185 $form['#collapsed']=$collapsed;
186
187 return $form;
188
189 }
190
191 function radioactivity_admin_profile_form($dpid) {
192
193 $form=array();
194
195 if (!(int)$dpid) $dpid=-1;
196
197 $form[]=
198 array('#type' => 'item',
199 '#title' => t('Profile id'),
200 '#value' => $dpid>0? $dpid : t('Unassigned'));
201
202 $form['decay_profile_id']=
203 array('#type' => 'hidden',
204 '#value' => $dpid );
205
206 if ($dpid>0) {
207 $decay_profiles=_radioactivity_get_decay_profiles();
208 $decay_profile=$decay_profiles[$dpid];
209 unset($decay_profiles);
210 } else {
211 // defaults for new
212 $decay_profile=array('half_life' => 6*3600,
213 'cut_off_energy' => 0.5,
214 'energy' => array('node' => array('view' => 1)));
215 }
216
217 $form['label']=
218 array('#type' => 'textfield',
219 '#title' => t('Profile label'),
220 '#required' => TRUE,
221 '#description' => t('The profile label. Used in views, links, etc'),
222 '#default_value' => $decay_profile['label']);
223
224 $form['description']=
225 array('#type' => 'textarea',
226 '#title' => t('Description'),
227 '#description' => t('The description of the profile.'),
228 '#default_value' => $decay_profile['description']);
229
230 $form['half_life']=
231 array('#type' => 'textfield',
232 '#title' => t('Half-life of the radioactivity in seconds'),
233 '#required' => TRUE,
234 '#description' => t('Determines the decay rate of the radioactivity. For exaple, if the decay rate is '.
235 '3600 (one hour), the radioactivity halves once an hour. If it is now 1000, it will '.
236 'be 500 after an hour, 250 after two hours, and so on. The default is 6 hours.'),
237 '#default_value' => $decay_profile['half_life']);
238
239 $form['cut_off_energy']=
240 array('#type' => 'textfield',
241 '#title' => t('Cut-off energy'),
242 '#required' => TRUE,
243 '#description' => t('The cut-off energy. Below this energy level, the node is considered non-radioactive and '.
244 'the radioactivity information will be deleted from the database. Leave 0 disable cut-off.'),
245 '#default_value' => $decay_profile['cut_off_energy']);
246
247 $radioactivity_info=radioactivity_get_radioactivity_info();
248
249 // $form['debug']=
250 // array('#value' => print_r($radioactivity_info, TRUE));
251
252 $form['energy']=
253 array('#type' => 'fieldset',
254 '#tree' => TRUE,
255 '#title' => t('Energy settings'));
256
257 if (count($radioactivity_info["targets"])==0) {
258 // no energy target classes
259 $form['energy']['no_targets']=
260 array('#type' => 'item',
261 '#value' => t('You must enable at least one plug-in that provides an energy target class. '.
262 'Try <em>radioactivity_node</em>.'));
263 } else {
264 foreach ($radioactivity_info['targets'] as $oclass => $def) {
265 $form['energy'][$oclass]=
266 _radioactivity_oclassdef_to_form($oclass, $oclass, $def, $radioactivity_info['sources'][$oclass],
267 $decay_profile['energy'][$oclass]);
268 $form['energy'][$oclass]['#collapsed']=FALSE;
269 }
270 }
271
272 $form['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Save decay profile') );
273 $form['buttons']['delete'] = array('#value' => l(t('Delete profile'), 'admin/settings/radioactivity/profile_'.$dpid.'/delete'));
274
275 if (!empty($_POST) && form_get_errors()) {
276 drupal_set_message(t('The settings have not been saved because of the errors.'), 'error');
277 }
278
279 return $form;
280 }
281
282 // removes empty subclass leafs
283 function _radioactivity_prune_array($energy) {
284 $ret=array();
285 foreach ($energy as $key => $value) {
286 if (is_array($value)) {
287 $value=_radioactivity_prune_array($value);
288 }
289 if ($value || strlen($value)) {
290 $ret[$key]=$value;
291 }
292 }
293 return $ret;
294 }
295
296 function radioactivity_admin_profile_form_submit($form_id, $form) {
297 $dpid=(int)$form['decay_profile_id'];
298
299 if ($dpid==0) {
300 // internal error
301 drupal_set_message(t('Internal error: decay_profile_id=@dpid', array('@dpid'=>$dpid)), 'error');
302 return FALSE;
303 }
304
305 $decay_profiles=_radioactivity_get_decay_profiles();
306
307 if ($dpid<0) {
308 // get new $dpid
309 $dpids=array_keys($decay_profiles);
310 if (count($dpids)>0) {
311 $dpid=1+max($dpids);
312 } else {
313 $dpid=1;
314 }
315 }
316
317 // build profile array
318 $decay_profile=array();
319 $decay_profile['label']=$form['label'];
320 $decay_profile['description']=$form['description'];
321
322 $half_life=(int)$form['half_life'];
323 if ($half_life<=0) $half_life=6*3600;
324 $decay_profile['half_life']=$half_life;
325
326 $decay_profile['cut_off_energy']=(double)$form['cut_off_energy'];
327
328 $decay_profile['energy']=_radioactivity_prune_array($form['energy']);
329
330 $decay_profiles[$dpid]=$decay_profile;
331
332 _radioactivity_set_decay_profiles($decay_profiles);
333 drupal_set_message(t('Profile @dpid saved.', array('@dpid'=>$dpid)));
334 }
335
336 function radioactivity_admin_delete_profile_form($dpid) {
337 $decay_profiles=_radioactivity_get_decay_profiles();
338
339 return confirm_form(array('decay_profile_id' => array('#type' => 'hidden',
340 '#value' => $dpid )),
341 t('Are you sure you want to delete radiation decay profile @label (@id)?',
342 array('@label'=>$decay_profiles[$dpid]['label'], '@id'=>$dpid)),
343 "admin/settings/radioactivity/profile_".$dpid, NULL,
344 t('Delete'));
345 }
346
347 function radioactivity_admin_delete_profile_form_submit($form_id, $form) {
348 $dpid=$form['decay_profile_id'];
349 drupal_set_message(t("Deleted profile @id", array('@id' => $dpid)));
350
351
352 $decay_profiles=_radioactivity_get_decay_profiles();
353 unset($decay_profiles[$dpid]);
354 _radioactivity_set_decay_profiles($decay_profiles);
355
356 db_query("DELETE FROM {radioactivity} WHERE decay_profile=%d", $dpid);
357
358 drupal_goto("admin/settings/radioactivity");
359 }
360
361 function radioactivity_cron() {
362 $timestamp=time();
363
364 // last cron
365 $last_cron_timestamp=(int)variable_get('radioactivity_last_cron_timestamp', 0);
366 $granularity=(int)_radioactivity_get_decay_granularity();
367 $threshold_timestamp=$last_cron_timestamp-($last_cron_timestamp % $granularity) + $granularity;
368 if ($timestamp<$threshold_timestamp) return; // don't update yet
369
370 foreach (_radioactivity_get_decay_profiles() as $dpid => $decay_profile) {
371 $half_life=(double)$decay_profile["half_life"];
372 $cut_off_energy=(double)$decay_profile["cut_off_energy"];
373
374 // the formula is:
375 // E=E_0 * 2^(- delta_time / half_life)
376
377 db_query("UPDATE {radioactivity} SET energy=energy * pow(2, (last_emission_timestamp-%d)*1.0/%f), last_emission_timestamp=%d ".
378 "WHERE decay_profile=%d AND last_emission_timestamp<%d",
379 $timestamp, $half_life, $timestamp, $dpid, $timestamp);
380
381 // delete clean (l. non-radioactive) nodes
382 db_query("DELETE FROM {radioactivity} WHERE decay_profile=%d AND energy < %f",
383 $dpid, $cut_off_energy);
384 }
385
386 variable_set('radioactivity_last_cron_timestamp', $timestamp);
387 }
388
389 /**
390 * Reads energies for a node. Returns array of $dpid => $energy
391 */
392 function radioactivity_get_energy($oid, $oclass) {
393 $ret=array();
394
395 // remap id if necessary
396 $oid=_radioactivity_possibly_remap_id($oid, $oclass);
397
398 $result=db_query("SELECT decay_profile, energy FROM {radioactivity} WHERE id=%d AND class='%s'", $oid, $oclass);
399
400 while ($row = db_fetch_object($result)) {
401 $ret[$row->decay_profile]=$row->energy;
402 }
403
404 return $ret;
405 }
406
407 function radioactivity_delete_energy($oid, $oclass) {
408 // remap id if necessary
409 $oid=_radioactivity_possibly_remap_id($oid, $oclass);
410 db_query("DELETE FROM {radioactivity} WHERE id=%d AND class='%s'", $oid, $oclass);
411 return TRUE;
412 }
413
414 function radioactivity_get_radioactivity_array($oid, $oclass) {
415
416 $ret=array();
417 $energies=radioactivity_get_energy($oid, $oclass);
418
419 foreach ($energies as $dpid => $energy) {
420 $ret['energy'][$dpid]=(double)$energies[$dpid];
421 }
422
423 return $ret;
424 }
425

  ViewVC Help
Powered by ViewVC 1.1.2