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

Contents of /contributions/modules/tracker2/tracker2.module

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


Revision 1.15 - (show annotations) (download) (as text)
Mon Feb 9 16:39:52 2009 UTC (9 months, 2 weeks ago) by damz
Branch: MAIN
CVS Tags: HEAD
Changes since 1.14: +2 -2 lines
File MIME type: text/x-php
#367069: fix display of the my tracker tab.
1 <?php
2 // $Id: tracker2.module,v 1.14 2009/01/12 22:09:35 toddnienkerk Exp $
3 /**
4 * @file
5 * Enables tracking of recent posts for users.
6 */
7
8 /**
9 * Implementation of hook_help().
10 */
11 function tracker2_help($path, $arg) {
12 switch ($path) {
13 case 'admin/help#tracker2':
14 return '<p>'. t('The Tracker2 module is a much more efficient tracker that maintains seperate database tables of updated items.') .'</p>';
15 }
16 }
17
18 /**
19 * Implementation of hook_menu().
20 */
21 function tracker2_menu() {
22 $base = 'tracker2';
23 $user_base = 'track2';
24 if (!module_exists('tracker')) {
25 $base = 'tracker';
26 $user_base = 'track';
27 }
28
29 $items[$base] = array(
30 'title' => 'Recent posts',
31 'page callback' => 'tracker2_page',
32 'access arguments' => array('access content'),
33 'weight' => 1,
34 'file' => 'tracker2.pages.inc',
35 );
36
37 $items[$base .'/all'] = array(
38 'title' => 'All recent posts',
39 'type' => MENU_DEFAULT_LOCAL_TASK,
40 );
41 $items[$base .'/%user_uid_optional'] = array(
42 'title' => 'My recent posts',
43 'access callback' => '_tracker2_myrecent_access',
44 'access arguments' => array(1),
45 'page arguments' => array(1),
46 'type' => MENU_LOCAL_TASK,
47 );
48
49 $items['admin/settings/tracker2'] = array(
50 'title' => 'Tracker 2',
51 'description' => 'High-performance reimplementation of the Tracker module.',
52 'page callback' => 'drupal_get_form',
53 'access arguments' => array('administer tracker'),
54 'page arguments' => array('tracker2_admin'),
55 'file' => 'tracker2.admin.inc',
56 );
57
58 $items['user/%user/'. $user_base] = array(
59 'title' => 'Track',
60 'page callback' => 'tracker2_track_user',
61 'access arguments' => array('access content'),
62 'type' => MENU_LOCAL_TASK,
63 'file' => 'tracker2.pages.inc',
64 );
65 $items['user/%user/'. $user_base .'/posts'] = array(
66 'title' => 'Track posts',
67 'type' => MENU_DEFAULT_LOCAL_TASK,
68 );
69
70 return $items;
71 }
72
73 /**
74 * Access callback for tracker/%user.
75 */
76 function _tracker2_myrecent_access($account) {
77 // This path is only allowed for authenticated users looking at their own posts.
78 return $account->uid && ($GLOBALS['user']->uid == $account->uid) && user_access('access content');
79 }
80
81 /**
82 * Access callback for user account tracker tab.
83 */
84 function _tracker2_user_access($account) {
85 return user_view_access($account) && user_access('access content');
86 }
87
88
89 /**
90 * Implementation of hook_perm().
91 */
92 function tracker2_perm() {
93 return array('administer tracker');
94 }
95
96 /**
97 * Implementation of hook_cron().
98 */
99 function tracker2_cron() {
100 $max_nid = variable_get('tracker2_index_nid', 0);
101 $batch_size = variable_get('tracker2_batch_size', 1000);
102 if ($max_nid) {
103 $last_nid = FALSE;
104 $res = db_query_range("SELECT nid, uid, status FROM {node} WHERE nid <= %d ORDER BY nid DESC", $max_nid, 0, $batch_size);
105 $count = 0;
106
107 while ($row = db_fetch_object($res)) {
108 // Calculate the changed timestamp for this node.
109 $changed = _tracker2_calculate_changed($row->nid);
110
111 // Remove existing data for this node.
112 db_query("DELETE FROM {tracker2_node} WHERE nid = %d", $row->nid);
113 db_query("DELETE FROM {tracker2_user} WHERE nid = %d", $row->nid);
114
115 // Insert the node-level data.
116 db_query("INSERT INTO {tracker2_node} (nid, published, changed) VALUES (%d, %d, %d)", $row->nid, $row->status, $changed);
117
118 // Insert the user-level data for the node's author.
119 db_query("INSERT INTO {tracker2_user} (nid, published, uid, changed) VALUES (%d, %d, %d, %d)", $row->nid, $row->status, $row->uid, $changed);
120
121 // Insert the user-level data for the commenters (except if a commenter is the node's author).
122 db_query("INSERT INTO {tracker2_user} (nid, published, uid, changed) SELECT DISTINCT %d AS nid, %d AS published, uid, %d AS changed FROM {comments} WHERE nid = %d AND uid <> %d AND status = %d", $row->nid, $row->status, $changed, $row->nid, $row->uid, COMMENT_PUBLISHED);
123
124 // Note that we have indexed at least one node.
125 $last_nid = $row->nid;
126
127 $count++;
128 }
129
130 if ($last_nid !== FALSE) {
131 // Prepare a starting point for the next run.
132 variable_set('tracker2_index_nid', $last_nid - 1);
133
134 watchdog('tracker2', 'Indexed %count nodes for tracking.', array('%count' => $count));
135 }
136 else {
137 // If all nodes have been indexed, set to zero to skip future cron runs.
138 variable_set('tracker2_index_nid', 0);
139 }
140 }
141 }
142
143 /**
144 * Create or update the tracker2 records.
145 */
146 function _tracker2_add($nid, $uid, $changed) {
147 $node = db_fetch_object(db_query("SELECT nid, status, uid, changed FROM {node} WHERE nid = %d", $nid));
148
149 $insert = new stdClass();
150 $insert->nid = $nid;
151 // Adding a comment can only increase the changed timestamp, so our calculation here is easy.
152 $insert->changed = max($node->changed, $changed);
153 $insert->published = $node->status;
154
155 // Create or update the node-level data.
156 $exists = db_result(db_query("SELECT COUNT(*) FROM {tracker2_node} WHERE nid = %d", $nid));
157 if ($exists) {
158 drupal_write_record('tracker2_node', $insert, 'nid');
159 }
160 else {
161 drupal_write_record('tracker2_node', $insert);
162 }
163
164 // Create or update the user-level data.
165 $exists = db_result(db_query("SELECT COUNT(*) FROM {tracker2_user} WHERE nid = %d AND uid = %d", $nid, $uid));
166 $insert->uid = $uid;
167 if ($exists) {
168 drupal_write_record('tracker2_user', $insert, 'nid');
169 }
170 else {
171 drupal_write_record('tracker2_user', $insert);
172 }
173 }
174
175 /**
176 * Calculate the last time the node was changed or commented upon.
177 */
178 function _tracker2_calculate_changed($nid) {
179 $changed = db_result(db_query("SELECT changed FROM {node} WHERE nid = %d", $nid));
180 $comment_changed = db_result(db_query_range("SELECT timestamp FROM {comments} WHERE nid = %d AND status = %d ORDER BY timestamp DESC", $nid, COMMENT_PUBLISHED, 0, 1));
181 return max($comment_changed, $changed);
182 }
183
184 /**
185 * Delete from the tracker2 records.
186 */
187 function _tracker2_remove($nid, $uid = NULL, $changed = NULL) {
188 $node = db_fetch_object(db_query("SELECT nid, status, uid, changed FROM {node} WHERE nid = %d", $nid));
189
190 if ($node) {
191 $keep_subscription = FALSE;
192
193 // The user only keeps his or her subscription if both of the following are true:
194 // (1) The node exists.
195 // (2) The user is either the node author or has commented on the node.
196
197 // Self-authorship is one reason to keep the user's subscription.
198 $keep_subscription = ($node->uid == $uid);
199
200 // Comments are a second reason to keep the user's subscription.
201 if (!$keep_subscription) {
202 // Check if the user has a published comment at least once on the given nid.
203 $keep_subscription = db_result(db_query_range("SELECT COUNT(*) FROM {comments} WHERE nid = %d AND uid = %d AND status = 0", $nid, $uid, 0, 1));
204 }
205
206 // If we haven't found a reason to keep the user's subscription, delete it.
207 if (!$keep_subscription) {
208 db_query("DELETE FROM {tracker2_user} WHERE nid = %d AND uid = %d", $nid, $uid);
209 }
210
211 // Now we need to update the (possibly) changed timestamps for other users and the node itself.
212
213 // We only need to do this if the removed item has a timestamp that equals
214 // or exceeds the listed changed timestamp for the node.
215 $tracker_node = db_fetch_object(db_query("SELECT nid, changed FROM {tracker2_node} WHERE nid = %d", $nid));
216 if ($tracker_node && $changed >= $tracker_node->changed) {
217 // If we're here, the item being removed is *possibly* the item that established the node's changed timestamp.
218
219 $insert = new stdClass();
220 $insert->nid = $nid;
221 $insert->published = $node->status;
222
223 // We just have to recalculate things from scratch.
224 $insert->changed = _tracker2_calculate_changed($nid);
225
226 // And then we push the out the new changed timestamp to our denormalized tables.
227 drupal_write_record('tracker2_node', $insert, 'nid');
228 drupal_write_record('tracker2_user', $insert, 'nid');
229 }
230 }
231 else {
232 // If the node doesn't exist, remove everything.
233 db_query("DELETE FROM {tracker2_node} WHERE nid = %d", $nid);
234 db_query("DELETE FROM {tracker2_user} WHERE nid = %d", $nid);
235 }
236 }
237
238 /**
239 * Implementation of hook_nodeapi().
240 */
241 function tracker2_nodeapi(&$node, $op) {
242 if ($op == 'insert' || $op == 'update') {
243 _tracker2_add($node->nid, $node->uid, $node->changed);
244 }
245 else if ($op == 'delete') {
246 _tracker2_remove($node->nid, $node->uid, $node->changed);
247 }
248 }
249
250 /**
251 * Implementation of hook_comment().
252 */
253 function tracker2_comment($a1, $op) {
254 $comment = (array) $a1;
255 switch ($op) {
256 case 'insert':
257 case 'update':
258 case 'publish':
259 if ($comment['status'] == COMMENT_PUBLISHED) {
260 _tracker2_add($comment['nid'], $comment['uid'], $comment['timestamp']);
261 }
262 else {
263 _tracker2_remove($comment['nid'], $comment['uid'], $comment['timestamp']);
264 }
265 break;
266 case 'delete':
267 case 'unpublish':
268 _tracker2_remove($comment['nid'], $comment['uid'], $comment['timestamp']);
269 break;
270 }
271 }
272
273 /**
274 * Implementation of hook_theme().
275 */
276 function tracker2_theme() {
277 return array(
278 'tracker2_page' => array(
279 'arguments' => array('nodes' => array()),
280 'file' => 'tracker2.pages.inc',
281 ),
282 );
283 }

  ViewVC Help
Powered by ViewVC 1.1.2