=== modified file 'planet.info'
--- planet.info 2009-03-01 02:54:23 +0000
+++ planet.info 2009-03-13 08:51:04 +0000
@@ -1,6 +1,7 @@
; $Id: planet.info,v 1.2 2007/05/30 03:22:01 daryl Exp $
name = Planet
description = Planet blog aggregator
+; TODO better module definition, including specificity if possible.
package = Community - optional
version = 6.x
core = 6.x
=== modified file 'planet.install'
--- planet.install 2009-03-01 03:00:14 +0000
+++ planet.install 2009-03-13 08:46:18 +0000
@@ -10,37 +10,43 @@
'description' => t('The base table for planet.'),
'fields' => array(
'fid' => array(
- 'description' => t('The primary identifier for a planet_feeds table.'),
+ 'description' => t('Primary Key: Unique identifier for a planet RSS feed.'),
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'uid' => array(
+ 'description' => t('Foreign key to {users}.uid . Identifies user who choose the feed.'),
'type' => 'int',
'unsigned' => 1,
'not null' => FALSE,
),
'title' => array(
'type' => 'varchar',
+ 'description' => t('Title of the feed.'),
'length' => 50,
'not null' => TRUE,
),
'link' => array(
'type' => 'varchar',
+ 'description' => t('URL to the feed'),
'length' => 80,
'not null' => TRUE,
),
'image' => array(
+ 'description' => t('An image representing the feed'),
'type' => 'varchar',
'length' => 120,
'not null' => FALSE,
),
'checked' => array(
+ 'description' => t('Last time feed was checked for new items, as Unix timestamp'),
'type' => 'int',
'not null' => FALSE,
),
'frozen' => array(
- 'type' => 'int',
+ // TODO: add field description 'description' => t(''),
+ 'type' => 'int', // TODO change to boolean when supported
'not null' => TRUE,
'default' => 0,
),
@@ -52,7 +58,7 @@
'description' => t('contain feed id and its corresponding nid'),
'fields' => array(
'id' => array(
- 'description' => t('The primary identifier for a planet_items table'),
+ 'description' => t('Primary key: Unique identifier for a planet feed item'),
'type' => 'serial',
'unsigned' => 1,
'not null' => TRUE,
@@ -91,11 +97,9 @@
/**
* Implementation of hook_install()
*
- * This will automatically install the database tables for the planet module for MySQL.
+ * This will automatically install the database tables for the planet
+ * module, using Drupal's data abstraction layer.
*
- * If you are using another database, you will have to install the tables by hand, using the queries below as a reference.
- *
- *
*/
function planet_install() {
@@ -106,9 +110,9 @@
/**
* Implementation of hook_uninstall()
*
- * This will automatically uninstall the database tables for the planet module for MySQL.
+ * Uninstalls planet module by removing its own database tables, nodes
+ * and persistent variables.
*
- *
*/
function planet_uninstall() {
=== modified file 'planet.module'
--- planet.module 2009-03-08 19:00:05 +0000
+++ planet.module 2009-03-13 21:27:34 +0000
@@ -3,7 +3,13 @@
/**
* @file
- * The planet module
+ * The planet module.
+ *
+ * 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.
*
*/
@@ -33,6 +39,7 @@
$output .= '
General Settings. 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.';
$output .= 'Feeds. 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.';
$output .= 'Feeds. 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.';
+ $output .= '';
return $output;
case 'admin/modules#description':
return t('Aggregates RSS feeds and faciliates their association with site users who belong to a given role.');
@@ -41,8 +48,10 @@
function planet_view($node, $teaser = FALSE, $page = FALSE, $links = TRUE) {
if ($page === true && variable_get('planet_redirect_page', 0) == 1) {
- $obj = db_fetch_object(db_query('SELECT * FROM {planet_items} WHERE nid = %d', $node->nid));
- if ($obj->nid == $node->nid && $obj->link != '') {
+ $obj = db_fetch_object(db_query('SELECT link FROM {planet_items} WHERE nid = %d', $node->nid));
+ // if the query succeeds, $obj->nid == $node->nid , otherwise, $obj==FALSE,
+ // only 'link' field is used, so I restricted the query
+ if ($obj && $obj->link != '') {
header('Location: '. $obj->link);
exit;
}
@@ -128,6 +137,10 @@
return $items;
}
+
+/**
+ * Page callback for 'admin/settings/planet/refresh/%' ("planet refresh")
+ */
function planet_call_refresh() {
$title = planet_refresh();
watchdog('planet', 'Feed "'. $title .'" refreshed.');
@@ -135,6 +148,9 @@
drupal_goto('admin/settings/planet');
}
+/**
+ * Page callback for 'admin/settings/planet/(un|)freeze/%' ("planet freeze")
+ */
function planet_toggle_frozen() {
$fid = intval(arg(4));
@@ -144,53 +160,47 @@
}
-function planet_user_feeds() {
-global $user;
-if ($_POST) {
- $edit = $_POST;
- if ($_POST['op'] == 'Delete' && intval($edit['fid']) > 0) {
+/**
+ * Deletes a feed and related items
+ * @param $fid the feed identifier key (integer)
+ */
+function planet__drop_feed($fid) {
$result = db_query('SELECT nid FROM {planet_items} WHERE fid = %d', intval($edit['fid']));
while ($node = db_fetch_object($result)) {
$nodes[$node->nid] = TRUE;
}
- return drupal_get_form('planet_multiple_delete_confirm', $nodes, intval($edit['fid']), 'user/'. $user->uid .'/planet');
- }
- else if ($_POST['op'] == 'Delete all' && $_POST['confirm'] == 1) {
- $edit['fid'] = intval(arg(3));
+ return drupal_get_form('planet_multiple_delete_confirm', $nodes,
+ intval($edit['fid']), 'user/'. $user->uid .'/planet');
+}
+
+/**
+ * Page callback for 'user/%user/planet' ("Planet Feeds")
+ */
+function planet_user_feeds() {
+ global $user;
+ if ($_POST) {
+ $edit = $_POST;
+ $fid = intval($edit['fid']);
+ if (($_POST['op'] == 'Delete') && ($fid != 0)) {
+ return planet__drop_feed($fid);
+ } else if ($_POST['op'] == 'Delete all' && $_POST['confirm'] == 1) {
+ $edit['fid'] = intval(arg(3)); // @deprecated arg()
$edit['redirect'] = 'user/'. $user->uid .'/planet';
return drupal_get_form('planet_multiple_delete_confirm_submit', $edit);
- }
- else {
- if (isset($edit['fid']) && intval($edit['fid']) == 0) {
- 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']);
- $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']));
- $title = planet_refresh(intval($edit_r['fid']));
- drupal_set_message('Added new feed: ' . $title);
- }
- else if ($edit['fid'] && intval($edit['fid']) > 0) {
- 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']);
- drupal_set_message('Edited "'. $edit['title'] .'" feed.');
- }
- else {
- if ($edit['planet_author_roles']) {
- variable_set('planet_author_roles', $edit['planet_author_roles']);
- }
- if ($edit['planet_filter_formats']) {
- variable_set('planet_filter_formats', $edit['planet_filter_formats']);
- }
- if ($edit['planet_redirect_page'] == 1) {
- variable_set('planet_redirect_page', $edit['planet_redirect_page']);
+ } else {
+ if (isset($edit['fid'])) {
+ if (intval($edit['fid']) == 0) {
+ planet__add_feed($edit);
+ } else {
+ planet__update_feed($edit);
}
- else {
- variable_del('planet_redirect_page');
- }
- drupal_set_message('Edited general planet settings.');
+ } else {
+ planet__update_vars($edit);
}
}
drupal_goto('user/'. $user->uid .'/planet');
- }
- else {
- $fid = intval(arg(3));
+ } else { // no $_POST
+ $fid = intval(arg(3)); // @deprecated: arg()
if ($fid > 0) {
$edit = db_fetch_array(db_query('SELECT * FROM {planet_feeds} WHERE fid = %d', $fid));
$output .= drupal_get_form('planet_feed_form', $edit, true, $user);
@@ -199,32 +209,100 @@
$output .= drupal_get_form('planet_feed_form', $edit, false, $user);
- // $result = db_query('SELECT *, (UNIX_TIMESTAMP(NOW()) - checked) _checked FROM {planet_feeds}');
- $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);
+ $output .= 'Feeds
';
+ $output .= planet__build_feeds_table1();
+ }
+ print theme('page', $output);
+ }
+}
+
+// Note: I use 'planet__' prefix to name internal (private) functions
+// TODO: apply the same naming convention (this one or another) in whole module
+/**
+ * TODO merge with planet__build_feeds_table()
+ */
+function planet__build_feeds_table1() {
+ global $user;
+ $feeds = db_query('SELECT fid, title, checked FROM {planet_feeds} '
+ . ' WHERE uid = %d;', $user->uid);
$rows = array();
$headers = array('Feed', 'Items', 'Edit', 'Last checked');
- while ($feed = db_fetch_object($result)) {
- $checked = intval($feed->_checked / 60) .' minutes';
- if ($feed->_checked % 60 > 0) {
+ $now = time();
+ $items_statement = 'SELECT count(*) FROM {planet_items}'
+ . ' WHERE fid=%d';
+ // TODO: change this to prepared statement when support by drupal DB abastraction layer.
+ while ($feed = db_fetch_object($feeds)) {
+ $_checked = $now - $feed->checked;
+ $checked = intval($_checked / 60) .' minutes';
+ if ($_checked % 60 > 0) {
$checked .= ', '. $feed->_checked % 60 .' seconds';
}
$checked .= ' ago';
+ $items = db_query($items_statement, $feed->fid);
+ if (!$items) trigger_error('ERROR while counting feed items.');
+ $cnt = db_result($items);
array_push($rows, array(
$feed->title,
- $feed->cnt,
+ $cnt,
l('edit', 'user/'. $user->uid .'/planet/'. intval($feed->fid)),
$checked,
)
);
}
- $output .= 'Feeds
';
- $output .= theme('table', $headers, $rows);
- }
- print theme('page', $output);
- }
+ return theme('table', $headers, $rows);
}
+/**
+ * Adds a new feed to planet_feeds table.
+ * @param $data associative array with keys
+ * 'uid' (optional), 'title', 'link', 'image' (optional)
+ */
+function planet__add_feed($data) {
+ $data['checked'] = 0;
+ $data['frozen'] = 0;
+ $rslt = drupal_write_record('planet_feeds', $data);
+ if ($rslt!=SAVED_NEW) trigger_error('Failed to add new feed');
+ $title = planet_refresh(intval($data['fid']));
+ drupal_set_message('Added new feed: ' . $title);
+}
+/**
+ * Updates an existing feed in planet_feeds table.
+ * @param $data associative array with keys
+ * 'fid' (mandatory, primary key),
+ * other fields as needed:
+ * 'uid', 'title', 'link', 'image', 'checked', 'frozen'
+ */
+function planet__update_feed($data) {
+ $rslt = drupal_write_record('planet_feeds', $data, 'fid');
+ if ($rslt!=SAVED_UPDATED) trigger_error('Failed to edit feed');
+ drupal_set_message('Edited "'. $data['title'] .'" feed.');
+}
+
+/**
+ * Updates an planet settings persistent variables.
+ * @param $data associative array with all optional keys
+ * 'planet_author_roles', 'planet_filter_formats',
+ * 'planet_redirect_page'.
+ */
+function planet__update_vars($data) {
+ if ($edit['planet_author_roles']) {
+ variable_set('planet_author_roles', $edit['planet_author_roles']);
+ }
+ if ($edit['planet_filter_formats']) {
+ variable_set('planet_filter_formats', $edit['planet_filter_formats']);
+ }
+ if ($edit['planet_redirect_page'] == 1) {
+ variable_set('planet_redirect_page', $edit['planet_redirect_page']);
+ } else {
+ variable_del('planet_redirect_page');
+ }
+ drupal_set_message('Edited general planet settings.');
+}
+
+/**
+ * Page callback for 'admin/settings/planet' ("Planet Settings")
+ */
function _planet_settings() {
if ($_POST) {
$edit = $_POST;
@@ -241,37 +319,23 @@
$edit['redirect'] = 'admin/settings/planet';
return drupal_get_form('planet_multiple_delete_confirm_submit', $edit);
}
- else {
- if (isset($edit['fid']) && intval($edit['fid']) == 0) {
- 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']);
- $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']));
- $title = planet_refresh(intval($edit_r['fid']));
- drupal_set_message('Added new feed: ' . $title);
- }
- else if ($edit['fid'] && intval($edit['fid']) > 0) {
- 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']);
- drupal_set_message('Edited "'. $edit['title'] .'" feed.');
- }
- else {
- if ($edit['planet_author_roles']) {
- variable_set('planet_author_roles', $edit['planet_author_roles']);
- }
- if ($edit['planet_filter_formats']) {
- variable_set('planet_filter_formats', $edit['planet_filter_formats']);
- }
- if ($edit['planet_redirect_page'] == 1) {
- variable_set('planet_redirect_page', $edit['planet_redirect_page']);
- }
- else {
- variable_del('planet_redirect_page');
- }
- drupal_set_message('Edited general planet settings.');
+ else {
+ if (isset($edit['fid'])) {
+ if (intval($edit['fid']) == 0) {
+ planet__add_feed($edit);
+ } else {
+ planet__update_feed($edit);
+ }
+ } else {
+ // TODO if user needs to click separately for each fieldset,
+ // why not using different forms ?
+ // or conversely, allow setting everything at once ?
+ planet__update_vars($edit);
}
}
drupal_goto('admin/settings/planet');
- }
- else {
- $fid = intval(arg(3));
+ } else {
+ $fid = intval(arg(3)); // @deprecated arg()
if ($fid > 0) {
$edit = db_fetch_array(db_query('SELECT * FROM {planet_feeds} WHERE fid = %d', $fid));
$output .= drupal_get_form('planet_feed_form', $edit, true);
@@ -279,38 +343,49 @@
else {
$output .= drupal_get_form('planet_settings_form');
- //$output .= drupal_get_form('settings', $form);
- //$output .= $form;
$output .= drupal_get_form('planet_feed_form', $edit);
- // $result = db_query('SELECT *, (UNIX_TIMESTAMP(NOW()) - checked) _checked FROM {planet_feeds}');
- $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;');
- $rows = array();
- $headers = array('Feed', 'Items', 'Edit', 'Last checked', 'Refresh', 'Freeze');
- while ($feed = db_fetch_object($result)) {
- $checked = intval($feed->_checked / 60) .' minutes';
- if ($feed->_checked % 60 > 0) {
- $checked .= ', '. $feed->_checked % 60 .' seconds';
- }
- $checked .= ' ago';
- array_push($rows, array(
- $feed->title,
- $feed->cnt,
- l('edit', 'admin/settings/planet/'. intval($feed->fid)),
- $checked,
- l('refresh', 'admin/settings/planet/refresh/'. intval($feed->fid)),
- l($feed->frozen ? 'unfreeze' : 'freeze', 'admin/settings/planet/'. ($feed->frozen ? 'unfreeze/' : 'freeze/') . intval($feed->fid))
- )
- );
- }
$output .= 'Feeds
';
- $output .= theme('table', $headers, $rows);
+ $output .= planet__build_feeds_table();
}
print theme('page', $output);
}
}
+function planet__build_feeds_table() {
+ global $user;
+ $feeds = db_query('SELECT fid, title, checked, frozen FROM {planet_feeds} '
+ . ' WHERE uid = %d;', $user->uid);
+ $rows = array();
+ $headers = array('Feed', 'Items', 'Edit', 'Last checked', 'Refresh', 'Freeze');
+ $now = time();
+ $items_statement = 'SELECT count(*) FROM {planet_items} WHERE fid=%';
+ // TODO: change this to prepared statement when supported by drupal DB Abstraction Layer.
+ while ($feed = db_fetch_object($feeds)) {
+ $_checked = $now - $feed->checked;
+ $checked = intval($_checked / 60) .' minutes';
+ if ($_checked % 60 > 0) {
+ $checked .= ', '. $feed->_checked % 60 .' seconds';
+ }
+ $checked .= ' ago';
+ $items = db_query($items_statement, $feed->fid);
+ if (!$items) trigger_error('ERROR while counting feed items.');
+ $cnt = db_result($items);
+ $fid = strval($feed->fid);
+ array_push($rows, array(
+ $feed->title,
+ $cnt,
+ l('edit', 'admin/settings/planet/'. $fid),
+ $checked,
+ l('refresh', 'admin/settings/planet/refresh/'. $fid),
+ l($feed->frozen ? 'unfreeze' : 'freeze', 'admin/settings/planet/'. ($feed->frozen ? 'unfreeze/' : 'freeze/') . $fid)
+ )
+ );
+ }
+ return theme('table', $headers, $rows);
+}
+
function planet_multiple_delete_confirm(&$form_state, $nodes, $fid, $redirect) {
$form_state['values']['fid'] = $fid;
$form_state['values']['redirect'] = $redirect;
@@ -1229,10 +1304,16 @@
}
//print ''. print_r($entry, 1) .'
';
node_save($entry);
- 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);
+ $item_record = array('fid' => $feed->fid,
+ 'nid' => $entry->nid,
+ 'guid'=> $guid,
+ 'link' =>$link,
+ 'created' => time());
+ drupal_write_record('planet_items', $item_record);
watchdog('planet', 'Adding '. $title);
drupal_set_message('Adding '. $title);
}
+ // TODO split this huge function
}
return $items_added;
@@ -1333,6 +1414,9 @@
}
}
+/**
+ * Page callback for 'planet' ("Planet")
+ */
function planet_page_last() {
global $user;
@@ -1351,6 +1435,9 @@
print theme('page', $output);
}
+/**
+ * Page callback for 'planet/feed' ("Planet")
+ */
function planet_feed() {
$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);
$title = db_fetch_array(db_query("SELECT link_title FROM {menu_links} WHERE link_path = 'planet'"));
@@ -1409,6 +1496,9 @@
}
}
+/**
+ * Page callback for 'planet/%' ("planet")
+ */
function planet_page_user($uid) {
global $user;