You are here

recommender_example.module in Recommender API 7.6

File

recommender_example/recommender_example.module
View source
<?php

/**
 * Implements hook_menu().
 */
function recommender_example_menu() {
  $items = array();
  $items[RECOMMENDER_ADMIN_PATH . '/recommender_example'] = array(
    'type' => MENU_LOCAL_TASK,
    'title' => 'Recommender Example',
    'description' => 'The admin interface to interact with Recommender Example.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'recommender_example_admin_form',
    ),
    'access arguments' => array(
      'administer recommender',
    ),
  );
  return $items;
}
function recommender_example_admin_form($form, &$form_state) {
  $form['info'] = array(
    '#markup' => '<p>' . t('This module is an example about using Recommender API. Data is from !link. Please refer to the README file for more details.', array(
      '!link' => l('Resnick et al (1994)', 'http://ccs.mit.edu/papers/CCSWP165.html'),
    )) . '</p>',
  );

  // handle preference.
  if (db_query("SELECT COUNT(*) FROM {recommender_example_preference}")
    ->fetchField() > 0) {
    $rows = db_query("SELECT uid, eid, score FROM {recommender_example_preference}")
      ->fetchAll(PDO::FETCH_NUM);
    foreach ($rows as &$row) {
      $user = user_load($row[0]);
      $row[0] = l($user->name, 'user/' . $user->uid);
      $node = node_load($row[1]);
      $row[1] = l($node->title, 'node/' . $node->nid);
    }
    $form['preference_data'] = array(
      '#markup' => theme('table', array(
        'header' => array(
          'User',
          'Node',
          'Score',
        ),
        'rows' => $rows,
        'caption' => t('Ratings data'),
      )),
    );
  }
  else {
    $form['preference_data'] = array(
      '#markup' => '<p>' . t('Please load example data by clicking the "Load Example Data" button below. Make sure you have at least 4 users and 6 nodes before loading example data, or generate users and nodes first by using the devel_generate.module.') . '</p>',
    );
  }
  if (db_query("SELECT COUNT(*) FROM {recommender_example_prediction_user}")
    ->fetchField() > 0) {
    $rows = db_query("SELECT uid1, uid2, score FROM {recommender_example_user_similarity}")
      ->fetchAll(PDO::FETCH_NUM);
    foreach ($rows as &$row) {
      $user1 = user_load($row[0]);
      $row[0] = l($user1->name, 'user/' . $user1->uid);
      $user2 = user_load($row[1]);
      $row[1] = l($user2->name, 'user/' . $user2->uid);
    }
    $form['similarity_data'] = array(
      '#markup' => theme('table', array(
        'header' => array(
          'User 1',
          'User 2',
          'Score',
        ),
        'rows' => $rows,
        'caption' => t('User-User similarity data'),
      )),
    );
    $rows = db_query("SELECT uid, eid, score FROM {recommender_example_prediction_user}")
      ->fetchAll(PDO::FETCH_NUM);
    foreach ($rows as &$row) {
      $user = user_load($row[0]);
      $row[0] = l($user->name, 'user/' . $user->uid);
      $node = node_load($row[1]);
      $row[1] = l($node->title, 'node/' . $node->nid);
    }
    $form['prediction_data'] = array(
      '#markup' => theme('table', array(
        'header' => array(
          'User',
          'Node',
          'Score',
        ),
        'rows' => $rows,
        'caption' => t('Prediction data'),
      )),
    );
    $form['views_message'] = array(
      '#markup' => '<p>' . t('Recommendations data are computed. Please enable !link to display recommendations on user pages and node pages.', array(
        '!link' => l(t('the default Recommender Example views'), 'admin/structure/views'),
      )) . '</p>',
    );
  }
  else {
    $form['prediction_data'] = array(
      '#markup' => '<p>' . t('Recommendations are not generated yet. After example data are loaded, please go to !add and submit a command to run Item-Item algorithm. Then click the "Run Recommender" button below to computing recommendations. You might also use Drush or the Java program to run recommender. See README for more details.', array(
        '!add' => l(t('Command'), COMPUTING_MODULE_ADMIN_PATH . '/list'),
      )) . '</p>',
    );
  }
  $form['actions'] = array(
    '#type' => 'actions',
    'load' => array(
      '#type' => 'submit',
      '#name' => 'load',
      '#value' => t('Load Example Data'),
    ),
  );
  return $form;
}
function recommender_example_admin_form_submit($form, &$form_state) {

  //dpm(func_get_args());
  if ($form_state['triggering_element']['#name'] == 'load') {
    _recommender_example_load_data();
  }
}
function _recommender_example_load_data() {
  $uid_list = db_query_range("SELECT uid FROM {users} WHERE status = 1", 0, 4)
    ->fetchCol();
  $nid_list = db_query_range("SELECT nid FROM {node} WHERE status = 1", 0, 6)
    ->fetchCol();
  if (count($uid_list) != 4 || count($nid_list) != 6) {
    drupal_set_message(t('You have %num_user (need at least 4) and !num_node (need at least 6). Please create the missing users and nodes before loading example data.', array(
      '%num_user' => format_plural(count($uid_list), '1 user', '@count users'),
      '!num_node' => format_plural(count($nid_list), '1 node', '@count nodes'),
    )), 'error');
    return;
  }

  // truncate table first
  db_query("DELETE FROM {recommender_example_preference}");

  // load toy data from GroupLens paper
  // Ken: 1, Lee: 2, Meg: 3, Nan: 4; Items 1~6.
  // Expected correlation between Ken(1) and Lee(2) is -0.8, between Ken(1) and Meg(3) is 1, between Ken(1) and Nan(4) is 0.
  // Expected prediction for Ken on Item6 is: 4.56, for Nan(4) on item6 is: 3.75 (my calculation is 3.85)
  $values = array(
    array(
      1,
      1,
      1,
    ),
    array(
      1,
      2,
      5,
    ),
    array(
      1,
      4,
      2,
    ),
    array(
      1,
      5,
      4,
    ),
    array(
      2,
      1,
      4,
    ),
    array(
      2,
      2,
      2,
    ),
    array(
      2,
      4,
      5,
    ),
    array(
      2,
      5,
      1,
    ),
    array(
      2,
      6,
      2,
    ),
    array(
      3,
      1,
      2,
    ),
    array(
      3,
      2,
      4,
    ),
    array(
      3,
      3,
      3,
    ),
    array(
      3,
      6,
      5,
    ),
    array(
      4,
      1,
      2,
    ),
    array(
      4,
      2,
      4,
    ),
    array(
      4,
      4,
      5,
    ),
    array(
      4,
      5,
      1,
    ),
  );
  $timestamp = time();
  $insert = db_insert('recommender_example_preference')
    ->fields(array(
    'uid',
    'eid',
    'score',
    'updated',
  ));
  foreach ($values as $row) {
    $insert
      ->values(array(
      'uid' => $uid_list[$row[0] - 1],
      'eid' => $nid_list[$row[1] - 1],
      'score' => $row[2],
      'updated' => $timestamp,
    ));
  }
  $insert
    ->execute();
}

