Ну что же, для того, что бы повторить функционал стандартного трэкера, добавим закладку «Сообщения с моим участием» для зарегистрированных пользователей.
Ну а что бы было совсем интересно (не повторять же код модуля tracker), добавим еще закладочку с материалами, опубликованными текущим пользователем, и закладочки с разбивкой по типам материалов (выбрать тип материалов можно будет на странице настройки модуля)
Шаг номер 8:
Первое, что надо сделать, это модифицировать код функции cctracker_menu, что бы определить закладки на странице вывода.
// $Id$
/**
* File: cctracker.module
* Enables extending tracking.
*/
/**
* Implementation of hook_menu().
*/
function cctracker_menu() {
$items['admin/settings/cctracker'] = array(
'title' => 'Cctracker',
'page callback' => 'drupal_get_form',
'page arguments' => array('cctracker_settings'),
'access arguments' => array('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
'file' => 'cctracker.admin.inc',
);
$items[$base_page] = array(
'title' => 'Recent posts',
'page callback' => 'cctracker_track',
'page arguments' => array(NULL, 'all'),
'access arguments' => array('access content'),
'file' => 'cctracker.page.inc',
);
$items[$base_page . '/all'] = array(
'title' => 'All recent posts',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[$base_page . '/my-recent-posts/%user_uid_optional'] = array(
'title' => 'My recent posts',
'page arguments' => array(2, 'my-recent-posts'),
'access callback' => '_cctracker_myrecent_access',
'access arguments' => array(2),
'type' => MENU_LOCAL_TASK,
);
$items[$base_page . '/my-posts/%user_uid_optional'] = array(
'title' => 'My posts',
'page arguments' => array(2, 'my-posts'),
'access callback' => '_cctracker_myrecent_access',
'access arguments' => array(2),
'type' => MENU_LOCAL_TASK,
);
$tab_types = variable_get('cctracker_tab_types', array());
foreach ($tab_types as $key => $value) {
if ($value) {
$items[$base_page . '/' . $key] = array(
'title' => check_plain(node_get_types('name', $value)),
'page arguments' => array(1, 'tab-types'),
'access arguments' => array('access content'),
'type' => MENU_LOCAL_TASK,
);
}
}
return $items;
}
function _cctracker_myrecent_access($account) {
// This path is only allowed for authenticated users looking at their own posts.
return $account->uid && ($GLOBALS['user']->uid == $account->uid) && user_access('access content');
}
/**
* Implementation of hook_theme().
*/
function cctracker_theme() {
return array(
// определяем файл шаблона для вывода трэкера
'cctracker_page_wrapper' => array(
'template' => 'cctracker-page-wrapper',
'arguments' => array('tracker' => NULL, 'pager' => NULL),
),
// определяем функцию темизации для рендеринга трэкера
'cctracker_page' => array(
'arguments' => array('tracker' => array(), 'tp' => NULL),
'file' => 'cctracker.page.inc',
),
);
}
Шаг номер 9:
Дальше, немного изменим страницу настройки, добавим группу чекбоксов с типами материалов, закладки по которым добавим в вывод трэкера.
Изменяем файл cctracker.admin.inc
// $Id$
/**
* @file
*/
function cctracker_settings() {
$form['cctracker'] = array(
'#type' => 'fieldset',
'#title' => t('Cctracker settings'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['cctracker']['cctracker_node_per_page'] = array(
'#type' => 'select',
'#title' => t('Node per page'),
'#options' => drupal_map_assoc(array(5, 10, 15, 20, 25, 30, 50, 100, 150, 200, 300)),
'#default_value' => variable_get('cctracker_node_per_page', 50),
'#description' => t('Number of nodes to show per page.'),
);
$form['cctracker']['cctracker_node_types'] = array(
'#type' => 'checkboxes',
'#title' => t('Allowed content types'),
'#options' => node_get_types('names'),
'#default_value' => variable_get('cctracker_node_types', array()),
'#description' => t('Select node types for see in tracker.'),
);
$form['cctracker']['cctracker_tab_types'] = array(
'#type' => 'checkboxes',
'#title' => t('Allowed tab page of content types'),
'#options' => node_get_types('names'),
'#default_value' => variable_get('cctracker_tab_types', array()),
'#description' => t('Select node types for see in tab page tracker.'),
);
$form['#submit'][] = 'cctracker_settings_submit';
return system_settings_form($form);
}
function cctracker_settings_submit($form, &$form_state) {
if (!form_get_errors()) {
cache_clear_all();
menu_rebuild();
}
}
Шаг номер 10:
Что бы не засорять код функции cctracker_page - код построения запроса, я вынес в отдельную вспомогательную функцию _cctracker_get_query.
// $Id$
/**
* File: cctracker.page.inc
*/
function cctracker_page($account = NULL, $tp = 'all') {
$cnt = variable_get('cctracker_node_per_page', 50);
$output = '';
$tracker = array();
$result = _cctracker_get_query($arg, $tp);
while ($items = db_fetch_object($result)) {
$tracker[$items->nid] = $items;
}
// здесь мы уже получили массив для с данными для текущей страниц
// в переменную $outtracker помещаем отренедеренный контент нашего трэкера
// за выврод трэкера отвечает функция темизации theme_cctracker_page
// ранее зарегистрированная в файле cctracker.module
if (count($tracker)) {
$outtracker = theme('cctracker_page',$tracker,$tp);
}
// в переменную $pager мы помещаем отрендеренный пейджинг
$pager = theme('pager', NULL, $cnt, 0);
// теперь обе эти переменные передаем в файл шаблона
$output .= theme('cctracker_page_wrapper',$outtracker,$pager);
return $output;
}
function _cctracker_get_query($arg, $tp){
$cnt = variable_get('cctracker_node_per_page', 50);
$types = variable_get('cctracker_node_types', array());
$placeholder = db_placeholders($types, 'varchar');
switch ($tp) {
// Все материалы определенные для показа
case 'all':
// запишем запрос в строку $sql в формате heredoc (что бы он был более читемым)
// в принципе данный запрос, возвращает все нужне нам данные
$sql = <<<EOT
SELECT DISTINCT(n.nid) AS nid, n.title, n.type, n.changed, n.uid, n.created, u.name,
GREATEST(n.changed, l.last_comment_timestamp) AS last_update,
l.comment_count,nc.totalcount, nc.daycount,nc.timestamp AS lastread FROM {node} n
INNER JOIN {node_comment_statistics} l ON n.nid = l.nid AND n.status=1 AND n.type IN ($placeholder)
LEFT JOIN {comments} c ON n.nid = c.nid
LEFT JOIN {users} u ON u.uid=n.uid
LEFT JOIN {node_counter} nc ON nc.nid = n.nid
ORDER BY last_update DESC
EOT;
$sql = db_rewrite_sql($sql);
// этот запрос даст нам общее количество материалов в трэкере
$sql_cnt = 'SELECT COUNT(n.nid) FROM {node} n WHERE n.status=1 AND n.type IN (' . $placeholder. ')';
$sql_cnt = db_rewrite_sql($sql_cnt);
$result = pager_query($sql, $cnt, 0, $sql_cnt, $types);
break;
// Материалы с опубликованные текущим пользователем
case 'my-posts':
$sql = <<<EOT
SELECT DISTINCT(n.nid) AS nid, n.title, n.type, n.changed, n.uid, n.created, u.name,
GREATEST(n.changed, l.last_comment_timestamp) AS last_update,
l.comment_count,nc.totalcount, nc.daycount,nc.timestamp AS lastread FROM {node} n
INNER JOIN {node_comment_statistics} l ON n.nid = l.nid AND n.status=1 AND n.type IN ($placeholder) AND n.uid =%d
LEFT JOIN {comments} c ON n.nid = c.nid
LEFT JOIN {users} u ON u.uid=n.uid
LEFT JOIN {node_counter} nc ON nc.nid = n.nid
ORDER BY last_update DESC
EOT;
$sql = db_rewrite_sql($sql);
$sql_cnt = 'SELECT COUNT(n.nid) FROM {node} n WHERE n.status=1 AND n.type IN (' . $placeholder. ') AND n.uid = %d';
$sql_cnt = db_rewrite_sql($sql_cnt);
$types[] = $arg;
$result = pager_query($sql, $cnt, 0, $sql_cnt, $types);
break;
// Материалы с участием текущего пользователя
case 'my-recent-posts':
$sql = <<<EOT
SELECT DISTINCT(n.nid) AS nid, n.title, n.type, n.changed, n.uid, n.created, u.name,
GREATEST(n.changed, l.last_comment_timestamp) AS last_update,
l.comment_count,nc.totalcount, nc.daycount,nc.timestamp AS lastread FROM {node} n
INNER JOIN {node_comment_statistics} l ON n.nid = l.nid AND n.status=1 AND n.type IN ($placeholder)
LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = %d OR c.status IS NULL)
LEFT JOIN {users} u ON u.uid=n.uid
LEFT JOIN {node_counter} nc ON nc.nid = n.nid
WHERE (n.uid = %d OR c.uid=%d)
ORDER BY last_update DESC
EOT;
$sql = db_rewrite_sql($sql);
$sql_cnt = <<<EOT
SELECT COUNT(DISTINCT(n.nid)) FROM {node} n
INNER JOIN {node_comment_statistics} l ON n.nid = l.nid AND n.status=1 AND n.type IN ($placeholder)
LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = %d OR c.status IS NULL)
WHERE (n.uid = %d OR c.uid=%d)
EOT;
$sql_cnt = db_rewrite_sql($sql_cnt);
$types[] = COMMENT_PUBLISHED;
$types[] = $arg;
$types[] = $arg;
$result = pager_query($sql, $cnt, 0, $sql_cnt, $types);
break;
// Материалы определенного типа
case 'tab-types':
$sql = <<<EOT
SELECT DISTINCT(n.nid) AS nid, n.title, n.type, n.changed, n.uid, n.created, u.name,
GREATEST(n.changed, l.last_comment_timestamp) AS last_update,
l.comment_count,nc.totalcount, nc.daycount,nc.timestamp AS lastread FROM {node} n
INNER JOIN {node_comment_statistics} l ON n.nid = l.nid AND n.status=1 AND n.type = '%s'
LEFT JOIN {comments} c ON n.nid = c.nid
LEFT JOIN {users} u ON u.uid=n.uid
LEFT JOIN {node_counter} nc ON nc.nid = n.nid
ORDER BY last_update DESC
EOT;
$sql = db_rewrite_sql($sql);
$sql_cnt = 'SELECT COUNT(n.nid) FROM {node} n WHERE n.status=1 AND n.type = \'%s\'';
$sql_cnt = db_rewrite_sql($sql_cnt);
$result = pager_query($sql, $cnt, 0, $sql_cnt, $arg);
break;
}
return $result;
}
Ну и в том же файле переделываем функцию темизации
$header = array();
if ($tp != 'tab-types'){
$header[] = t('Type');
}
$header[] = t('Post');
if ($tp != 'my-posts') {
$header[] = t('Author');
}
$header[] = t('Created');
$header[] = t('Replies');
$header[] = t('Last updated');
$rows = array();
foreach($tracker as $key => $value){
$comments = 0;
if ($value->comment_count) {
$comments = $value->comment_count;
if ($new = comment_num_new($value->nid)) {
$comments .= '<br />';
$comments .= l(format_plural($new, '1 new', '@count new'), 'node/'. $value->nid, array('fragment' => 'new'));
}
}
$row = array();
if ($tp != 'tab-types'){
$row[] = array('data' => check_plain(node_get_types('name', $value->type)), 'class' => 'cctracker-type-' . $value->type);
}
$row[] = array('data' => l($value->title,'node/'.$key) .' '. theme('mark', node_mark($value->nid, $value->changed)), 'class' => 'cctracker-title');
if ($tp != 'my-posts') {
$row[] = array('data' => theme('username',$value), 'class' => 'cctracker-user');
}
$row[] = array('data' => format_date($value->created,'small'), 'class' => 'cctracker-date-created');
$row[] = array('data' => $comments, 'class' => 'cctracker-replies');
$row[] = array('data' => t('!time ago', array('!time' => format_interval(time()-$value->last_update))), 'class' => 'cctracker-last-update');
$rows[] = array('data'=>$row, 'id' => 'cctracker-' . $value->nid);
}
$output = theme('table', $header, $rows);
return $output;
}
