/[drupal]/contributions/modules/cre/recommendation_modules/node_recommendation.module
ViewVC logotype

Diff of /contributions/modules/cre/recommendation_modules/node_recommendation.module

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

revision 1.1.4.9, Thu Aug 30 04:19:52 2007 UTC revision 1.1.4.10, Mon Nov 3 13:17:49 2008 UTC
# Line 1  Line 1 
1  <?php  <?php
2  // $Id: node_recommendation.module,v 1.1.4.8 2007/07/23 14:11:41 hickory Exp $  // $Id: $
3    
4    
5    /**
6     * Implementation of hook_init
7     */
8    function node_recommendation_init() {
9      // ensure we are not serving a cached page
10      if (function_exists('drupal_set_content')) {
11        // we don't do this in hook_menu to ensure the files are already included when
12        // views_menu is executed
13        if (module_exists('views')) {
14          include_once('./'. drupal_get_path('module', 'node_recommendation') .'/node_recommendation_views.inc');
15        }
16      }
17    }
18    
19  /*  /*
20  * hook_help  * hook_help
# Line 14  function node_recommendation_help($secti Line 29  function node_recommendation_help($secti
29  }  }
30    
31  /**  /**
32  * hook_perm().   * hook_cron
33  */   * update the node_recommendations table
34  function node_recommendation_perm() {   */
35    return array('access recommendations');  function node_recommendation_cron() {
36      // big query  to calc recommendations for all users
37      // get the user limit
38      $limit = 25;
39      $query_type = variable_get('cre_query_type', 'accurate');
40    
41      // set a variable to use to make sure we don't time out
42      variable_set('node_recommendation_calc', time());
43    
44      // register a function to check that variable
45      register_shutdown_function('node_recommendation_shutdown');
46    
47      $tag = variable_get('node_recommendation_tag', 'vote');
48    
49      // grab the most recently voted users
50      $users = db_query_range("SELECT DISTINCT(uid) FROM {votingapi_vote} WHERE uid <> 0 ORDER BY timestamp DESC", 0, $limit);
51      while ($account = db_fetch_object($users)) {
52        if ($query_type == 'points') {
53          $field = 'ABS(node_similarity.sum/node_similarity.count)';
54          $voting_style   = 'points';
55          $sql = "SELECT n.nid, $field as score FROM {cre_similarity_matrix} node_similarity JOIN {node} n ON n.nid = content_id1 JOIN {votingapi_vote} r ON r.content_id = node_similarity.content_id2 WHERE content_type1 = 'node' AND content_type2 = 'node' AND r.tag = '$tag' AND r.value_type = '$voting_style' AND r.uid = $account->uid";
56        }
57        else {
58          $voting_style = 'percent';
59          if ($query_type == 'accurate') {
60            $field = "SUM(node_similarity.sum + node_similarity.count * r.value) / SUM(node_similarity.count)";
61            $sql = "SELECT n.nid, $field as score FROM {cre_similarity_matrix} node_similarity JOIN {node} n ON n.nid = content_id1 JOIN {votingapi_vote} r ON r.content_id = node_similarity.content_id2 WHERE r.content_type = 'node' AND r.tag = '$tag' AND r.uid = $account->uid AND r.value_type = '$voting_style'";
62          }
63          else {
64            $average = db_result(db_query("SELECT sum/count from {cre_average_vote} WHERE uid = %d", $account->uid));
65            $field = sprintf("SUM(node_similarity.sum + node_similarity.count) / SUM(node_similarity.count) + %d", $average);
66            $sql = "SELECT n.nid, $field as score FROM {cre_similarity_matrix} node_similarity JOIN {node} n ON n.nid = content_id1";
67          }
68        }
69        $sql .= " AND n.nid NOT IN (SELECT content_id FROM {votingapi_vote} WHERE uid = $account->uid AND content_type ='node') GROUP BY n.nid";
70        $recommendations = db_query($sql);
71        while($record = db_fetch_object($recommendations)) {
72    
73          // we update because that will be the most frequent db change
74          db_query("UPDATE {node_recommendations} SET score = %f WHERE nid = %d AND uid = %d", $record->score, $record->nid, $account->uid);
75          if (!db_affected_rows()) {
76            // if we didn't update anything we have a new record
77            db_query("INSERT INTO {node_recommendations} VALUES (%d, %d, %f)", $record->nid, $account->uid, $record->score);
78          }
79        }
80      }
81    
82      variable_del('node_recommendation_calc');
83    
84    }
85    
86    function node_recommendation_shutdown() {
87      if (variable_get('node_recommendation_calc', FALSE)) {
88        watchdog('node_recommendation', t('Calculation timed out'), WATCHDOG_ERROR);
89        variable_del('node_recommendation_calc');
90      }
91  }  }
92    
93  /**  /**
# Line 28  function node_recommendation_menu($may_c Line 98  function node_recommendation_menu($may_c
98    
99    if ($may_cache) {    if ($may_cache) {
100      $items[] = array(      $items[] = array(
       'path' => 'recommendations',  
       'title' => t('Your recommendations'),  
       'callback' => 'node_recommendation_recommendations_page',  
       'access' => user_access('access recommendations'),  
       'type' => MENU_SUGGESTED_ITEM  
       );  
   
     $items[] = array(  
101        'path' => 'admin/settings/cre/node',        'path' => 'admin/settings/cre/node',
102        'title' => t('Node recommendation'),        'title' => t('Node recommendation'),
103        'description' => t('Administer node recommendation settings.'),        'description' => t('Administer node recommendation settings.'),
# Line 56  function node_recommendation_menu($may_c Line 118  function node_recommendation_menu($may_c
118  * structured array that represents the setting form  * structured array that represents the setting form
119  */  */
120  function node_recommendation_settings() {  function node_recommendation_settings() {
   $form['node_recommendation_page_n'] = array(  
     '#type' => 'textfield',  
     '#title' => t('Number of items to display'),  
     '#description' => t('The maximum number of items to display on a node recommendation page.'),  
     '#size' => 3,  
     '#default_value' => variable_get('node_recommendation_page_n', 20),  
     );  
   
   foreach (node_get_types() as $type) {  
     $form['node_recommendation_days_' . $type->type] = array(  
       '#type' => 'textfield',  
       '#title' => t('Maximum age (in days) of any recommended %type node', array('%type' => $type->name)),  
       '#description' => t('Only nodes newer than this will be recommended; leave blank to recommend nodes of any age.'),  
       '#size' => 3,  
       '#default_value' => variable_get('node_recommendation_days_' . $type->type, NULL),  
       );  
   }  
   
121    $tags = _node_recommendation_get_tags();    $tags = _node_recommendation_get_tags();
122    if (!empty($tags)) {    if (!empty($tags)) {
123      $form['node_recommendation_tag'] = array(      $form['node_recommendation_tag'] = array(
# Line 83  function node_recommendation_settings() Line 127  function node_recommendation_settings()
127        '#options' => $tags        '#options' => $tags
128        );        );
129    }    }
   
   $options = array('1' => t('All types'));  
   foreach (node_get_types() as $type) {  
     $options[$type->type] = $type->name;  
   }  
   
   $form['node_recommendation_global_type'] = array(  
     '#type' => 'select',  
     '#title' => t('Type of node to recommend'),  
     '#default_value' => variable_get('node_recommendation_global_type', '1'),  
     '#description' => t('Limit all recommendations to nodes of a particular type?'),  
     '#options' => $options  
     );  
   
130    return system_settings_form($form);    return system_settings_form($form);
131  }  }
132    
# Line 111  function node_recommendation_nodeapi(&$n Line 141  function node_recommendation_nodeapi(&$n
141  }  }
142    
143  /*  /*
 * hook_block()  
 */  
 function node_recommendation_block($op = 'list', $delta = 0, $edit = array()) {  
   global $user;  
   
   // The $op parameter determines what piece of information is being requested.  
   switch ($op) {  
     case 'list':  
     return array(  
       '0' => array('info' => t('CRE: Recommended nodes (all types)')),  
       '1' => array('info' => t('CRE: Similarly rated nodes')),  
       '2' => array('info' => t('CRE: Recommended nodes (' . variable_get('node_recommendation_type_type_2', 1) . ')')),  
       '3' => array('info' => t('CRE: Recommended nodes (' . variable_get('node_recommendation_type_type_3', 2) . ')')),  
       '4' => array('info' => t('CRE: Recommended nodes (' . variable_get('node_recommendation_type_type_4', 3) . ')')),  
       );  
     break;  
   
     case 'configure':  
     $form = array();  
     switch ($delta){  
   
       // Personalised recommendations.  
       case 0:  
       $form['node_recommendation_n'] = array(  
         '#type' => 'textfield',  
         '#title' => t('Maximum number of nodes to recommend'),  
         '#size' => 2,  
         '#description' => t('The maximum number of nodes shown in the "Recommended nodes" block'),  
         '#default_value' => variable_get('node_recommendation_n_value', 2)  
         );  
       break;  
   
       // General similar block.  
       case 1:  
       $form['node_recommendation_n'] = array(  
         '#type' => 'textfield',  
         '#title' => t('Maximum number of nodes to recommend'),  
         '#size' => 2,  
         '#description' => t('The maximum number of nodes shown in the "Similarly rated nodes" block'),  
         '#default_value' => variable_get('node_recommendation_similar_n_value', 4),  
         );  
       break;  
   
       // Recommendations of a certain type.  
       case 2:  
       case 3:  
       case 4:  
       $options = array();  
       foreach (node_get_types() as $type) {  
         $options[$type->type] = $type->name;  
       }  
   
       $form['node_recommendation_type'] = array(  
         '#type' => 'select',  
         '#title' => t('Type of node to recommend'),  
         '#default_value' => variable_get('node_recommendation_type_type_' . $delta, 'story'),  
         '#options' => $options  
         );  
   
       $form['node_recommendation_n'] = array(  
         '#type' => 'textfield',  
         '#title' => t('Maximum number of nodes to recommend'),  
         '#size' => 2,  
         '#description' => t('The maximum number of nodes shown in the "Recommended nodes of a particular type" block'),  
         '#default_value' => variable_get('node_recommendation_type_n_value_' . $delta, 5),  
         );  
       break;  
   
     }  
     return $form;  
   
     case 'save':  
     switch ($delta){  
       case 0:  
       variable_set('node_recommendation_n_value', $edit['node_recommendation_n']);  
       break;  
   
       case 1:  
       variable_set('node_recommendation_similar_n_value', $edit['node_recommendation_n']);  
       break;  
   
       case 2:  
       case 3:  
       case 4:  
       variable_set('node_recommendation_type_type_' . $delta, $edit['node_recommendation_type']);  
       variable_set('node_recommendation_type_n_value_' . $delta, $edit['node_recommendation_n']);  
       break;  
     }  
     return;  
   
     case 'view':  
     default:  
     switch ($delta) {  
   
       // Personalised recommendations.  
       case 0:  
       return array(  
         'subject' => l(t('Recommended'), variable_get('node_recommendation_path_to_page', 'recommendations')),  
         'content' => theme('cre_title_list', node_recommendation_get_top_n($user->uid, variable_get('node_recommendation_n_value', 5))),  
         );  
       break;  
   
       // General similar block.  
       case 1:  
       if (arg(0) == 'node') {  
         return array(  
           'subject' => t('Those that like this also like'),  
           'content' => theme('cre_title_list', node_recommendation_get_similar(variable_get('node_recommendation_similar_n_value', 5))),  
           );  
       }  
       break;  
   
       // Recommendations of a certain type.  
       case 2:  
       case 3:  
       case 4:  
       $type = variable_get('node_recommendation_type_type_' . $delta, 'story');  
       return array(  
         'subject' => l(t('Recommended'), variable_get('node_recommendation_path_to_page', 'recommendations') . "/$type"),  
         'content' => theme('cre_title_list', node_recommendation_get_top_n($user->uid, variable_get('node_recommendation_type_n_value_' . $delta, 5), $type)),  
         );  
       break;  
     }  
   }  
 }  
   
 /*  
 * Returns the top n nodes of a particular type  
 *  
 * @param $uid  
 * uid for the personalized recommendations  
 *  
 * @param $n  
 * specifies the number of recommendations to return  
 */  
   
 function node_recommendation_get_top_n($uid, $n, $type = 'node') {  
   return cre_top($uid, 'node_recommendation_cre_query', $n, 'node', variable_get('node_recommendation_tag', 'vote'), 'node', array($type));  
 }  
   
 /*  
 * Returns nodes that were rated similarly to the currently viewed node  
 *  
 * @param $n  
 * Specifies the number of recommendations to return  
 */  
 function node_recommendation_get_similar($n) {  
   $nid = arg(1);  
   if (is_numeric($nid)){  
     return cre_similar($n, $nid, 'node', variable_get('node_recommendation_tag', 'vote'));  
   }  
 }  
   
 /**  
 * Callback to display a page of recommended items  
 */  
 function node_recommendation_recommendations_page($type = 'node', $uid = NULL) {  
   if (!is_numeric($uid)){  
     global $user;  
     $uid = $user->uid;  
   }  
   
   $n = variable_get('node_recommendation_page_n', 20);  
   
   $recommendations = $uid ? cre_top($uid, 'node_recommendation_cre_query', $n, 'node', variable_get('node_recommendation_tag', 'vote'), 'node', array($type)) : _node_recommendation_get_top_rated_nodes($n); // return recommendations for logged-in users, top-rated nodes otherwise.  
   
   if($uid != 0 ) {  
     $recommendations = cre_top($uid, 'node_recommendation_cre_query', $n, 'node', variable_get('node_recommendation_tag', 'vote'), 'node', array($type));  
     if($recommendations == NULL) {  
       // user doesn't have any recommendations therefore! return top nodes  
       $recommendations = _node_recommendation_get_top_rated_nodes($n);  
     }  
   }  
   else { // anon user therefore just get the top rated nodes  
     $recommendations = _node_recommendation_get_top_rated_nodes($n);  
   }  
   $content = array();  
   foreach ($recommendations as $node) {  
     $content[] = theme('cre_node_view', $node->content_id);  
   }  
   return implode("\n", $content);  
 }  
   
 /*  
 * gets the highest rated items  
 */  
 function _node_recommendation_get_top_rated_nodes($n) {  
   $result = db_query("SELECT c.content_id as content_id, c.value as avg_vote, n.title  
     FROM {votingapi_cache} c, {node} n  
     WHERE c.content_id = n.nid AND c.function = 'average' AND c.tag = '%s' AND c.content_type = 'node'  
     ORDER BY avg_vote DESC LIMIT %d",  
     variable_get('node_recommendation_tag', 'vote'), $n);  
   $voting_results = array();  
   while ($tmp = db_fetch_object($result)) {  
     $voting_results[] = $tmp;  
   }  
   return $voting_results;  
 }  
   
 function node_recommendation_cre_query(&$query, $uid, $args) {  
   $query->add_table('{node} n');  
   $query->add_column('n.title');  
   $query->add_column('n.type');  
   $query->add_where('n.nid = d.content_id1');  
   //$query->add_where('n.uid <> %d', $uid);  
   $query->add_where("r.tag = '%s'", variable_get(node_recommendation_tag, 'vote'));  
   
   if ($type = $args[0]){  
     $query->add_where("n.type = '%s'", $type);  
   }  
   else {  
     $global_type = variable_get('node_recommendation_global_type', '1');  
     if ($global_type != '1'){  
       $query->add_where("n.type = '%s'", $global_type);  
     }  
   }  
   
   if ($numdays = variable_get('node_recommendation_days_' . $type, FALSE)) {  
     $query->add_where('n.created >= %d', time() - (60 * 60 * 24 * $numdays));  
   }  
 }  
   
 /*  
144  * private function to return all voting tags present in the system  * private function to return all voting tags present in the system
145  */  */
146  function _node_recommendation_get_tags() {  function _node_recommendation_get_tags() {

Legend:
Removed from v.1.1.4.9  
changed lines
  Added in v.1.1.4.10

  ViewVC Help
Powered by ViewVC 1.1.2