Merge lp://qastaging/~m-baert/ubuntu-drupal-planet/6.x into lp://qastaging/~swe3tdave-deactivatedaccount/ubuntu-drupal-planet/6.x
- 6.x
- Merge into 6.x
Proposed by
David Giard
Status: | Merged |
---|---|
Merged at revision: | 17 |
Proposed branch: | lp://qastaging/~m-baert/ubuntu-drupal-planet/6.x |
Merge into: | lp://qastaging/~swe3tdave-deactivatedaccount/ubuntu-drupal-planet/6.x |
Diff against target: | None lines |
To merge this branch: | bzr merge lp://qastaging/~m-baert/ubuntu-drupal-planet/6.x |
Related bugs: | |
Related blueprints: |
Code Documentation
(Undefined)
PostgreSQL port
(Undefined)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
David Giard | Approve | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
David Giard (swe3tdave-deactivatedaccount) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'planet.info' |
2 | --- planet.info 2009-03-01 02:54:23 +0000 |
3 | +++ planet.info 2009-03-14 00:23:25 +0000 |
4 | @@ -1,6 +1,7 @@ |
5 | ; $Id: planet.info,v 1.2 2007/05/30 03:22:01 daryl Exp $ |
6 | name = Planet |
7 | description = Planet blog aggregator |
8 | +; TODO better module definition, including specificity if possible. |
9 | package = Community - optional |
10 | version = 6.x |
11 | core = 6.x |
12 | |
13 | === modified file 'planet.install' |
14 | --- planet.install 2009-03-01 03:00:14 +0000 |
15 | +++ planet.install 2009-03-14 00:23:25 +0000 |
16 | @@ -10,37 +10,43 @@ |
17 | 'description' => t('The base table for planet.'), |
18 | 'fields' => array( |
19 | 'fid' => array( |
20 | - 'description' => t('The primary identifier for a planet_feeds table.'), |
21 | + 'description' => t('Primary Key: Unique identifier for a planet RSS feed.'), |
22 | 'type' => 'serial', |
23 | 'unsigned' => TRUE, |
24 | 'not null' => TRUE, |
25 | ), |
26 | 'uid' => array( |
27 | + 'description' => t('Foreign key to {users}.uid . Identifies user who choose the feed.'), |
28 | 'type' => 'int', |
29 | 'unsigned' => 1, |
30 | 'not null' => FALSE, |
31 | ), |
32 | 'title' => array( |
33 | 'type' => 'varchar', |
34 | + 'description' => t('Title of the feed.'), |
35 | 'length' => 50, |
36 | 'not null' => TRUE, |
37 | ), |
38 | 'link' => array( |
39 | 'type' => 'varchar', |
40 | + 'description' => t('URL to the feed'), |
41 | 'length' => 80, |
42 | 'not null' => TRUE, |
43 | ), |
44 | 'image' => array( |
45 | + 'description' => t('An image representing the feed'), |
46 | 'type' => 'varchar', |
47 | 'length' => 120, |
48 | 'not null' => FALSE, |
49 | ), |
50 | 'checked' => array( |
51 | + 'description' => t('Last time feed was checked for new items, as Unix timestamp'), |
52 | 'type' => 'int', |
53 | 'not null' => FALSE, |
54 | ), |
55 | 'frozen' => array( |
56 | - 'type' => 'int', |
57 | + // TODO: add field description 'description' => t(''), |
58 | + 'type' => 'int', // TODO change to boolean when supported |
59 | 'not null' => TRUE, |
60 | 'default' => 0, |
61 | ), |
62 | @@ -52,7 +58,7 @@ |
63 | 'description' => t('contain feed id and its corresponding nid'), |
64 | 'fields' => array( |
65 | 'id' => array( |
66 | - 'description' => t('The primary identifier for a planet_items table'), |
67 | + 'description' => t('Primary key: Unique identifier for a planet feed item'), |
68 | 'type' => 'serial', |
69 | 'unsigned' => 1, |
70 | 'not null' => TRUE, |
71 | @@ -91,11 +97,9 @@ |
72 | /** |
73 | * Implementation of hook_install() |
74 | * |
75 | - * This will automatically install the database tables for the planet module for MySQL. |
76 | - * |
77 | - * If you are using another database, you will have to install the tables by hand, using the queries below as a reference. |
78 | - * |
79 | - * |
80 | + * This will automatically install the database tables for the planet |
81 | + * module, using Drupal's data abstraction layer. |
82 | + * |
83 | */ |
84 | |
85 | function planet_install() { |
86 | @@ -106,9 +110,9 @@ |
87 | /** |
88 | * Implementation of hook_uninstall() |
89 | * |
90 | - * This will automatically uninstall the database tables for the planet module for MySQL. |
91 | + * Uninstalls planet module by removing its own database tables, nodes |
92 | + * and persistent variables. |
93 | * |
94 | - * |
95 | */ |
96 | |
97 | function planet_uninstall() { |
98 | |
99 | === modified file 'planet.module' |
100 | --- planet.module 2009-03-08 19:00:05 +0000 |
101 | +++ planet.module 2009-03-20 16:05:00 +0000 |
102 | @@ -1,48 +1,92 @@ |
103 | <?php |
104 | // $Id: planet.install Exp $ |
105 | |
106 | -/** |
107 | + /** |
108 | * @file |
109 | - * The planet module |
110 | + * The planet module. |
111 | + * |
112 | + * Planet is an aggregator that allows you to aggregate the blogs for |
113 | + * users in a given role (e.g. staff) and associate content with the |
114 | + * users rather than as a detached feed. This provides the benefit of |
115 | + * showing avatars with content, providing per-user aggregation of |
116 | + * planet content in addition to blog content, etc. |
117 | * |
118 | */ |
119 | |
120 | +/** |
121 | + * Implementation of hook_node_info. |
122 | + * |
123 | + * @return An array of information on the module's node types. |
124 | + * |
125 | + * @ingroup planet_node |
126 | + */ |
127 | function planet_node_info() { |
128 | return array( |
129 | 'planet' => array( |
130 | - 'name' => t('Planet Entry'), |
131 | - 'module' => 'planet', |
132 | - 'description' => t('Node to contain posts aggregated from various blogs.'), |
133 | + 'name' => t('Planet Entry'), |
134 | + 'module' => 'planet', |
135 | + 'description' => t('Node to contain posts aggregated from various blogs.'), |
136 | ) |
137 | ); |
138 | } |
139 | |
140 | /** |
141 | - * Implementation of hook_perm. |
142 | + * Implementation of hook_perm - Defines user permissions. |
143 | + * The suggested naming convention for permissions is "action_verb modulename". |
144 | + * |
145 | + * @return An array of permissions strings. |
146 | + * |
147 | + * @ingroup base |
148 | */ |
149 | function planet_perm() { |
150 | - return array('administer planet', 'administer own planet feeds'); |
151 | + return array('administer planet', 'administer own planet feeds', 'view all planet nodes'); |
152 | } |
153 | |
154 | +/** |
155 | + * Implementation of hook_help - Provides online user help. |
156 | + * |
157 | + * @param $path A Drupal menu router path the help is being requested for |
158 | + * @param $arg |
159 | + * @return A localized string containing the help text. |
160 | + * |
161 | + * @ingroup base |
162 | + */ |
163 | function planet_help($path, $arg) { |
164 | switch ($path) { |
165 | - case 'admin/help/planet': |
166 | + case 'admin/help#planet': |
167 | + // The module's help text, displayed on the admin/help page and through the module's individual help link. |
168 | $output = '<p>Planet is an aggregator that allows you to aggregate the blogs for users in a given role (e.g. staff) and associate content with the users rather than as a detached feed. This provides the benefit of showing avatars with content, providing per-user aggregation of planet content in addition to blog content, etc.</p>'; |
169 | $output .= '<p>To use planet, go to admin/settings/planet and note the following sections:</p>'; |
170 | $output .= '<ul>'; |
171 | $output .= '<li><strong>General Settings</strong>. The role to select bloggers from lets you narrow the user list for when you\'re adding a feed and associating it with a user. A common setting will be to create a staff role and use this for planet.</li>'; |
172 | $output .= '<li><strong>Feeds</strong>. This section lets you add a new feed. Give it a title, select an author, provide the feed url, and you\'re off. You\'ll have to manually refresh it or wait for a cron run for items to be imported.</li>'; |
173 | $output .= '<li><strong>Feeds</strong>. This section lists current feeds, when they were last updated, how many items they have, and it allows you to edit, refresh, or freeze them. Freezing is a quick way to temporarily suspend updates from the given feed.</li>'; |
174 | + // @DIFFGROUP output syntax |
175 | + $output .= '</ul>'; |
176 | return $output; |
177 | - case 'admin/modules#description': |
178 | - return t('Aggregates RSS feeds and faciliates their association with site users who belong to a given role.'); |
179 | + // @DIFFINFO in D6, admin/modules#description is moved to .info file |
180 | } |
181 | } |
182 | |
183 | -function planet_view($node, $teaser = FALSE, $page = FALSE, $links = TRUE) { |
184 | +/** |
185 | + * Implementation of hook_view() - Displays a planet node. |
186 | + * |
187 | + * @param $node The node to be displayed. |
188 | + * @param $teaser Whether to generate only a summary ("teaser") of the node. |
189 | + * @param $page Whether the node is being displayed as a standalone page. |
190 | + * @return The modified $node parameter, properly presented for output. |
191 | + * |
192 | + * @ingroup planet_node |
193 | + * @CRUD{variables,R} |
194 | + * @CRUD{planet_items,R} |
195 | + */ |
196 | +function planet_view($node, $teaser = FALSE, $page = FALSE) { |
197 | + // @DIFFINFO removed $link param to match D6 hook definition |
198 | if ($page === true && variable_get('planet_redirect_page', 0) == 1) { |
199 | - $obj = db_fetch_object(db_query('SELECT * FROM {planet_items} WHERE nid = %d', $node->nid)); |
200 | - if ($obj->nid == $node->nid && $obj->link != '') { |
201 | + // @DIFFINFO only 'link' field is used, so I restricted the query |
202 | + $obj = db_fetch_object(db_query('SELECT link FROM {planet_items} WHERE nid = %d', $node->nid)); |
203 | + // @DIFFINFO if the query succeeds, $obj->nid == $node->nid , otherwise, $obj==FALSE, |
204 | + if ($obj && $obj->link != '') { |
205 | header('Location: '. $obj->link); |
206 | exit; |
207 | } |
208 | @@ -52,22 +96,51 @@ |
209 | } |
210 | } |
211 | |
212 | +/** |
213 | + * Implementation of hook_access() - Define access permissions for planet nodes (aka CRUD) . |
214 | + * @param $op The operation to be performed: 'create', 'view', 'update', 'delete' |
215 | + * @param $node The node on which the operation is to be performed, or, if it does not yet exist, the type of node to be created. |
216 | + * @param $account A user object representing the user for whom the operation is to be performed. |
217 | + * @return true if the user is allowed to perform operation, false otherwise. |
218 | + * |
219 | + * @ingroup planet_node |
220 | + */ |
221 | function planet_access($op, $node, $account) { |
222 | - |
223 | - |
224 | + // @DIFFINFO using planet-dedicated permissions |
225 | + // Planet administrator has all permissions related to planet module |
226 | + if (user_access('administer planet', $account)) |
227 | + return TRUE; |
228 | + // Users allowed to edit their own planet nodes, are also allowed to create them, others are not. |
229 | + $author = user_access('edit own planet feeds', $account); |
230 | if ($op == 'create') { |
231 | - return user_access('edit own blog', $account) && $account->uid; |
232 | + return $author; |
233 | } |
234 | |
235 | + // Does current user own requested node ? |
236 | + $own = $account->uid == $node->uid; |
237 | + if ($op == 'view') |
238 | + return $own || user_access('view all planet nodes'); |
239 | if ($op == 'update' || $op == 'delete') { |
240 | - if (user_access('edit own blog', $account) && ($account->uid == $node->uid) || user_access('administer nodes', $account)) { |
241 | - return TRUE; |
242 | - } |
243 | + return $author && $own; // ok if $author owns the node |
244 | } |
245 | + trigger_error("Unknown operation requested: $op"); |
246 | + return FALSE; |
247 | } |
248 | |
249 | +/** |
250 | + * Implementation of hook_menu() - Defines menu items and page callbacks. |
251 | + * |
252 | + * @return An array of menu items. |
253 | + * Each menu item has a key corresponding to the Drupal path being registered. |
254 | + * |
255 | + * @ingroup base |
256 | + * |
257 | + * This diagram shows how requests are handled. |
258 | + * Each arrow is labeled with the permission required to access link. |
259 | + * The menu item colors reflect the item type. |
260 | + * @dotfile menu-links.dot "Menus and Pages" |
261 | + */ |
262 | function planet_menu() { |
263 | - |
264 | $items['admin/settings/planet'] = array( |
265 | 'title' => 'Planet Settings', |
266 | 'description' => 'Configure settings for the planet module.', |
267 | @@ -84,31 +157,28 @@ |
268 | ); |
269 | |
270 | // if (arg(0) == 'planet' && is_numeric(arg(1))) { |
271 | + // FIXME access denied http://localhost/drupal/?q=planet/1 |
272 | $items['planet/'. '%'] = array( |
273 | 'title' => 'planet', |
274 | 'page callback' => 'planet_page_user', |
275 | 'page arguments' => array(arg(1)) |
276 | ); |
277 | -// } |
278 | |
279 | -// if (arg(3) == 'refresh' && is_numeric(arg(4))) { |
280 | - |
281 | + // if (arg(3) == 'refresh' && is_numeric(arg(4))) { |
282 | $items['admin/settings/planet/refresh/%'] = array( |
283 | 'title' => 'planet refresh', |
284 | 'page callback' => 'planet_call_refresh', |
285 | 'access arguments' => array('administer nodes'), |
286 | 'type' => MENU_CALLBACK |
287 | ); |
288 | -// } |
289 | |
290 | -// if (is_numeric(arg(4)) && (arg(3) == 'freeze' || arg(3) == 'unfreeze')) { |
291 | + // if (is_numeric(arg(4)) && (arg(3) == 'freeze' || arg(3) == 'unfreeze')) { |
292 | $items['admin/settings/planet/'. arg(3) .'/%'] = array( |
293 | 'title' => 'planet freeze', |
294 | 'page callback' => 'planet_toggle_frozen', |
295 | 'access arguments' => array('administer nodes'), |
296 | 'type' => MENU_CALLBACK |
297 | ); |
298 | -// } |
299 | |
300 | $items['planet'] = array( |
301 | 'title' => 'Planet', |
302 | @@ -128,6 +198,12 @@ |
303 | return $items; |
304 | } |
305 | |
306 | + |
307 | +/** |
308 | + * Page callback for 'admin/settings/planet/refresh/%' ("planet refresh") |
309 | + * |
310 | + * @ingroup page |
311 | + */ |
312 | function planet_call_refresh() { |
313 | $title = planet_refresh(); |
314 | watchdog('planet', 'Feed "'. $title .'" refreshed.'); |
315 | @@ -135,6 +211,12 @@ |
316 | drupal_goto('admin/settings/planet'); |
317 | } |
318 | |
319 | +/** |
320 | + * Page callback for 'admin/settings/planet/(un|)freeze/%' ("planet freeze") |
321 | + * |
322 | + * @ingroup page |
323 | + * @CRUD{planet_feeds,U} |
324 | + */ |
325 | function planet_toggle_frozen() { |
326 | |
327 | $fid = intval(arg(4)); |
328 | @@ -144,53 +226,57 @@ |
329 | } |
330 | |
331 | |
332 | +/** |
333 | + * Deletes a feed and related items |
334 | + * @param $fid the feed identifier key (integer) |
335 | + * |
336 | + * @internal |
337 | + * @ingroup planet_feed |
338 | + * @CRUD{planet_items,R} |
339 | + * @invoke{drupal_get_form,planet_multiple_delete_confirm} |
340 | + */ |
341 | +function planet__drop_feed($fid) { |
342 | + $result = db_query('SELECT nid FROM {planet_items} WHERE fid = %d', intval($edit['fid'])); |
343 | + while ($node = db_fetch_object($result)) { |
344 | + $nodes[$node->nid] = TRUE; |
345 | + } |
346 | + return drupal_get_form('planet_multiple_delete_confirm', $nodes, |
347 | + intval($edit['fid']), 'user/'. $user->uid .'/planet'); |
348 | +} |
349 | + |
350 | +/** |
351 | + * Page callback for 'user/%user/planet' ("Planet Feeds") |
352 | + * |
353 | + * @ingroup page |
354 | + * @CRUD{planet_feeds,R} |
355 | + * @invoke{drupal_get_form,planet_multiple_delete_confirm_submit} |
356 | + * @invoke{drupal_get_form,planet_feed_form} |
357 | + */ |
358 | function planet_user_feeds() { |
359 | -global $user; |
360 | -if ($_POST) { |
361 | + global $user; |
362 | + if ($_POST) { |
363 | $edit = $_POST; |
364 | - if ($_POST['op'] == 'Delete' && intval($edit['fid']) > 0) { |
365 | - $result = db_query('SELECT nid FROM {planet_items} WHERE fid = %d', intval($edit['fid'])); |
366 | - while ($node = db_fetch_object($result)) { |
367 | - $nodes[$node->nid] = TRUE; |
368 | - } |
369 | - return drupal_get_form('planet_multiple_delete_confirm', $nodes, intval($edit['fid']), 'user/'. $user->uid .'/planet'); |
370 | - } |
371 | - else if ($_POST['op'] == 'Delete all' && $_POST['confirm'] == 1) { |
372 | - $edit['fid'] = intval(arg(3)); |
373 | + $fid = intval($edit['fid']); |
374 | + if (($_POST['op'] == 'Delete') && ($fid != 0)) { |
375 | + return planet__drop_feed($fid); |
376 | + } else if ($_POST['op'] == 'Delete all' && $_POST['confirm'] == 1) { |
377 | + $edit['fid'] = intval(arg(3)); // @deprecated arg() |
378 | $edit['redirect'] = 'user/'. $user->uid .'/planet'; |
379 | return drupal_get_form('planet_multiple_delete_confirm_submit', $edit); |
380 | - } |
381 | - else { |
382 | - if (isset($edit['fid']) && intval($edit['fid']) == 0) { |
383 | - db_query('INSERT INTO {planet_feeds} (uid, title, link, image, checked, frozen) VALUES(%d, "%s", "%s", "%s", 0, 0)', $user->uid, $edit['title'], $edit['link'], $edit['image']); |
384 | - $edit_r = db_fetch_array(db_query('SELECT fid FROM {planet_feeds} WHERE uid = %d AND title = "%s" AND link = "%s"', $user->uid, $edit['title'], $edit['link'])); |
385 | - $title = planet_refresh(intval($edit_r['fid'])); |
386 | - drupal_set_message('Added new feed: ' . $title); |
387 | - } |
388 | - else if ($edit['fid'] && intval($edit['fid']) > 0) { |
389 | - db_query('UPDATE {planet_feeds} SET uid = %d, title="%s", link = "%s", image="%s" WHERE fid=%d', $user->uid, $edit['title'], $edit['link'], $edit['image'], $edit['fid']); |
390 | - drupal_set_message('Edited "'. $edit['title'] .'" feed.'); |
391 | - } |
392 | - else { |
393 | - if ($edit['planet_author_roles']) { |
394 | - variable_set('planet_author_roles', $edit['planet_author_roles']); |
395 | - } |
396 | - if ($edit['planet_filter_formats']) { |
397 | - variable_set('planet_filter_formats', $edit['planet_filter_formats']); |
398 | - } |
399 | - if ($edit['planet_redirect_page'] == 1) { |
400 | - variable_set('planet_redirect_page', $edit['planet_redirect_page']); |
401 | - } |
402 | - else { |
403 | - variable_del('planet_redirect_page'); |
404 | - } |
405 | - drupal_set_message('Edited general planet settings.'); |
406 | + } else { |
407 | + if (isset($edit['fid'])) { |
408 | + if (intval($edit['fid']) == 0) { |
409 | + planet__add_feed($edit); |
410 | + } else { |
411 | + planet__update_feed($edit); |
412 | + } |
413 | + } else { |
414 | + planet__update_vars($edit); |
415 | } |
416 | } |
417 | drupal_goto('user/'. $user->uid .'/planet'); |
418 | - } |
419 | - else { |
420 | - $fid = intval(arg(3)); |
421 | + } else { // no $_POST |
422 | + $fid = intval(arg(3)); // @deprecated: arg() |
423 | if ($fid > 0) { |
424 | $edit = db_fetch_array(db_query('SELECT * FROM {planet_feeds} WHERE fid = %d', $fid)); |
425 | $output .= drupal_get_form('planet_feed_form', $edit, true, $user); |
426 | @@ -199,32 +285,143 @@ |
427 | |
428 | $output .= drupal_get_form('planet_feed_form', $edit, false, $user); |
429 | |
430 | - // $result = db_query('SELECT *, (UNIX_TIMESTAMP(NOW()) - checked) _checked FROM {planet_feeds}'); |
431 | - $result = db_query('SELECT COUNT(f.fid) cnt, f.*, (UNIX_TIMESTAMP(NOW()) - checked) _checked FROM {planet_feeds} f LEFT OUTER JOIN {planet_items} i ON i.fid = f.fid WHERE f.uid = %d GROUP BY f.fid;', $user->uid); |
432 | + $output .= '<h2>Feeds</h2>'; |
433 | + $output .= planet__build_user_feeds_table(); |
434 | + } |
435 | + print theme('page', $output); |
436 | + } |
437 | +} |
438 | + |
439 | +// Note: I use 'planet__' prefix to name internal functions |
440 | +// TODO: apply the same naming convention (this one or another) in whole module |
441 | +/** |
442 | + * @todo merge with planet__build_admin_feeds_table() |
443 | + * |
444 | + * @ingroup planet_feed |
445 | + * @internal |
446 | + * @CRUD{planet_feeds,R} |
447 | + * @CRUD{planet_items,R} |
448 | + */ |
449 | +function planet__build_user_feeds_table() { |
450 | + // @DIFFINFO renamed planet__build_feeds_table1 |
451 | + global $user; |
452 | + $feeds = db_query('SELECT fid, title, checked FROM {planet_feeds} ' |
453 | + . ' WHERE uid = %d;', $user->uid); |
454 | $rows = array(); |
455 | $headers = array('Feed', 'Items', 'Edit', 'Last checked'); |
456 | - while ($feed = db_fetch_object($result)) { |
457 | - $checked = intval($feed->_checked / 60) .' minutes'; |
458 | - if ($feed->_checked % 60 > 0) { |
459 | + $now = time(); |
460 | + $items_statement = 'SELECT count(*) FROM {planet_items}' |
461 | + . ' WHERE fid=%d'; |
462 | + // TODO: change this to prepared statement when supported by drupal DB abstraction layer. |
463 | + while ($feed = db_fetch_object($feeds)) { |
464 | + $_checked = $now - $feed->checked; |
465 | + $checked = intval($_checked / 60) .' minutes'; |
466 | + if ($_checked % 60 > 0) { |
467 | $checked .= ', '. $feed->_checked % 60 .' seconds'; |
468 | } |
469 | $checked .= ' ago'; |
470 | + $items = db_query($items_statement, $feed->fid); |
471 | + if (!$items) trigger_error('ERROR while counting feed items.'); |
472 | + $cnt = db_result($items); |
473 | array_push($rows, array( |
474 | $feed->title, |
475 | - $feed->cnt, |
476 | + $cnt, |
477 | l('edit', 'user/'. $user->uid .'/planet/'. intval($feed->fid)), |
478 | $checked, |
479 | ) |
480 | ); |
481 | } |
482 | - $output .= '<h2>Feeds</h2>'; |
483 | - $output .= theme('table', $headers, $rows); |
484 | - } |
485 | - print theme('page', $output); |
486 | - } |
487 | -} |
488 | - |
489 | - |
490 | + return theme('table', $headers, $rows); |
491 | +} |
492 | + |
493 | +/** |
494 | + * Adds a new feed to planet_feeds table. |
495 | + * @param $data associative array with keys |
496 | + * 'uid' (optional), 'title', 'link', 'image' (optional) |
497 | + * @return success status |
498 | + * |
499 | + * @ingroup planet_feed |
500 | + * @internal |
501 | + * @CRUD{planet_feeds,C} |
502 | + */ |
503 | +function planet__add_feed($data) { |
504 | + $data['checked'] = 0; |
505 | + $data['frozen'] = 0; |
506 | + if (isset($data['fid'])) { // @DEBUGGING |
507 | + trigger_error('Primary key fid shouldn\'t be set for a need feed (value: {$data->fid}). Record not added.', E_ERROR); |
508 | + return FALSE; |
509 | + } |
510 | + $rslt = drupal_write_record('planet_feeds', $data); |
511 | + if ($rslt==SAVED_NEW) { |
512 | + $title = planet_refresh(intval($data['fid'])); |
513 | + drupal_set_message('Added new feed: ' . $title); |
514 | + return TRUE; |
515 | + } |
516 | + trigger_error('Failed to add new feed'); |
517 | + return FALSE; |
518 | +} |
519 | + |
520 | +/** |
521 | + * Updates an existing feed in planet_feeds table. |
522 | + * @param $data associative array with keys |
523 | + * 'fid' (mandatory, primary key), |
524 | + * other fields as needed: |
525 | + * 'uid', 'title', 'link', 'image', 'checked', 'frozen' |
526 | + * @return success status |
527 | + * |
528 | + * @ingroup planet_feed |
529 | + * @internal |
530 | + * @CRUD{planet_feeds,U} |
531 | +*/ |
532 | +function planet__update_feed($data) { |
533 | + $rslt = drupal_write_record('planet_feeds', $data, 'fid'); |
534 | + if ($rslt==SAVED_UPDATED) { |
535 | + drupal_set_message('Edited "'. $data['title'] .'" feed.'); |
536 | + return TRUE; |
537 | + } |
538 | + if ($rslt==SAVED_NEW) // @DEBUGGING |
539 | + trigger_error('Feed {$data->fid} didn\'t exist. Record added.', E_ERROR); |
540 | + else |
541 | + trigger_error('Failed to edit feed'); |
542 | + return FALSE; |
543 | +} |
544 | + |
545 | +/** |
546 | + * Updates an planet settings persistent variables. |
547 | + * @param $data associative array with all optional keys |
548 | + * 'planet_author_roles', 'planet_filter_formats', |
549 | + * 'planet_redirect_page'. |
550 | + * |
551 | + * @ingroup isettings |
552 | + * @internal |
553 | + * @CRUD{variables,CUD} |
554 | +*/ |
555 | +function planet__update_vars($data) { |
556 | + if ($edit['planet_author_roles']) { |
557 | + variable_set('planet_author_roles', $edit['planet_author_roles']); |
558 | + } |
559 | + if ($edit['planet_filter_formats']) { |
560 | + variable_set('planet_filter_formats', $edit['planet_filter_formats']); |
561 | + } |
562 | + if ($edit['planet_redirect_page'] == 1) { |
563 | + variable_set('planet_redirect_page', $edit['planet_redirect_page']); |
564 | + } else { |
565 | + variable_del('planet_redirect_page'); |
566 | + } |
567 | + drupal_set_message('Edited general planet settings.'); |
568 | +} |
569 | + |
570 | +/** |
571 | + * Page callback for 'admin/settings/planet' ("Planet Settings") |
572 | + * |
573 | + * @ingroup page |
574 | + * @CRUD{planet_items,R} |
575 | + * @CRUD{planet_feeds,R} |
576 | + * @invoke{drupal_get_form,planet_multiple_delete_confirm} |
577 | + * @invoke{drupal_get_form,planet_multiple_delete_confirm_submit} |
578 | + * @invoke{drupal_get_form,planet_feed_form} |
579 | + * @invoke{drupal_get_form,planet_settings_form} |
580 | + */ |
581 | function _planet_settings() { |
582 | if ($_POST) { |
583 | $edit = $_POST; |
584 | @@ -241,37 +438,23 @@ |
585 | $edit['redirect'] = 'admin/settings/planet'; |
586 | return drupal_get_form('planet_multiple_delete_confirm_submit', $edit); |
587 | } |
588 | - else { |
589 | - if (isset($edit['fid']) && intval($edit['fid']) == 0) { |
590 | - db_query('INSERT INTO {planet_feeds} (uid, title, link, image, checked, frozen) VALUES(%d, "%s", "%s", "%s", 0, 0)', $edit['uid'], $edit['title'], $edit['link'], $edit['image']); |
591 | - $edit_r = db_fetch_array(db_query('SELECT fid FROM {planet_feeds} WHERE uid = %d AND title = "%s" AND link = "%s"', $edit['uid'], $edit['title'], $edit['link'])); |
592 | - $title = planet_refresh(intval($edit_r['fid'])); |
593 | - drupal_set_message('Added new feed: ' . $title); |
594 | - } |
595 | - else if ($edit['fid'] && intval($edit['fid']) > 0) { |
596 | - db_query('UPDATE {planet_feeds} SET uid = %d, title="%s", link = "%s", image="%s" WHERE fid=%d', $edit['uid'], $edit['title'], $edit['link'], $edit['image'], $edit['fid']); |
597 | - drupal_set_message('Edited "'. $edit['title'] .'" feed.'); |
598 | - } |
599 | - else { |
600 | - if ($edit['planet_author_roles']) { |
601 | - variable_set('planet_author_roles', $edit['planet_author_roles']); |
602 | - } |
603 | - if ($edit['planet_filter_formats']) { |
604 | - variable_set('planet_filter_formats', $edit['planet_filter_formats']); |
605 | - } |
606 | - if ($edit['planet_redirect_page'] == 1) { |
607 | - variable_set('planet_redirect_page', $edit['planet_redirect_page']); |
608 | - } |
609 | - else { |
610 | - variable_del('planet_redirect_page'); |
611 | - } |
612 | - drupal_set_message('Edited general planet settings.'); |
613 | + else { |
614 | + if (isset($edit['fid'])) { |
615 | + if (intval($edit['fid']) == 0) { |
616 | + planet__add_feed($edit); |
617 | + } else { |
618 | + planet__update_feed($edit); |
619 | + } |
620 | + } else { |
621 | + // TODO if user needs to click separately for each fieldset, |
622 | + // why not using different forms ? |
623 | + // or conversely, allow setting everything at once ? |
624 | + planet__update_vars($edit); |
625 | } |
626 | } |
627 | drupal_goto('admin/settings/planet'); |
628 | - } |
629 | - else { |
630 | - $fid = intval(arg(3)); |
631 | + } else { |
632 | + $fid = intval(arg(3)); // @deprecated arg() |
633 | if ($fid > 0) { |
634 | $edit = db_fetch_array(db_query('SELECT * FROM {planet_feeds} WHERE fid = %d', $fid)); |
635 | $output .= drupal_get_form('planet_feed_form', $edit, true); |
636 | @@ -279,38 +462,72 @@ |
637 | else { |
638 | |
639 | $output .= drupal_get_form('planet_settings_form'); |
640 | - //$output .= drupal_get_form('settings', $form); |
641 | - //$output .= $form; |
642 | |
643 | $output .= drupal_get_form('planet_feed_form', $edit); |
644 | |
645 | - // $result = db_query('SELECT *, (UNIX_TIMESTAMP(NOW()) - checked) _checked FROM {planet_feeds}'); |
646 | - $result = db_query('SELECT COUNT(f.fid) cnt, f.*, (UNIX_TIMESTAMP(NOW()) - checked) _checked FROM {planet_feeds} f LEFT OUTER JOIN {planet_items} i ON i.fid = f.fid GROUP BY f.fid;'); |
647 | - $rows = array(); |
648 | - $headers = array('Feed', 'Items', 'Edit', 'Last checked', 'Refresh', 'Freeze'); |
649 | - while ($feed = db_fetch_object($result)) { |
650 | - $checked = intval($feed->_checked / 60) .' minutes'; |
651 | - if ($feed->_checked % 60 > 0) { |
652 | - $checked .= ', '. $feed->_checked % 60 .' seconds'; |
653 | - } |
654 | - $checked .= ' ago'; |
655 | - array_push($rows, array( |
656 | - $feed->title, |
657 | - $feed->cnt, |
658 | - l('edit', 'admin/settings/planet/'. intval($feed->fid)), |
659 | - $checked, |
660 | - l('refresh', 'admin/settings/planet/refresh/'. intval($feed->fid)), |
661 | - l($feed->frozen ? 'unfreeze' : 'freeze', 'admin/settings/planet/'. ($feed->frozen ? 'unfreeze/' : 'freeze/') . intval($feed->fid)) |
662 | - ) |
663 | - ); |
664 | - } |
665 | $output .= '<h2>Feeds</h2>'; |
666 | - $output .= theme('table', $headers, $rows); |
667 | + $output .= planet__build_admin_feeds_table(); |
668 | } |
669 | print theme('page', $output); |
670 | } |
671 | } |
672 | |
673 | +/** |
674 | + * builds an HTML table of feeds for administrator interaction. |
675 | + * |
676 | + * @return |
677 | + * |
678 | + * @ingroup planet_feed |
679 | + * @internal |
680 | + * @CRUD{planet_feeds,R} |
681 | + * @CRUD{planet_items,R} |
682 | + */ |
683 | +function planet__build_admin_feeds_table() { |
684 | + // @DIFFINFO renamed planet__build_feeds_table() { |
685 | + global $user; |
686 | + $feeds = db_query('SELECT fid, title, checked, frozen FROM {planet_feeds} ' |
687 | + . ' WHERE uid = %d;', $user->uid); |
688 | + $rows = array(); |
689 | + $headers = array('Feed', 'Items', 'Edit', 'Last checked', 'Refresh', 'Freeze'); |
690 | + $now = time(); |
691 | + $items_statement = 'SELECT count(*) FROM {planet_items} WHERE fid=%'; |
692 | + // TODO: change this to prepared statement when supported by drupal DB Abstraction Layer. |
693 | + while ($feed = db_fetch_object($feeds)) { |
694 | + $_checked = $now - $feed->checked; |
695 | + $checked = intval($_checked / 60) .' minutes'; |
696 | + if ($_checked % 60 > 0) { |
697 | + $checked .= ', '. $feed->_checked % 60 .' seconds'; |
698 | + } |
699 | + $checked .= ' ago'; |
700 | + $items = db_query($items_statement, $feed->fid); |
701 | + if (!$items) trigger_error('ERROR while counting feed items.'); |
702 | + $cnt = db_result($items); |
703 | + $fid = strval($feed->fid); |
704 | + array_push($rows, array( |
705 | + $feed->title, |
706 | + $cnt, |
707 | + l('edit', 'admin/settings/planet/'. $fid), |
708 | + $checked, |
709 | + l('refresh', 'admin/settings/planet/refresh/'. $fid), |
710 | + l($feed->frozen ? 'unfreeze' : 'freeze', 'admin/settings/planet/'. ($feed->frozen ? 'unfreeze/' : 'freeze/') . $fid) |
711 | + ) |
712 | + ); |
713 | + } |
714 | + return theme('table', $headers, $rows); |
715 | +} |
716 | + |
717 | +/** |
718 | + * TODO. |
719 | + * |
720 | + * @param &$form_state |
721 | + * @param $nodes |
722 | + * @param $fid |
723 | + * @param $redirect |
724 | + * @return |
725 | + * |
726 | + * @ingroup iforms |
727 | + * @CRUD{node,R} |
728 | + */ |
729 | function planet_multiple_delete_confirm(&$form_state, $nodes, $fid, $redirect) { |
730 | $form_state['values']['fid'] = $fid; |
731 | $form_state['values']['redirect'] = $redirect; |
732 | @@ -333,21 +550,42 @@ |
733 | t('Delete all'), t('Cancel')); |
734 | } |
735 | |
736 | +/** |
737 | + * TODO. |
738 | + * |
739 | + * @param &$form_state |
740 | + * @param $edit |
741 | + * @return |
742 | + * |
743 | + * @ingroup iforms |
744 | + * @CRUD{node,D} |
745 | + * @CRUD{planet_items,D} |
746 | + * @CRUD{planet_feeds,D} |
747 | + */ |
748 | function planet_multiple_delete_confirm_submit(&$form_state, $edit) { |
749 | $fid = $edit['fid']; |
750 | if ($edit['confirm']) { |
751 | foreach ($edit['nodes'] as $nid => $value) { |
752 | node_delete($nid); |
753 | } |
754 | + // @DIFFINFO inverted drop order to respect foreign keys |
755 | + db_query('DELETE FROM {planet_items} WHERE fid = %d', $fid); |
756 | db_query('DELETE FROM {planet_feeds} WHERE fid = %d', $fid); |
757 | - db_query('DELETE FROM {planet_items} WHERE fid = %d', $fid); |
758 | drupal_set_message(t('The feed and items have been deleted.')); |
759 | } |
760 | drupal_goto($edit['redirect']); |
761 | } |
762 | |
763 | |
764 | - |
765 | +/** |
766 | + * TODO. |
767 | + * |
768 | + * @param &$form_state |
769 | + * @return |
770 | + * @ingroup iforms |
771 | + * @CRUD{role,R} |
772 | + * @CRUD{variables,R} |
773 | + */ |
774 | function planet_settings_form(&$form_state) { |
775 | $roles = array(); |
776 | |
777 | @@ -402,6 +640,20 @@ |
778 | } |
779 | |
780 | |
781 | +/** |
782 | + * TODO. |
783 | + * |
784 | + * @param &$form_state |
785 | + * @param $edit |
786 | + * @param $individual |
787 | + * @param $user |
788 | + * @return |
789 | + * @ingroup iforms |
790 | + * @CRUD{users,R} |
791 | + * @CRUD{role,R} |
792 | + * @CRUD{users_roles,R} |
793 | + * @CRUD{variables,R} |
794 | + */ |
795 | function planet_feed_form(&$form_state, $edit = array(), $individual = false, $user = NULL) { |
796 | $uids = array(); |
797 | $result = db_query('SELECT u.uid, u.name FROM {users} u, {role} r, {users_roles} ur WHERE u.uid = ur.uid AND ur.rid = r.rid AND r.rid = %d ORDER BY u.name ASC', variable_get('planet_author_roles', 2)); |
798 | @@ -474,6 +726,13 @@ |
799 | return $form; |
800 | } |
801 | |
802 | +/** |
803 | + * Implementation of hook_cron - Perform periodic actions. |
804 | + * |
805 | + * @return none |
806 | + * @ingroup system |
807 | + * @CRUD{planet_feeds,R} |
808 | + */ |
809 | function planet_cron() { |
810 | $result = db_query('SELECT fid FROM {planet_feeds} WHERE frozen = 0'); |
811 | while ($feed = db_fetch_object($result)) { |
812 | @@ -482,6 +741,17 @@ |
813 | } |
814 | } |
815 | |
816 | + |
817 | +/** |
818 | + * Private function; Checks a news feed for new items. |
819 | + * |
820 | + * @param $fid feed identifier (defaults to arg(4)) |
821 | + * @return |
822 | + * |
823 | + * @private |
824 | + * @CRUD{planet_feeds,U} |
825 | + * @invoke{module_invoke,taxonomy_node_get_terms} |
826 | + */ |
827 | function planet_refresh($fid = null) { |
828 | if (!$fid) { |
829 | $fid = intval(arg(4)); |
830 | @@ -638,60 +908,8 @@ |
831 | /** |
832 | * Private function; Parse HTTP headers from data retreived with cURL |
833 | * from: http://pl2.php.net/manual/en/function.curl-setopt.php#42009 |
834 | - */ |
835 | -function planet_parse_response($response) { |
836 | - /* |
837 | - ***original code extracted from examples at |
838 | - ***http://www.webreference.com/programming |
839 | - /php/cookbook/chap11/1/3.html |
840 | - |
841 | - ***returns an array in the following format which varies depending on headers returned |
842 | - |
843 | - [0] => the HTTP error or response code such as 404 |
844 | - [1] => Array |
845 | - ( |
846 | - [Server] => Microsoft-IIS/5.0 |
847 | - [Date] => Wed, 28 Apr 2004 23:29:20 GMT |
848 | - [X-Powered-By] => ASP.NET |
849 | - [Connection] => close |
850 | - [Set-Cookie] => COOKIESTUFF |
851 | - [Expires] => Thu, 01 Dec 1994 16:00:00 GMT |
852 | - [Content-Type] => text/html |
853 | - [Content-Length] => 4040 |
854 | - ) |
855 | - [2] => Response body (string) |
856 | - */ |
857 | - |
858 | - do { |
859 | - list($response_headers, $response) = explode("\r\n\r\n", $response, 2); |
860 | - $response_header_lines = explode("\r\n", $response_headers); |
861 | - |
862 | - // first line of headers is the HTTP response code |
863 | - $http_response_line = array_shift($response_header_lines); |
864 | - if (preg_match('@^HTTP/[0-9]\.[0-9] ([0-9]{3})@', $http_response_line, $matches)) { |
865 | - $response_code = $matches[1]; |
866 | - } |
867 | - else { |
868 | - $response_code = "Error"; |
869 | - } |
870 | - } |
871 | - while (substr($response_code, 0, 1) == "1"); |
872 | - |
873 | - $response_body = $response; |
874 | - |
875 | - // put the rest of the headers in an array |
876 | - $response_header_array = array(); |
877 | - foreach ($response_header_lines as $header_line) { |
878 | - list($header, $value) = explode(':', $header_line, 2); |
879 | - $response_header_array[$header] = trim($value); |
880 | - } |
881 | - |
882 | - return array($response_code, $response_header_array, $response_body, $http_response_line); |
883 | -} |
884 | - |
885 | -/** |
886 | - * Private function; Gets data from given URL :) |
887 | - */ |
888 | + * @ingroup rss |
889 | + * @private |
890 | function planet_http_request($url, $headers = array(), $timeout = 15, $method = 'GET', $data = NULL, $follow = 3) { |
891 | if (!function_exists('curl_init')) { |
892 | return drupal_http_request($url, $headers, $method, $data, $follow); |
893 | @@ -750,11 +968,6 @@ |
894 | } |
895 | |
896 | /** |
897 | - * Private function; Checks a news feed for new items. |
898 | - */ |
899 | - |
900 | - |
901 | -/** |
902 | * Private function; |
903 | * Parse the W3C date/time format, a subset of ISO 8601. PHP date parsing |
904 | * functions do not handle this format. |
905 | @@ -763,6 +976,8 @@ |
906 | * |
907 | * @param $date_str A string with a potentially W3C DTF date. |
908 | * @return A timestamp if parsed successfully or -1 if not. |
909 | + * @ingroup rss |
910 | + * @private |
911 | */ |
912 | function planet_parse_w3cdtf($date_str) { |
913 | if (preg_match('/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/', $date_str, $match)) { |
914 | @@ -799,6 +1014,8 @@ |
915 | * |
916 | * @param $ord Number |
917 | * @return UTF-8 string |
918 | + * @ingroup rss |
919 | + * @private |
920 | */ |
921 | function planet_replace_num_entity($ord) { |
922 | $ord = $ord[1]; |
923 | @@ -959,6 +1176,8 @@ |
924 | /** |
925 | * Private function; Convert named entities to UTF-8 characters |
926 | * from: http://pl2.php.net/manual/en/function.html-entity-decode.php#51722 |
927 | + * @ingroup rss |
928 | + * @private |
929 | */ |
930 | function planet_replace_name_entities(&$text) { |
931 | static $ttr; |
932 | @@ -974,23 +1193,20 @@ |
933 | |
934 | /** |
935 | * Private function; Convert all entities to UTF-8 characters |
936 | + * @ingroup rss |
937 | + * @private |
938 | + * @invoke{preg_replace_callback,planet_replace_num_entity} |
939 | */ |
940 | function planet_replace_entities(&$text) { |
941 | $result = planet_replace_name_entities($text); |
942 | return preg_replace_callback('/&#([0-9a-fx]+);/mi', 'planet_replace_num_entity', $result); |
943 | } |
944 | |
945 | -/** |
946 | - * Private function; Clone object function to stay compatible with both php4 and php5 |
947 | - * from: Drupal 4.7CVS |
948 | - * TODO: remove after moving to Drupal 4.7 |
949 | - */ |
950 | -function planet_clone($object) { |
951 | - return version_compare(phpversion(), '5.0') < 0 ? $object : clone($object); |
952 | -} |
953 | |
954 | /** |
955 | * Private function; Convert relative URLs |
956 | + * @ingroup rss |
957 | + * @private |
958 | */ |
959 | function planet_convert_relative_urls(&$data, $base_url) { |
960 | $src = '%( href| src)="(?!\w+://)/?([^"]*)"%'; |
961 | @@ -1000,6 +1216,13 @@ |
962 | |
963 | /** |
964 | * Private function; Creates nodes from data found in given xml_tree |
965 | + * |
966 | + * @ingroup rss |
967 | + * @private |
968 | + * @CRUD{variables,R} |
969 | + * @CRUD{planet_items,R} |
970 | + * @CRUD{node,CU} |
971 | + * @invoke{module_invoke,taxonomy_node_get_terms} |
972 | */ |
973 | function planet_parse_items(&$xml_tree, &$feed) { |
974 | |
975 | @@ -1229,10 +1452,16 @@ |
976 | } |
977 | //print '<pre>'. print_r($entry, 1) .'</pre>'; |
978 | node_save($entry); |
979 | - db_query('INSERT INTO {planet_items} (fid, nid, guid, link, created) VALUES(%d, %d, "%s", "%s", UNIX_TIMESTAMP(NOW()))', $feed->fid, $entry->nid, $guid, $link); |
980 | + $item_record = array('fid' => $feed->fid, |
981 | + 'nid' => $entry->nid, |
982 | + 'guid'=> $guid, |
983 | + 'link' =>$link, |
984 | + 'created' => time()); |
985 | + drupal_write_record('planet_items', $item_record); |
986 | watchdog('planet', 'Adding '. $title); |
987 | drupal_set_message('Adding '. $title); |
988 | } |
989 | + // TODO split this huge function |
990 | } |
991 | |
992 | return $items_added; |
993 | @@ -1241,6 +1470,12 @@ |
994 | |
995 | /** |
996 | * Private function; parses given XML data and returns array |
997 | + * |
998 | + * @ingroup rss |
999 | + * @private |
1000 | + * @invoke{xml_set_element_handler,planet_element_start} |
1001 | + * @invoke{xml_set_element_handler,planet_element_end} |
1002 | + * @invoke{xml_set_character_data_handler,planet_element_data} |
1003 | */ |
1004 | function planet_parse_xml(&$data) { |
1005 | global $xml_tree, $xml_paths, $xml_path_cur; |
1006 | @@ -1297,6 +1532,8 @@ |
1007 | |
1008 | /** |
1009 | * Private call-back function used by the XML parser. |
1010 | + * @ingroup rss |
1011 | + * @internal |
1012 | */ |
1013 | function planet_element_start($parser, $name, $attributes) { |
1014 | global $xml_tree, $xml_paths, $xml_path_cur; |
1015 | @@ -1308,6 +1545,8 @@ |
1016 | |
1017 | /** |
1018 | * Private call-back function used by the XML parser. |
1019 | + * @ingroup rss |
1020 | + * @private |
1021 | */ |
1022 | function planet_element_end($parser, $name) { |
1023 | global $xml_tree, $xml_paths, $xml_path_cur; |
1024 | @@ -1322,6 +1561,8 @@ |
1025 | |
1026 | /** |
1027 | * Private call-back function used by the XML parser. |
1028 | + * @ingroup rss |
1029 | + * @private |
1030 | */ |
1031 | function planet_element_data($parser, $data) { |
1032 | global $xml_tree, $xml_paths, $xml_path_cur; |
1033 | @@ -1333,6 +1574,12 @@ |
1034 | } |
1035 | } |
1036 | |
1037 | +/** |
1038 | + * Page callback for 'planet' ("Planet"). |
1039 | + * @ingroup page |
1040 | + * @CRUD{node,R} |
1041 | + * @CRUD{variables,R} |
1042 | + */ |
1043 | function planet_page_last() { |
1044 | global $user; |
1045 | |
1046 | @@ -1351,6 +1598,12 @@ |
1047 | print theme('page', $output); |
1048 | } |
1049 | |
1050 | +/** |
1051 | + * Page callback for 'planet/feed' ("Planet"). |
1052 | + * @ingroup page |
1053 | + * @CRUD{node,R} |
1054 | + * @CRUD{menu_links,R} |
1055 | + */ |
1056 | function planet_feed() { |
1057 | $result = db_query_range(db_rewrite_sql("SELECT n.nid, n.created FROM {node} n WHERE n.type = 'planet' AND n.status = 1 ORDER BY n.created DESC"), 0, 15); |
1058 | $title = db_fetch_array(db_query("SELECT link_title FROM {menu_links} WHERE link_path = 'planet'")); |
1059 | @@ -1363,12 +1616,14 @@ |
1060 | while ($row = db_fetch_object($result)) { |
1061 | $items[] = $row->nid; |
1062 | } |
1063 | - |
1064 | + // generate RSS feed from $items set of nodes. |
1065 | node_feed($items, $channel); |
1066 | } |
1067 | |
1068 | /** |
1069 | - * Implementation of hook_user(). |
1070 | + * Implementation of hook_user() - React when operations are performed on user accounts. |
1071 | + * @ingroup system |
1072 | + * @CRUD{planet_feeds,R} |
1073 | */ |
1074 | function planet_user($type, &$edit, &$user) { |
1075 | if ($type == 'view' && user_access('edit own blog', $user)) { |
1076 | @@ -1390,6 +1645,8 @@ |
1077 | |
1078 | /** |
1079 | * Menu callback; displays a Drupal page containing recent planet entries. |
1080 | + * @todo remove orphan function, or reuse it |
1081 | + * @ingroup page |
1082 | */ |
1083 | function planet_page($a = NULL, $b = NULL) { |
1084 | |
1085 | @@ -1409,6 +1666,13 @@ |
1086 | } |
1087 | } |
1088 | |
1089 | +/** |
1090 | + * Page callback for 'planet/%' ("planet"). |
1091 | + * @ingroup page |
1092 | + * |
1093 | + * @CRUD{node,R} |
1094 | + * @CRUD{variables,R} |
1095 | + */ |
1096 | function planet_page_user($uid) { |
1097 | global $user; |
1098 | |
1099 | @@ -1441,12 +1705,28 @@ |
1100 | } |
1101 | } |
1102 | |
1103 | +/** |
1104 | + * Implementation of hook_load - Load node-type-specific information. |
1105 | + * |
1106 | + * @param $node The node being loaded. |
1107 | + * @return An object containing properties of the node being loaded. |
1108 | + * @ingroup system |
1109 | + * @CRUD{planet_items,R} |
1110 | + */ |
1111 | function planet_load($node) { |
1112 | $additions = db_fetch_object(db_query('SELECT link, guid FROM {planet_items} WHERE nid = %d', $node->nid)); |
1113 | return $additions; |
1114 | } |
1115 | |
1116 | -function planet_form(&$node, &$param) { |
1117 | +/** |
1118 | + * Implementation of hook_form - Display a node editing form. |
1119 | + * |
1120 | + * @param &$node The node being added or edited. |
1121 | + * @param $form_state The form state array (unused). |
1122 | + * @return An array containing the form elements to be displayed in the node edit form. |
1123 | + * @ingroup planet_node |
1124 | + */ |
1125 | +function planet_form(&$node, &$form_state) { |
1126 | $form = array(); |
1127 | $form['title'] = array('#type' => 'textfield', '#title' => 'Title', '#value' => $node->title, '#size' => 30, '#maxlength' => 80); |
1128 | $form['body'] = array('#type' => 'textarea', '#title' => 'Body', '#value' => $node->body); |