Hide unaccessible fields properly
[drupal_comment_timer.git] / comment_timer.module
blobad690ef5a31f00a070723d0e4aa54533bd81dd67
1 <?php
3 /**
4  * @file Tracks time spent on comments.
5  */
7 /**
8  * Implementation of hook_perm().
9  */
10 function comment_timer_perm() {
11   return array(
12     'administer comment timer',
13     'access comment timer',
14   );
17 /**
18  * Implementation of hook_menu().
19  */
20 function comment_timer_menu() {
21   $items['admin/settings/comment_timer'] = array(
22     'title' => 'Comment Timer',
23     'description' => 'Configure the content types to have time-tracked comments.',
24     'page callback' => 'drupal_get_form',
25     'page arguments' => array('comment_timer_admin_settings'),
26     'access arguments' => array('administer comment timer'),
27     'type' => MENU_NORMAL_ITEM,
28   );
29   return $items;
32 /**
33  * Provide an admin settings form.
34  */
35 function comment_timer_admin_settings() {
36   $node_types = array_map('check_plain', node_get_types('names'));
37   $form['comment_timer_node_types'] = array(
38     '#type' => 'checkboxes',
39     '#title' => t('Enable to have time-tracked comments'),
40     '#default_value' => variable_get('comment_timer_node_types', array()),
41     '#options' => $node_types,
42     '#description' => t('Select the content types to have time-tracked comments.'),
43   );
44   $form['comment_timer_weight'] = array(
45     '#type' => 'weight',
46     '#title' => t('Weight of comment timer on node page'),
47     '#required' => TRUE,
48     '#default_value' => variable_get('comment_timer_weight', 0),
49   );
50   $form['comment_timer_display'] = array(
51     '#type' => 'checkbox',
52     '#title' => t('Display comment timer'),
53     '#description' => t('Comment timer info will be concatenated to the comment if enabled.'),
54     '#default_value' => variable_get('comment_timer_display', 0),
55   );
56   $form['comment_timer_display_title'] = array(
57     '#type' => 'checkbox',
58     '#title' => t('Display comment timer field titles'),
59     '#description' => t('Comment timer fields will have titles if enabled.'),
60     '#default_value' => variable_get('comment_timer_display_title', 1),
61   );
62   return system_settings_form($form);
65 /**
66  * Implementation of hook_form_FORM_ID_alter().
67  */
68 function comment_timer_form_comment_form_alter(&$form, &$form_state) {
69   if (isset($form['nid']) && is_array($form['nid'])) {
70     $node = node_load($form['nid']['#value']);
71     $node_types = variable_get('comment_timer_node_types', array());
72     if (isset($node) && is_object($node) && isset($node->type) && !empty($node_types[$node->type])) {
73       if (is_array($form_state['post']) && is_array($form_state['post']['comment_timer'])) {
74         // If the form is only previewed, retrieve timer information from
75         // there. If the first textfield is not empty, consider that one
76         // instead of the (auto-measured) second one.
77         if ($form_state['post']['comment_timer']['seconds'] == '') {
78           $seconds = _comment_timer_hms_to_seconds($form_state['post']['comment_timer']['elapsed']);
79         }
80         else {
81           $seconds = _comment_timer_hms_to_seconds($form_state['post']['comment_timer']['seconds']);
82         }
83       }
84       else {
85         // If the form is simply displayed, retrieve timing information from
86         // the DB.
87         if (isset($form['cid']) && is_array($form['cid']) && isset($form['cid']['#value'])) {
88           $seconds = db_result(db_query('SELECT seconds FROM {comment_timer_comment} WHERE cid = %d', $form['cid']['#value']));
89         }
90         else {
91           $seconds = 0;
92         }
93       }
94       comment_timer_form_timer($form, $seconds);
95       $form['#validate'][] = 'comment_timer_form_validate';
96     }
97   }
101  * Implementation of hook_form_alter().
102  */
103 function comment_timer_form_alter(&$form, $form_state, $form_id) {
104   if (isset($form['#node']) && $form_id == $form['#node']->type .'_node_form') {
105     $node_types = variable_get('comment_timer_node_types', array());
106     if (!empty($node_types[$form['#node']->type])) {
107       if (is_array($form_state['post']) && is_array($form_state['post']['comment_timer'])) {
108         // If the form is only previewed, retrieve timer information from
109         // there. If the first textfield is not empty, consider that one
110         // instead of the (auto-measured) second one.
111         if ($form_state['post']['comment_timer']['seconds'] == '') {
112           $seconds = _comment_timer_hms_to_seconds($form_state['post']['comment_timer']['elapsed']);
113         }
114         else {
115           $seconds = _comment_timer_hms_to_seconds($form_state['post']['comment_timer']['seconds']);
116         }
117       }
118       else {
119         // If the form is simply displayed, retrieve timing information from
120         // the DB.
121         if (isset($form['nid']) && is_array($form['nid']) && isset($form['nid']['#value'])) {
122           $seconds = db_result(db_query('SELECT nodeseconds FROM {comment_timer_node} WHERE nid = %d', $form['nid']['#value']));
123         }
124         else {
125           $seconds = 0;
126         }
127       }
128       comment_timer_form_timer($form, $seconds);
129       $form['#validate'][] = 'comment_timer_form_validate';
130     }
131   }
135  * Validates comment timer time information textfield.
136  */
137 function comment_timer_form_validate($form, &$form_state) {
138   if (($form_state['values']['comment_timer']['seconds'] != '') && !preg_match('/^\d{2}:(\d{2}):(\d{2})$/', $form_state['values']['comment_timer']['seconds'], $matches)) {
139     form_set_error('comment_timer][seconds', t('Invalid time format.'));
140   }
141   elseif ($matches[1] > 59 || $matches[2] > 59) {
142     form_set_error('comment_timer][seconds', t('Invalid time format.'));
143   }
144   elseif ($form_state['clicked_button']['#id'] == 'edit-preview') {
145     // We should store the value upon preview and rebuild the form.
146     // @XXX: Anyway, this doesn't seem to be working.
147     /*
148     dpm($form_state);
149     if ($form_state['values']['comment_timer']['seconds'] == '') {
150       $seconds = _comment_timer_hms_to_seconds($form_state['values']['comment_timer']['elapsed']);
151     }
152     else {
153       $seconds = _comment_timer_hms_to_seconds($form_state['values']['comment_timer']['seconds']);
154     }
155     $form_state['#comment_timer-seconds'] = $seconds;
156     $form_state['rebuild'] = TRUE;
157      */
158   }
162  * Converts number of seconds to HH:MM:SS.
163  */
164 function _comment_timer_seconds_to_hms($seconds) {
165   $hours = $minutes = 0;
166   if ($seconds > 60) {
167     $minutes = floor($seconds / 60);
168     $seconds %= 60;
169   }
170   if ($minutes > 60) {
171     $hours = floor($minutes / 60);
172     $minutes %= 60;
173   }
174   return sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
178  * Converts 'HH:MM:SS' to seconds. Does not validates by itself.
179  */
180 function _comment_timer_hms_to_seconds($string) {
181   $hms = explode(':', $string);
182   return 3600 * $hms[0] + 60 * $hms[1] + $hms[2];
186  * Implementation of hook_nodeapi().
187  */
188 function comment_timer_nodeapi(&$node, $op, $teaser, $page) {
189   $node_types = variable_get('comment_timer_node_types', array());
190   if (isset($node_types[$node->type])) {
191     switch ($op) {
192       case 'view':
193         if (!user_access('access comment timer')) {
194           return;
195         }
196         // Display time spent on all the comments.
197         $result = db_fetch_object(db_query('SELECT seconds, nodeseconds FROM {comment_timer_node} WHERE nid = %d', $node->nid));
198         if ($result->seconds || $result->nodeseconds) {
199           $title = variable_get('comment_timer_display_title', 1);
200           // @TODO: Add these to the CCK reorder form instead (if available).
201           $node->content['comment_timer_node'] = array(
202             '#value' => $title ? t('Node time: @time', array('@time' => _comment_timer_seconds_to_hms($result->nodeseconds))) : _comment_timer_seconds_to_hms($result->nodeseconds),
203             '#weight' => variable_get('comment_timer_weight', 0),
204             '#prefix' => '<div class="comment-timer-node">',
205             '#suffix' => '</div>',
206           );
207           $node->content['comment_timer_comment'] = array(
208             '#value' => $title ? t('Comment time: @time', array('@time' => _comment_timer_seconds_to_hms($result->seconds))) : _comment_timer_seconds_to_hms($result->seconds),
209             '#weight' => variable_get('comment_timer_weight', 0),
210             '#prefix' => '<div class="comment-timer-comment">',
211             '#suffix' => '</div>',
212           );
213           $node->content['comment_timer_all'] = array(
214             '#value' => $title ? t('All time: @time', array('@time' => _comment_timer_seconds_to_hms($result->seconds + $result->nodeseconds))) : _comment_timer_seconds_to_hms($result->seconds + $result->nodeseconds),
215             '#weight' => variable_get('comment_timer_weight', 0),
216             '#prefix' => '<div class="comment-timer-all">',
217             '#suffix' => '</div>',
218           );
219         }
220         break;
221       case 'load':
222         return db_fetch_array(db_query('SELECT seconds, nodeseconds FROM {comment_timer_node} WHERE nid = %d', $node->nid));
223         break;
224       case 'delete':
225         // Iterate through node's comments, DELETE each comment timer comment entry.
226         $result = db_query('SELECT cid FROM {comments} WHERE nid = %d', $node->nid);
227         while ($cid = db_result($result)) {
228           db_query('DELETE FROM {comment_timer_comment} WHERE cid = %d', $cid);
229         }
230         // DELETE the comment timer node entry.
231         db_query('DELETE FROM {comment_timer_node} WHERE nid = %d', $node->nid);
232         break;
233       case 'insert':
234         if ($node->comment_timer['seconds'] == '') {
235           $seconds = _comment_timer_hms_to_seconds($node->comment_timer['elapsed']);
236         }
237         else {
238           $seconds = _comment_timer_hms_to_seconds($node->comment_timer['seconds']);
239         }
240         db_query('INSERT INTO {comment_timer_node} (nid, seconds, nodeseconds) VALUES (%d, 0, %d)', $node->nid, $seconds);
241         break;
242       case 'update':
243         if ($node->comment_timer['seconds'] == '') {
244           $seconds = _comment_timer_hms_to_seconds($node->comment_timer['elapsed']);
245         }
246         else {
247           $seconds = _comment_timer_hms_to_seconds($node->comment_timer['seconds']);
248         }
249         db_query('UPDATE {comment_timer_node} SET nodeseconds = %d WHERE nid = %d', $seconds, $node->nid);
250         if (!db_affected_rows()) {
251           db_query('INSERT INTO {comment_timer_node} (nid, seconds, nodeseconds) VALUES (%d, 0, %d)', $node->nid, $seconds);
252         }
253         break;
254     }
255   }
259  * Implementation of hook_comment().
260  */
261 function comment_timer_comment(&$comment, $op) {
262   switch ($op) {
263     case 'view':
264       if (!user_access('access comment timer')) {
265         return;
266       }
267       // Display time spent on the comment.
268       $seconds = db_result(db_query('SELECT seconds FROM {comment_timer_comment} WHERE cid = %d', $comment->cid));
269       if ($seconds) {
270         if (variable_get('comment_timer_display', 0)) {
271           $comment->comment .= '<div class="comment-timer">'. (variable_get('comment_timer_display_title', 1) ? t('Time: @time', array('@time' => _comment_timer_seconds_to_hms($seconds))) : _comment_timer_seconds_to_hms($seconds)) .'</div>';
272         }
273         $comment->comment_timer .= _comment_timer_seconds_to_hms($seconds);
274       }
275       break;
276     case 'insert':
277     case 'update':
278       // If the first textfield is not empty, consider that one instead of
279       // the (auto-measured) second one.
280       if ($comment['comment_timer']['seconds'] == '') {
281         $seconds = _comment_timer_hms_to_seconds($comment['comment_timer']['elapsed']);
282       }
283       else {
284         $seconds = _comment_timer_hms_to_seconds($comment['comment_timer']['seconds']);
285       }
286       db_query('UPDATE {comment_timer_comment} SET seconds = %d WHERE cid = %d', $seconds, $comment['cid']);
287       if (!db_affected_rows()) {
288         db_query('INSERT INTO {comment_timer_comment} (cid, seconds) VALUES(%d, %d)', $comment['cid'], $seconds);
289       }
290       db_query('UPDATE {comment_timer_node} SET seconds = (SELECT SUM(seconds) FROM {comments} c INNER JOIN {comment_timer_comment} ctc ON ctc.cid = c.cid WHERE c.nid = %d) WHERE nid = %d', $comment['nid'], $comment['nid']);
291       if (!db_affected_rows()) {
292         $seconds = db_result(db_query('SELECT SUM(seconds) FROM {comments} c INNER JOIN {comment_timer_comment} ctc ON ctc.cid = c.cid WHERE c.nid = %d', $comment['nid']));
293         db_query('INSERT INTO {comment_timer_node} (nid, seconds, nodeseconds) VALUES (%d, %d, 0)', $comment['nid'], $seconds);
294       }
295       break;
296     case 'delete':
297       db_query('DELETE FROM {comment_timer_comment} WHERE cid = %d', $comment->cid);
298       db_query('UPDATE {comment_timer_node} SET seconds = (SELECT SUM(seconds) FROM {comments} c INNER JOIN {comment_timer_comment} ctc ON ctc.cid = c.cid WHERE c.nid = %d) WHERE nid = %d', $comment->nid, $comment->nid);
299   }
303  * Add comment timer elements to a form.
304  */
305 function comment_timer_form_timer(&$form, $seconds = 0) {
306   if (user_access('access comment timer')) {
307     // Add a fieldset to contain everything else.
308     $form['comment_timer'] = array(
309       '#type' => 'fieldset',
310       '#prefix' => '<div class="container-inline">',
311       '#suffix' => '</div>',
312       '#weight' => 1,
313       '#tree' => TRUE,
314       '#title' => t('Comment timer'),
315     );
316     $form['comment_timer']['seconds'] = array(
317       '#type' => 'textfield',
318       '#description' => t('time to store (hh:mm:ss)'),
319       '#size' => '8',
320       '#default_value' => '',
321     );
322     $form['comment_timer']['elapsed'] = array(
323       '#type' => 'textfield',
324       '#description' => t('time spent (hh:mm:ss)'),
325       '#size' => '8',
326     );
327     if ($seconds != 0) {
328       $form['comment_timer']['elapsed']['#default_value'] = _comment_timer_seconds_to_hms($seconds);
329     }
330     drupal_add_js(array('comment_timer' => array('seconds' => $seconds)), 'setting');
331     drupal_add_js(drupal_get_path('module', 'comment_timer'). '/comment_timer.js');
332     $form['comment_timer']['reset'] = array(
333       '#type' => 'button',
334       '#value' => t('Reset'),
335     );
336     $form['comment_timer']['pause'] = array(
337       '#type' => 'button',
338       '#value' => t('Pause'),
339     );
340   }
344  * Implementation of hook_views_api().
345  */
346 function comment_timer_views_api() {
347   return array(
348     'api' => 2,
349     'path' => drupal_get_path('module', 'comment_timer') .'/views',
350   );
354  * Implementation of template_preprocess_comment().
355  */
356 function comment_timer_preprocess_comment(&$vars) {
357   if (is_array($vars['comment']->comment_timer) && !empty($vars['comment']->comment_timer['elapsed'])) {
358     $vars['comment_timer'] = $vars['comment']->comment_timer['elapsed'];
359   }
360   elseif (!empty($vars['comment']->comment_timer)) {
361     $vars['comment_timer'] = $vars['comment']->comment_timer;
362   }
365 // vim: set ft=php syntax=php expandtab ts=2 sw=2 autoindent smartindent: