View source
<?php
define('CACHE_ON', true);
function cctags_help($path, $arg) {
switch ($path) {
case 'admin/help#cctags':
return t('Provides a tag cloud interface and additional processing capabilities dictionaries.');
}
}
function cctags_init() {
drupal_add_css(drupal_get_path('module', 'cctags') . '/cctags.css');
}
function cctags_theme() {
return array(
'cctags_settings' => array(
'render element' => 'form',
'file' => 'cctags.admin.inc',
),
'cctags_settings_add_item' => array(
'render element' => 'form',
'file' => 'cctags.admin.inc',
),
'cctags_settings_edit_item' => array(
'render element' => 'form',
'file' => 'cctags.admin.inc',
),
'cctags_settings_item' => array(
'render element' => 'form',
'file' => 'cctags.admin.inc',
),
'cctags_more' => array(
'variables' => array(
'cctid' => NULL,
),
),
'cctags_block' => array(
'variables' => array(
'cctid' => NULL,
'amount' => 0,
'extra_class' => '',
'more_link' => TRUE,
),
),
'cctags_level' => array(
'variables' => array(
'terms' => NULL,
'amount' => 0,
'page' => 0,
'mode' => 'mixed',
'vocname' => 0,
'out' => 'block',
),
'file' => 'cctags.page.inc',
),
'cctags_term' => array(
'variables' => array(
'term' => NULL,
'mode' => NULL,
),
'template' => 'cctags-term',
),
'cctags_vocname' => array(
'variables' => array(
'vocname' => NULL,
'vid' => NULL,
'terms' => 0,
'mode' => '',
'is_out' => array(),
),
'template' => 'cctags-vocname',
),
'cctags_page' => array(
'variables' => array(
'cctid' => NULL,
'extra_class' => NULL,
'content' => NULL,
'pager' => NULL,
),
'file' => 'cctags.page.inc',
'template' => 'cctags-page',
),
);
}
function cctags_menu() {
$items = array();
$items['admin/config/content/cctags'] = array(
'title' => 'Cctags',
'description' => 'Configure the Cctags.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'cctags_settings',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer site configuration',
),
'file' => 'cctags.admin.inc',
);
$items['admin/config/content/cctags/list'] = array(
'title' => 'Cctags configuration',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/config/content/cctags/add'] = array(
'title' => 'Add cctags item',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'cctags_settings_add_item',
),
'access arguments' => array(
'administer site configuration',
),
'type' => MENU_LOCAL_ACTION,
'file' => 'cctags.admin.inc',
);
$items['admin/config/content/cctags/%/edit'] = array(
'title' => 'Edit cctags item',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'cctags_settings_edit_item',
4,
),
'access arguments' => array(
'administer site configuration',
),
'type' => MENU_CALLBACK,
'file' => 'cctags.admin.inc',
);
$items['admin/config/content/cctags/%/delete'] = array(
'title' => 'Delete cctags item',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'cctags_settings_delete_item',
4,
),
'access arguments' => array(
'administer site configuration',
),
'type' => MENU_CALLBACK,
'file' => 'cctags.admin.inc',
);
$cctags_items = _cctags_get_settings(NULL);
foreach ($cctags_items as $key => $item) {
if ($item['page']) {
$items[$item['page_path']] = array(
'title' => $item['page_title'] == '<none>' ? $item['name'] : $item['page_title'],
'page callback' => 'cctags_page',
'page arguments' => array(
$item,
),
'access callback' => 'user_access',
'access arguments' => array(
'access content',
),
'file' => 'cctags.page.inc',
);
}
}
return $items;
}
function cctags_taxonomy_term_update($term) {
_cctags_clear_cache('', 'all');
}
function cctags_taxonomy_term_insert($term) {
_cctags_clear_cache('', 'all');
}
function cctags_taxonomy_term_delete($term) {
_cctags_clear_cache('', 'all');
}
function cctags_invoke_cctags_term_count(&$term) {
if (!module_invoke_all('cctags_term_count', $term)) {
$count = _cctgas_node_in_terms($term->tid);
$term->count = $count;
}
}
function cctags_build_level_tags($terms, $steps) {
$tags = array();
$min = 1000000000.0;
$max = -1000000000.0;
foreach ($terms as $key => $term) {
if (is_object($term)) {
$term->weight = log($term->count + 1);
$min = min($min, $term->weight);
$max = max($max, $term->weight);
$tags[$term->vid][$term->tid] = $term;
}
}
$range = max(0.01, $max - $min) * 1.0001;
foreach ($tags as $vid => $terms) {
$vocabulary = taxonomy_vocabulary_load($vid);
$tags[$vid]['vocname'] = check_plain($vocabulary->name);
foreach ($terms as $key => $value) {
$tags[$vid][$key]->level = 1 + floor(($steps - 1) * ($value->weight - $min) / $range);
}
}
return $tags;
}
function cctags_sort_tags($terms, $sort, $mode = 'mixed') {
list($sort, $order) = explode(',', $sort);
$tags = array();
$vocname = array();
$tcount = array();
$tvid = array();
if ($mode == 'mixed') {
foreach ($terms as $vid => $tag) {
if (isset($terms[$vid]['vocname'])) {
$vocname[] = $terms[$vid]['vocname'];
}
$tcount[] = count($tag);
$tvid[] = $vid;
foreach ($tag as $tid => $term) {
if (is_numeric($tid)) {
$tags[$tid] = $term;
}
}
}
$tags = _cctags_sort($tags, $sort, $order);
$terms = array();
foreach ($tags as $t => $tag) {
$terms[0][$tag->tid] = $tag;
}
if (isset($vocname)) {
$terms[0]['vocname'] = $vocname;
}
$terms[0]['terms'] = $tcount;
$terms[0]['vid'] = $tvid;
}
else {
foreach ($terms as $vid => $tags) {
$vocname = $tags['vocname'];
unset($tags['vocname']);
$terms[$vid] = _cctags_sort($tags, $sort, $order);
$terms[$vid]['vocname'] = array(
$vocname,
);
$terms[$vid]['terms'] = array(
count($tags),
);
$terms[$vid]['vid'] = array(
$vid,
);
}
}
return $terms;
}
function _cctags_sort($tags, $sort, $order) {
switch ($sort) {
case 'title':
usort($tags, "_cctags_sort_by_title");
break;
case 'level':
usort($tags, "_cctags_sort_by_level");
break;
case 'random':
shuffle($tags);
break;
}
if ($order == 'desc') {
$tags = array_reverse($tags);
}
return $tags;
}
function _cctags_sort_by_title($a, $b) {
return strnatcasecmp($a->name, $b->name);
}
function _cctags_sort_by_level($a, $b) {
if ($a->weight == $b->weight) {
return strnatcasecmp($a->name, $b->name);
}
return $a->weight > $b->weight;
}
function _cctags_clear_cache($cctid, $mode = 'all') {
if (!$cctid) {
$cctid = '%';
}
if ($mode == 'block' || $mode == 'all') {
$cache_name = 'cctags_cache_block_' . $cctid;
cache_clear_all($cache_name, 'cache', TRUE);
}
if ($mode == 'page' || $mode == 'all') {
$cache_name = 'cctags_cache_page_' . $cctid;
cache_clear_all($cache_name, 'cache', TRUE);
}
}
function cctags_get_level_tags($cctid, $mode = 'page') {
global $language;
$terms = array();
if ($mode == 'page') {
$cache_name = 'cctags_cache_page_' . $cctid . ':' . $language->language;
}
if ($mode == 'block') {
$cache_name = 'cctags_cache_block_' . $cctid . ':' . $language->language;
}
$cache = cache_get($cache_name);
if (isset($cache->data) && CACHE_ON) {
$terms = $cache->data;
}
else {
$items = _cctags_get_settings($cctid);
$item = $items[$cctid];
$tree = array();
if ($item['page'] && $mode == 'page' || $item['block'] && $mode == 'block') {
foreach ($item['item_data']['vocs'] as $key => $value) {
if (is_numeric($key) && $value == 1) {
$tree = taxonomy_get_tree($key, 0, NULL, TRUE);
foreach ($item['item_data']['level'][$key] as $k => $v) {
if ($v == 1) {
foreach ($tree as $t => $vt) {
if ($vt->depth == $k) {
$term = $tree[$t];
cctags_invoke_cctags_term_count($term);
$uri = taxonomy_term_uri($term);
$term->path = $uri['path'];
$term->name = check_plain($term->name);
if ($term->count > 0) {
$terms[] = $term;
}
}
}
}
}
}
}
$terms = cctags_build_level_tags($terms, $item['page_level'] + 1);
if ($mode == 'page') {
$terms = cctags_sort_tags($terms, $item['page_sort'], $item['page_mode']);
}
else {
$terms = cctags_sort_tags($terms, 'level,desc', 'mixed');
$terms = $terms[0];
$settings_data = variable_get('cctags_settings_block', '');
$settings_block = empty($settings_data) ? array() : unserialize($settings_data);
$sort = isset($settings_block[$cctid]['tags_sort']) ? $settings_block[$cctid]['tags_sort'] : 'title,asc';
$level = isset($settings_block[$cctid]['level']) ? $settings_block[$cctid]['level'] : 6;
$level++;
$amount = isset($settings_block[$cctid]['tags']) ? $settings_block[$cctid]['tags'] : 40;
$t = array_chunk($terms, $amount);
$terms = $t[0];
$terms = cctags_build_level_tags($terms, $level);
$terms = cctags_sort_tags($terms, $sort, 'mixed');
$count = 0;
$block_terms = array();
foreach ($terms as $key => $value) {
foreach ($value as $tid => $term) {
if ($amount > 0) {
$block_terms[$cctid][$tid] = $term;
}
$amount--;
$count++;
}
}
$terms['count'] = $count;
}
}
cache_set($cache_name, $terms, 'cache', CACHE_TEMPORARY);
}
return $terms;
}
function _cctags_get_settings($cctid) {
$items = array();
$select = db_select('cctags', 'ct');
$select
->addField('ct', 'cctid');
$select
->addField('ct', 'name');
$select
->addField('ct', 'block');
$select
->addField('ct', 'block_name');
$select
->addField('ct', 'page');
$select
->addField('ct', 'page_title');
$select
->addField('ct', 'page_path');
$select
->addField('ct', 'page_level');
$select
->addField('ct', 'page_amount');
$select
->addField('ct', 'page_sort');
$select
->addField('ct', 'page_mode');
$select
->addField('ct', 'page_vocname');
$select
->addField('ct', 'page_extra_class');
$select
->addField('ct', 'item_data');
if ($cctid) {
$select
->condition('ct.cctid', $cctid);
}
$entries = $select
->execute()
->fetchAll();
foreach ($entries as $cctags) {
$items[$cctags->cctid] = array(
'cctid' => $cctags->cctid,
'name' => $cctags->name,
'block' => $cctags->block,
'block_name' => $cctags->block_name,
'page' => $cctags->page,
'page_title' => $cctags->page_title,
'page_path' => $cctags->page_path,
'page_level' => $cctags->page_level,
'page_amount' => $cctags->page_amount,
'page_sort' => $cctags->page_sort,
'page_mode' => $cctags->page_mode,
'page_vocname' => $cctags->page_vocname,
'page_extra_class' => $cctags->page_extra_class,
'item_data' => unserialize($cctags->item_data),
);
}
return $items;
}
function cctags_block_info() {
$blocks = array();
$items = _cctags_get_settings(NULL);
foreach ($items as $key => $item) {
if ($item['block']) {
$blocks[$key]['info'] = $item['block_name'];
$blocks[$key]['cache'] = DRUPAL_CACHE_GLOBAL;
}
}
return $blocks;
}
function cctags_block_view($delta = '') {
$blocks = array();
if (count($items = _cctags_get_settings($delta))) {
$blocks['subject'] = t('Cloud of tags');
$settings_data = variable_get('cctags_settings_block', '');
$settings_block = empty($settings_data) ? array() : unserialize($settings_data);
$tags_more = $items[$delta]['page'] ? isset($settings_block[$delta]['tags_more']) ? $settings_block[$delta]['tags_more'] : 1 : 0;
$amount = isset($settings_block[$delta]['tags']) ? $settings_block[$delta]['tags'] : 40;
$extra_class = isset($settings_block[$delta]['extra_class']) ? $settings_block[$delta]['extra_class'] : '';
$blocks['content'] = theme('cctags_block', array(
'cctid' => $delta,
'amount' => $amount,
'extra_class' => $extra_class,
'more_link' => $tags_more,
));
}
return $blocks;
}
function cctags_block_configure($delta = '') {
$items = _cctags_get_settings($delta);
$is_more = $items[$delta]['page'];
$settings_data = variable_get('cctags_settings_block', '');
$settings_block = empty($settings_data) ? array() : unserialize($settings_data);
$tags = isset($settings_block[$delta]['tags']) ? $settings_block[$delta]['tags'] : 40;
$tags_more = isset($settings_block[$delta]['tags_more']) ? $settings_block[$delta]['tags_more'] : 1;
$tags_sort = isset($settings_block[$delta]['tags_sort']) ? $settings_block[$delta]['tags_sort'] : 'title,asc';
$level = isset($settings_block[$delta]['level']) ? $settings_block[$delta]['level'] : 6;
$extra_class = isset($settings_block[$delta]['extra_class']) ? $settings_block[$delta]['extra_class'] : '';
$form = array();
$form['level'] = array(
'#type' => 'select',
'#options' => _cctags_get_select_list('level'),
'#title' => t('Number of levels fonts metrics'),
'#default_value' => $level,
'#description' => t('The number of levels between the least popular tags and the most popular ones. Different levels will be assigned a different class to be themed in cctags.css'),
);
$form['tags'] = array(
'#type' => 'select',
'#title' => 'Tags to show',
'#options' => _cctags_get_select_list('numtags'),
'#default_value' => $tags,
'#maxlength' => 3,
'#description' => t('The number of tags to show in this block.'),
);
$op_sort = array(
'level,asc' => t('by level, ascending'),
'level,desc' => t('by level, descending'),
'title,asc' => t('by title, ascending'),
'title,desc' => t('by title, descending'),
'random,none' => t('random'),
);
$form['tags_sort'] = array(
'#type' => 'radios',
'#title' => t('Tags sort order'),
'#options' => $op_sort,
'#default_value' => $tags_sort,
);
$form['extra_class'] = array(
'#type' => 'textfield',
'#title' => t('Block wrapper extra class'),
'#maxlength' => 64,
'#description' => t('Extra class for block wrapper.'),
'#default_value' => $extra_class,
);
$form['tags_more'] = array(
'#type' => 'checkbox',
'#title' => t('Enable more link of end block'),
'#default_value' => $is_more ? $tags_more : false,
);
return $form;
}
function cctags_block_save($delta = '', $edit = array()) {
$settings_data = variable_get('cctags_settings_block', '');
$settings_block = empty($settings_data) ? array() : unserialize($settings_data);
$settings_block[$delta]['tags'] = $edit['tags'];
$settings_block[$delta]['tags_sort'] = $edit['tags_sort'];
$settings_block[$delta]['tags_more'] = $edit['tags_more'];
$settings_block[$delta]['level'] = $edit['level'];
$settings_block[$delta]['extra_class'] = $edit['extra_class'];
variable_set('cctags_settings_block', serialize($settings_block));
}
function _cctags_get_select_list($type) {
$list = array();
switch ($type) {
case 'numtags':
$list = drupal_map_assoc(array(
0,
4,
6,
8,
10,
12,
14,
16,
18,
20,
24,
28,
32,
40,
50,
60,
100,
120,
150,
200,
));
break;
case 'level':
$list = drupal_map_assoc(array(
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
));
break;
case 'amount_tags':
$list = drupal_map_assoc(array(
0,
6,
12,
14,
16,
18,
20,
24,
28,
32,
40,
50,
60,
100,
120,
150,
200,
300,
400,
500,
600,
900,
1400,
));
break;
}
return $list;
}
function theme_cctags_level($variables) {
$terms = $variables['terms'];
$amount = $variables['amount'];
$page = $variables['page'];
$mode = $variables['mode'];
$vocname = $variables['vocname'];
$out = $variables['out'];
$output = '';
$start_term = $amount * $page;
$end_term = $start_term + $amount;
$cur_term = 0;
$is_out = array();
$term_out = '';
$vocname_out = '';
foreach ($terms as $voc => $tags) {
if (is_numeric($voc)) {
$is_out[$voc] = 0;
foreach ($tags as $term) {
if (is_object($term) && $term->tid) {
if ($cur_term >= $start_term && $cur_term < $end_term || $amount == 0) {
$is_out[$voc] = 1;
$term_out .= theme('cctags_term', array(
'term' => $term,
'mode' => $out,
));
}
$cur_term++;
}
}
if ($out == 'page') {
$vn = NULL;
if ($vocname) {
$vn = $terms[$voc]['vocname'];
}
$vocname_out = theme('cctags_vocname', array(
'vocname' => $vn,
'vid' => $terms[$voc]['vid'],
'terms' => $terms[$voc]['terms'],
'mode' => $mode,
'is_out' => $is_out,
));
}
$output .= $vocname_out . $term_out;
$term_out = '';
}
}
return $output;
}
function theme_cctags_more($variables) {
$cctid = $variables['cctid'];
$items = _cctags_get_settings($cctid);
$page_path = $items[$cctid]['page_path'];
return theme('more_link', array(
'class' => 'cctags-more-tags',
'title' => t('more tags'),
'url' => $page_path,
));
}
function template_preprocess_cctags_term(&$variables) {
$term = (object) $variables['term'];
$mode = $variables['mode'];
$t = '';
if (isset($term->count) && $term->count > 0) {
$t = l(check_plain($term->name), $term->path, array(
'attributes' => array(
'class' => array(
'cctags cctags-' . $mode . ' vid-' . $term->vid . ' level-' . $term->level . ' depth-' . $term->depth . ' count-' . $term->count . ' ccfilter tooltip',
),
'title' => $term->description,
'rel' => 'tag',
),
));
}
$variables['term'] = $t;
}
function theme_cctags_block($variables) {
$cctid = $variables['cctid'];
$amount = $variables['amount'];
$more_link = $variables['more_link'];
$extra_class = empty($variables['extra_class']) ? '' : ' ' . $variables['extra_class'];
$terms = cctags_get_level_tags($cctid, 'block');
$output = '';
if (count($terms)) {
$count = $terms['count'];
unset($terms['count']);
$output .= '<div class="cctags cctags-block wrapper' . $extra_class . '">';
$output .= theme('cctags_level', array(
'terms' => $terms,
'amount' => $amount,
'page' => 0,
'mode' => 'mixed',
'vocname' => 0,
'out' => 'block',
));
$output .= '</div>';
if ($more_link && $count > $amount) {
$output .= theme('cctags_more', array(
'cctid' => $cctid,
));
}
}
return $output;
}
function _cctgas_terms_in_node($node) {
$query = db_select('taxonomy_term_data', 't');
$query
->join('taxonomy_index', 'i', 'i.tid = t.tid');
$query
->addField('t', 'tid');
$query
->condition('i.nid', $node->nid);
$query
->addTag('term_access');
$tids = $query
->execute()
->fetchCol();
$terms = taxonomy_term_load_multiple($tids);
return $terms;
}
function _cctgas_node_in_terms($tid) {
$query = db_select('taxonomy_term_data', 't');
$query
->join('taxonomy_index', 'i', 'i.tid = t.tid');
$query
->addField('i', 'nid');
$query
->condition('t.tid', $tid);
$query
->addTag('node_access');
$tids = $query
->execute()
->fetchCol();
return count($tids);
}