Index: relatedlinks.module =================================================================== --- relatedlinks.module (.../trunk/newashoka/public/modules/relatedlinks/relatedlinks.module) (revision 1232) +++ relatedlinks.module (.../sandboxes/cschwartz/newashoka/public/modules/relatedlinks/relatedlinks.module) (working copy) @@ -3,21 +3,26 @@ /** * @file - * Related links are defined in 2 ways: - * 1) For certain content types, HTML links are automatically discovered and included. - * 2) The author may manually add HTML links that will appear at the top of the - * 'Related links' block. - * 3) An optional block can also list related taxonomy nodes as related links. + * Related links are defined in 3 ways: + * 1) Parsed Links: For certain content types, HTML links are + * automatically discovered and included. + * 2) Manual Links: The author may manually add HTML links that will + * appear at the top of the 'Related Links' block. + * 3) Taxonomy Links: Related taxonomy nodes can also be listed. * * When a node is viewed alone, a block is provided to authorized users that * displays a complete list of links. If no links are defined, the block will * disappear. + * + * Parsed and manual links are updated when the node is edited. Taxonomy + * links are determined on the fly. */ // Define mnemonics to indicate the types of links stored in the relatedlinks // table [type field]. -define('RELATEDLINKS_PARSED', 1); -define('RELATEDLINKS_MANUAL', 2); +define('RELATEDLINKS_PARSED', 1); +define('RELATEDLINKS_MANUAL', 2); +define('RELATEDLINKS_TAXONOMY', 3); /** * Implementation of hook_help(). @@ -27,7 +32,20 @@ case 'admin/modules#description': return t('Provides a block with related links.'); case 'admin/help#relatedlinks': - return t('Related links are defined in 2 ways: in certain input formats, HTML links are automatically discovered and included; when publishing certain content types, the author may manually add HTML links that will appear at the top of the Related links block. When a node is viewed alone, a block is provided to authorized users that displays a complete list of links. If no links are defined, the block will disappear.'); + return t('Related links are defined in 3 ways: ' . + '
http://www.example.com ' .
+ 'Clickable Text". If no title is submitted,' .
+ ' the URL itself will become the title.'),
);
}
}
@@ -144,9 +192,14 @@
* @todo Add caching support.
*/
function relatedlinks_block($op = 'list', $delta = 0) {
+
+ // Define the subheadings for each link type.
+ $headings[RELATEDLINKS_PARSED] = t('In Content');
+ $headings[RELATEDLINKS_MANUAL] = t('By Recommendation');
+ $headings[RELATEDLINKS_TAXONOMY] = t('By Taxonomy Terms');
+
if ($op == 'list') {
- $blocks[0]['info'] = t('Related links');
- $blocks[1]['info'] = t('Related taxonomy terms');
+ $blocks[0]['info'] = t('Related Links');
return $blocks;
}
if ($op == 'view') {
@@ -155,22 +208,45 @@
if ($node = node_load(arg(1))) {
switch ($delta) {
case 0:
- if (in_array($node->type, variable_get('relatedlinks_node_types', array()))) {
- // _relatedlinks_get_links also takes care of links filtering and validation.
- $links = _relatedlinks_get_links($node->nid);
-
- if (!empty($links)) {
- $block['subject'] = t('Related links');
- $block['content'] = theme('relatedlinks', $links);
+ // Only display the block if the current node type has related
+ // links enabled.
+ if (in_array($node->type,
+ variable_get('relatedlinks_node_types', array()))) {
+
+ // Combine links arrays from all sources.
+ $links_data = array_merge(
+ _relatedlinks_get_links($node->nid),
+ _relatedlinks_get_terms(array_keys($node->taxonomy),
+ $node->nid));
+
+ // If there are any links, display them.
+ if (count($links_data)) {
+ $block['subject'] = t('Related Links');
+
+ // Create an array that'll tell us how many of each link
+ // type we have. Each key is a link type, and each value
+ // is the number of that type in the $links_data array.
+ // While we're there, create a list containing only the
+ // links, with no other data.
+ $types = array();
+ $links_only = array();
+ foreach ($links_data as $key => $value) {
+ $types[$value['type']]++;
+ $links_only[] = $value['link'];
+ }
+
+ // Theme each sublist with a title.
+ $offset = 0;
+ $block['content'] = '';
+ foreach ($types as $link_type => $number_of_this_type) {
+ $block['content'] .= theme('relatedlinks',
+ array_slice($links_only, $offset, $number_of_this_type),
+ $headings[$link_type]);
+ $offset += $number_of_this_type;
+ }
}
}
break;
- case 1:
- $links = _relatedlinks_get_terms(array_keys($node->taxonomy), $node->nid);
- if (!empty($links)) {
- $block['subject'] = t('Related terms');
- $block['content'] = theme('relatedlinks_terms', $links);
- }
}
}
}
@@ -181,18 +257,11 @@
/**
* Theme the relatedlinks block output.
*/
-function theme_relatedlinks($links = array()) {
- return theme('item_list', $links);
+function theme_relatedlinks($links = array(), $title) {
+ return theme('item_list', $links, $title);
}
/**
- * Theme the relatedlinks block output.
- */
-function theme_relatedlinks_terms($links = array()) {
- return theme('item_list', $links);
-}
-
-/**
* Menu Callback: relatedlinks module settings form. Not using hook_settings
* due to the checkboxes element.
*/
@@ -206,7 +275,7 @@
$form['relatedlinks']['relatedlinks_node_types'] = array(
'#type' => 'checkboxes',
'#title' => t('Node associations'),
- '#description' => t('Select the node types to associate with the related links module [parsed and manually added links]. This is not applicable to the taxonomy terms block.'),
+ '#description' => t('Select the node types to associate with the related links module [parsed and manually added links]. This is not applicable to the taxonomy terms listing.'),
'#options' => node_get_types(),
'#default_value' => variable_get('relatedlinks_node_types', array()),
);
@@ -214,8 +283,9 @@
'#type' => 'checkboxes',
'#title' => t('Link types'),
'#description' => t('Select the link types to enable.'),
- '#options' => array('parsed' => t('Parsed links'),
- 'manual' => t('Manually added links')),
+ '#options' => array('parsed' => t('Parsed links'),
+ 'manual' => t('Manually added links'),
+ 'taxonomy' => t('Taxonomy terms')),
'#default_value' => variable_get('relatedlinks_types', array('parsed')),
);
$form['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
@@ -244,7 +314,27 @@
foreach ($links as $link) {
$link = trim($link);
if (!empty($link)) {
- db_query("INSERT INTO {relatedlinks} (nid, link, type) VALUES (%d, '%s', %d)", $nid, $link, $type);
+
+ // Manual links need to be converted from a user-friendly format
+ // to HTML format because they are entered by the user.
+ if ($type == RELATEDLINKS_MANUAL) {
+ // Get the URL and the title from the text.
+ $url_and_title = explode(" ", $link);
+ $url = array_shift($url_and_title);
+ $title = implode(" ", $url_and_title);
+
+ // If there is no title, the title will become the URL itself.
+ if (!$title) {
+ $title = $url;
+ }
+
+ // Construct the HTML-formatted link.
+ $link = "$title";
+ }
+
+ // Insert it into the database.
+ db_query("INSERT INTO {relatedlinks} (nid, link, type) " .
+ "VALUES (%d, '%s', %d)", $nid, $link, $type);
}
}
}
@@ -257,23 +347,45 @@
}
/**
- * Retrieve related links from the database.
+ * Retrieve related links from the database. This function also takes care
+ * of links filtering and validation.
+ *
+ * Returns: If $type is specified, then a one-dimensional array is returned
+ * filled with links of that type.
+ *
+ * If $type is not specified, a two-dimensional array is returned.
+ * In this case, the 'link' field will contain the link, and the
+ * 'type' field will contain the link type.
*/
function _relatedlinks_get_links($nid, $type = NULL) {
if (!isset($type)) {
- // The ORDER BY clause ensures that manually added links are given preference.
- $result = db_query('SELECT link FROM {relatedlinks} WHERE nid = %d ORDER BY TYPE DESC', $nid);
+ // The ORDER BY clause ensures that manually added links are given
+ // preference.
+ $result = db_query('SELECT link, type FROM {relatedlinks} WHERE nid = %d ' .
+ 'ORDER BY TYPE DESC', $nid);
}
else {
- $result = db_query('SELECT link FROM {relatedlinks} WHERE nid = %d AND type = %d ORDER BY TYPE DESC', $nid, $type);
+ $result = db_query('SELECT link FROM {relatedlinks} ' .
+ 'WHERE nid = %d AND type = %d ORDER BY TYPE DESC',
+ $nid, $type);
}
+ // Fetch the data into the an array.
$links = array();
-
+ $link_number = 0;
while ($link = db_fetch_array($result)) {
- $links[] = filter_xss($link['link'], array('a'));
+ if (!isset($type)) {
+ // We need to get the link type information as well.
+ $links[$link_number]['link'] = filter_xss($link['link'], array('a'));
+ $links[$link_number]['type'] = $link['type'];
+ }
+ else {
+ $links[$link_number] = filter_xss($link['link'], array('a'));
+ }
+ $link_number++;
}
+ // Return it.
return $links;
}
@@ -281,17 +393,30 @@
* Retrieve related taxonomy terms.
*/
function _relatedlinks_get_terms($tids, $nid) {
- // The following query is likely to prove expensive when the numbers involved are large.
- // pgSQL compliant?
- $result = module_invoke('taxonomy', 'select_nodes', $tids, 'or', 0, FALSE, 'RAND()');
+ $links = array();
- $links = array();
- while ($node = db_fetch_array($result)) {
- // Exclude the current nid.
- if ($node['nid'] != $nid) {
- $links[] = l($node['title'], 'node/'. $node['nid']);
+ // Only get the terms if this link type is enabled.
+ if (in_array('taxonomy',
+ variable_get('relatedlinks_types', array('parsed')))) {
+
+ // The following query is likely to prove expensive when the numbers
+ // involved are large.
+ // pgSQL compliant?
+ $result = module_invoke('taxonomy', 'select_nodes', $tids, 'or', 0,
+ FALSE, 'RAND()');
+
+ // Fetch the data into an array.
+ $link_number = 0;
+ while ($node = db_fetch_array($result)) {
+ // Exclude the current nid.
+ if ($node['nid'] != $nid) {
+ $links[$link_number]['link'] = l($node['title'], 'node/'. $node['nid']);
+ $links[$link_number]['type'] = RELATEDLINKS_TAXONOMY;
+ }
+ $link_number++;
}
}
+ // Return it.
return $links;
}