/**
 * Implements hook_recommender_data().
 * See details about hook_recommender_data() in README.
 */
function recommender_example_recommender_data() {
  return array(
    'recommender_example_user_based' => array(
      'title' => t('Recommender Example (User Based)'),
      'description' => t('An example to show how to use Recommender API with GroupLens toy data. Algorithm is user-user collaborative filtering.'),
      'algorithm' => 'user2user',
      'data structure' => array(
        'preference' => array(
          'type' => 'table',
          'name' => 'recommender_example_preference',
        ),
        'user similarity' => array(
          'type' => 'table',
          'name' => 'recommender_example_user_similarity',
        ),
        'prediction' => array(
          'type' => 'table',
          'name' => 'recommender_example_prediction_user',
        ),
        'item entity type' => 'node',
        // this is the entity type for "items".
        'user entity type' => 'user',
      ),
      'options' => array(),
      'form elements callback' => 'recommender_example_form_elements',
    ),
    'recommender_example_item_based' => array(
      'title' => t('Recommender Example (Item Based)'),
      'description' => t('An example to show how to use Recommender API with GroupLens toy data. Algorithm is item-item collaborative filtering.'),
      'algorithm' => 'item2item',
      'data structure' => array(
        'preference' => array(
          'type' => 'table',
          'name' => 'recommender_example_preference',
        ),
        'item similarity' => array(
          'type' => 'table',
          'name' => 'recommender_example_item_similarity',
        ),
        'prediction' => array(
          'type' => 'table',
          'name' => 'recommender_example_prediction_item',
        ),
        'item entity type' => 'node',
      ),
      'options' => array(),
      'form elements callback' => 'recommender_example_form_elements',
    ),
  );
}
function recommender_example_form_elements() {
  return array(
    'message' => array(
      '#markup' => 'No extra settings.',
    ),
  );
}

/**
 * Implements hook_views_api().
 */
function recommender_example_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'recommender_example'),
  );
}