View source
<?php
function tagadelic_help($path, $arg) {
switch ($path) {
case 'admin/help#tagadelic':
return t('Tagadelic offers dynamic urls. <br/>Visit example.com/tagadelic/list/2,1,5 to get the vocabularies 2,1 and 5 listed as tag groups. <br/>Visit example.com/tagadelic/chunk/2,1,5 to get a tag cloud of the terms in the vocabularies 2,1 and 5.<br/> Note that we limit to five vocabularies.');
}
}
function tagadelic_init() {
drupal_add_css(drupal_get_path('module', 'tagadelic') . '/tagadelic.css');
}
function tagadelic_menu() {
$items = array();
$items['admin/settings/tagadelic'] = array(
'title' => 'Tagadelic configuration',
'description' => 'Configure the tag clouds. Set the order, the number of tags, and the depth of the clouds.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'tagadelic_settings',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer taxonomy',
),
);
$items['tagadelic'] = array(
'title' => 'Tags',
'page callback' => 'tagadelic_page_chunk',
'page arguments' => array(
NULL,
),
'access callback' => 'user_access',
'access arguments' => array(
'access content',
),
'type' => MENU_SUGGESTED_ITEM,
);
$items['tagadelic/list/%tagadelic_vocs'] = array(
'title callback' => 'tagadelic_page_title_callback',
'title arguments' => array(
2,
),
'page callback' => 'tagadelic_page_list',
'page arguments' => array(
2,
),
'access callback' => 'user_access',
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
);
$items['tagadelic/chunk/%tagadelic_vocs'] = array(
'title callback' => 'tagadelic_page_title_callback',
'title arguments' => array(
2,
),
'page callback' => 'tagadelic_page_chunk',
'page arguments' => array(
2,
),
'access callback' => 'user_access',
'access arguments' => array(
'access content',
),
'type' => MENU_SUGGESTED_ITEM,
);
return $items;
}
function tagadelic_nodeapi(&$node, $op, $teaser, $page) {
if ($op == 'load') {
$node->tags = tagadelic_node_get_terms($node);
}
}
function tagadelic_settings() {
$options = array(
'weight,asc' => t('by weight, ascending'),
'weight,desc' => t('by weight, descending'),
'title,asc' => t('by title, ascending'),
'title,desc' => t('by title, descending'),
'random,none' => t('random'),
);
$form['tagadelic_sort_order'] = array(
'#type' => 'radios',
'#title' => t('Tagadelic sort order'),
'#options' => $options,
'#default_value' => variable_get('tagadelic_sort_order', 'title,asc'),
'#description' => t('Determines the sort order of the tags on the freetagging page.'),
);
$form['tagadelic_page_amount'] = array(
'#type' => 'textfield',
'#size' => 5,
'#title' => t('Amount of tags on the pages'),
'#default_value' => variable_get('tagadelic_page_amount', '60'),
'#description' => t('The amount of tags that will show up in a cloud on the pages. Amount of tags in blocks must be configured in the block settings of the various cloud blocks.'),
);
$form['tagadelic_levels'] = array(
'#type' => 'textfield',
'#size' => 5,
'#title' => t('Number of levels'),
'#default_value' => variable_get('tagadelic_levels', 6),
'#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 tagadelic.css'),
);
return system_settings_form($form);
}
function tagadelic_vocs_load($vocs) {
$parsed_vocs = array();
if (is_numeric($vocs)) {
$parsed_vocs = array(
$vocs,
);
}
elseif (preg_match('/^([0-9]+,){1,5}[0-9]+$/', $vocs)) {
$parsed_vocs = explode(',', $vocs);
}
return $parsed_vocs;
}
function tagadelic_page_title_callback($vocs) {
$title = '';
if (empty($vocs)) {
$title = t('Tags');
}
else {
$title = t('Tags in @vocabularies', array(
'@vocabularies' => theme('tagadelic_list_vocs', $vocs),
));
}
return $title;
}
function theme_tagadelic_list_vocs($vocs) {
$voc_names = array();
foreach ($vocs as $vid) {
$vocabulary = taxonomy_vocabulary_load($vid);
if (!empty($vocabulary)) {
$voc_names[] = $vocabulary->name;
}
}
return join(', ', $voc_names);
}
function tagadelic_page_chunk($vocs) {
if ($vocs == NULL) {
foreach (taxonomy_get_vocabularies(NULL) as $vocabulary) {
$vocs[] = $vocabulary->vid;
}
}
$tags = tagadelic_get_weighted_tags($vocs, variable_get('tagadelic_levels', 6), variable_get('tagadelic_page_amount', '60'));
$tags = tagadelic_sort_tags($tags);
$output = theme('tagadelic_weighted', $tags);
if (!$output) {
return drupal_not_found();
}
$output = "<div class=\"wrapper tagadelic\">{$output}</div>";
return $output;
}
function tagadelic_page_list($vocs) {
$output = '';
if ($vocs == NULL) {
return drupal_not_found();
}
foreach ($vocs as $vid) {
$vocabulary = taxonomy_vocabulary_load($vid);
if (!empty($vocabulary)) {
$vocabulary->description = filter_xss_admin($vocabulary->description);
$vocabulary->name = filter_xss_admin($vocabulary->name);
$tags = tagadelic_get_weighted_tags(array(
$vocabulary->vid,
), variable_get('tagadelic_levels', 6), variable_get('tagadelic_page_amount', '60'));
$tags = tagadelic_sort_tags($tags);
$output .= theme('tagadelic_list_box', $vocabulary, $tags);
}
}
if (empty($output)) {
return drupal_not_found();
}
$stylesheet = drupal_get_path('module', 'tagadelic') . '/tagadelic.css';
drupal_add_css($stylesheet, 'all');
$output = "<div class=\"wrapper tagadelic\">{$output}</div>";
return $output;
}
function tagadelic_node_get_terms($node) {
static $vocs;
if ($terms = taxonomy_node_get_terms($node, 'tid')) {
if (!isset($vocs[$node->type])) {
$vocs[$node->type] = taxonomy_get_vocabularies($node->type);
}
$tags = array();
foreach ($terms as $tid => $term) {
if ($vocs[$node->type][$term->vid]->tags) {
$tags[$term->vid][$tid] = $term;
}
}
return $tags;
}
}
function tagadelic_tags_lists($node) {
if (is_array($node->tags)) {
$output = '';
foreach ($node->tags as $vid => $terms) {
$vocabulary = taxonomy_vocabulary_load($vid);
$title = l($vocabulary->name, "tagadelic/chunk/{$vid}");
$items = array();
foreach ($terms as $term) {
$items[] = l($term->name, taxonomy_term_path($term), array(
'attributes' => array(
'title' => t('view all posts tagged with "@tag"', array(
'@tag' => $term->name,
)),
),
));
}
$output .= theme('item_list', $items, $title);
}
return $output;
}
}
function tagadelic_get_weighted_tags($vids, $steps = 6, $size = 60) {
$tags = array();
global $language;
$options = implode('_', $vids) . '_' . $language->language . '_' . $steps . '_' . $size;
$cache_name = 'tagadelic_cache_' . $options;
$cache = cache_get($cache_name, 'cache_page');
if (isset($cache->data)) {
$tags = $cache->data;
}
else {
if (!is_array($vids) || count($vids) == 0) {
return array();
}
$result = db_query_range(db_rewrite_sql('SELECT COUNT(*) AS count, td.tid, td.vid, td.name, td.description FROM {term_data} td INNER JOIN {term_node} tn ON td.tid = tn.tid INNER JOIN {node} n ON tn.vid = n.vid WHERE td.vid IN (' . db_placeholders($vids) . ') AND n.status = 1 GROUP BY td.tid, td.vid, td.name, td.description HAVING COUNT(*) > 0 ORDER BY count DESC'), $vids, 0, $size);
$tags = tagadelic_build_weighted_tags($result, $steps);
cache_set($cache_name, $tags, 'cache_page', CACHE_TEMPORARY);
}
return $tags;
}
function tagadelic_build_weighted_tags($result, $steps = 6) {
$tags = array();
$min = 1000000000.0;
$max = -1000000000.0;
while ($tag = db_fetch_object($result)) {
$tag->number_of_posts = $tag->count;
$tag->count = log($tag->count);
$min = min($min, $tag->count);
$max = max($max, $tag->count);
$tags[$tag->tid] = $tag;
}
$range = max(0.01, $max - $min) * 1.0001;
foreach ($tags as $key => $value) {
$tags[$key]->weight = 1 + floor($steps * ($value->count - $min) / $range);
}
return $tags;
}
function tagadelic_sort_tags($tags) {
list($sort, $order) = explode(',', variable_get('tagadelic_sort_order', 'title,asc'));
switch ($sort) {
case 'title':
usort($tags, "_tagadelic_sort_by_title");
break;
case 'weight':
usort($tags, "_tagadelic_sort_by_weight");
break;
case 'random':
shuffle($tags);
break;
}
if ($order == 'desc') {
$tags = array_reverse($tags);
}
return $tags;
}
function _tagadelic_sort_by_title($a, $b) {
return strnatcasecmp($a->name, $b->name);
}
function _tagadelic_sort_by_weight($a, $b) {
if ($a->weight == $b->weight) {
return $a->count > $b->count;
}
return $a->weight > $b->weight;
}
function theme_tagadelic_weighted($terms) {
$output = '';
foreach ($terms as $term) {
$output .= l($term->name, taxonomy_term_path($term), array(
'attributes' => array(
'class' => "tagadelic level{$term->weight}",
'rel' => 'tag',
'title' => $term->description,
),
)) . " \n";
}
return $output;
}
function theme_tagadelic_list_box($vocabulary, $tags) {
$output = '';
$content = theme('tagadelic_weighted', $tags);
if ($vocabulary->description) {
$content = theme("box", NULL, $vocabulary->description) . $content;
}
$output .= theme('box', $vocabulary->name, $content);
return $output;
}
function theme_tagadelic_more($vid = NULL) {
return "<div class='more-link'>" . l(t('more tags'), $vid ? "tagadelic/chunk/{$vid}" : "tagadelic") . "</div>";
}
function tagadelic_block($op = 'list', $delta = 0, $edit = array()) {
$blocks = array();
if ($op == 'view') {
if ($voc = taxonomy_vocabulary_load($delta)) {
$blocks['subject'] = variable_get('tagadelic_block_title_' . $delta, t('Tags in @voc', array(
'@voc' => $voc->name,
)));
$tags = tagadelic_get_weighted_tags(array(
$voc->vid,
), variable_get('tagadelic_levels', 6), variable_get('tagadelic_block_tags_' . $delta, 12));
$tags = tagadelic_sort_tags($tags);
$blocks['content'] = theme('tagadelic_weighted', $tags);
if (count($tags) >= variable_get('tagadelic_block_tags_' . $delta, 12)) {
$blocks['content'] .= theme('tagadelic_more', $voc->vid);
}
}
elseif ($delta == 'all') {
$blocks['subject'] = t('Tags');
$tags = tagadelic_get_weighted_tags(array_keys(taxonomy_get_vocabularies()), variable_get('tagadelic_levels', 6), variable_get('tagadelic_block_tags_' . $delta, 12));
$tags = tagadelic_sort_tags($tags);
$blocks['content'] = theme('tagadelic_weighted', $tags);
if (count($tags) >= variable_get('tagadelic_block_tags_' . $delta, 12)) {
$blocks['content'] .= theme('tagadelic_more');
}
}
elseif (arg(0) == 'node' && is_numeric(arg(1)) && ($node = node_load(arg(1)))) {
$blocks['subject'] = t('Tags for @title', array(
'@title' => $node->title,
));
$blocks['content'] = tagadelic_tags_lists($node);
}
return $blocks;
}
elseif ($op == 'list') {
foreach (taxonomy_get_vocabularies() as $voc) {
$blocks[$voc->vid]['info'] = t('Tags in @voc', array(
'@voc' => $voc->name,
));
$blocks[$voc->vid]['cache'] = BLOCK_CACHE_GLOBAL;
}
$blocks[0]['info'] = t('Tags for the current post');
$blocks[0]['cache'] = BLOCK_CACHE_PER_PAGE;
$blocks['all']['info'] = t('Tags for all vocabularies');
$blocks['all']['cache'] = BLOCK_CACHE_GLOBAL;
return $blocks;
}
elseif ($op == 'configure') {
$voc = taxonomy_vocabulary_load($delta);
$form = array();
$form['tags'] = array(
'#type' => 'textfield',
'#title' => t('Tags to show'),
'#default_value' => variable_get('tagadelic_block_tags_' . $delta, 12),
'#maxlength' => 3,
'#description' => t('The number of tags to show in this block.'),
);
return $form;
}
elseif ($op == 'save') {
variable_set('tagadelic_block_tags_' . $delta, $edit['tags']);
return;
}
}
function tagadelic_theme() {
return array(
'tagadelic_list_box' => array(
'arguments' => array(
'vocabulary' => NULL,
'tags' => NULL,
),
),
'tagadelic_more' => array(
'arguments' => array(
'vid' => NULL,
),
),
'tagadelic_weighted' => array(
'arguments' => array(
'terms' => NULL,
),
),
'tagadelic_list_vocs' => array(
'arguments' => array(
'vid' => NULL,
),
),
);
}