1*f61105deSAdrian Lang<?php 2*f61105deSAdrian Lang 3*f61105deSAdrian Langif(!defined('DOKU_INC')) die(); 4*f61105deSAdrian Langclass helper_plugin_tagging extends DokuWiki_Action_Plugin { 5*f61105deSAdrian Lang 6*f61105deSAdrian Lang private function getDB() { 7*f61105deSAdrian Lang static $db; 8*f61105deSAdrian Lang if (!is_null($db)) { 9*f61105deSAdrian Lang return $db; 10*f61105deSAdrian Lang } 11*f61105deSAdrian Lang 12*f61105deSAdrian Lang $db = plugin_load('helper', 'sqlite'); 13*f61105deSAdrian Lang if (is_null($db)) { 14*f61105deSAdrian Lang msg('The tagging plugin needs the sqlite plugin', -1); 15*f61105deSAdrian Lang return false; 16*f61105deSAdrian Lang } 17*f61105deSAdrian Lang if($db->init('tagging',dirname(__FILE__).'/db/')){ 18*f61105deSAdrian Lang return $db; 19*f61105deSAdrian Lang } 20*f61105deSAdrian Lang return false; 21*f61105deSAdrian Lang } 22*f61105deSAdrian Lang 23*f61105deSAdrian Lang public function replaceTags($id, $user, $tags) { 24*f61105deSAdrian Lang $db = $this->getDB(); 25*f61105deSAdrian Lang $db->query('BEGIN TRANSACTION'); 26*f61105deSAdrian Lang $queries = array(array('DELETE FROM taggings WHERE pid = ? AND tagger = ?', $id, $user)); 27*f61105deSAdrian Lang foreach ($tags as $tag) { 28*f61105deSAdrian Lang $queries[] = array('INSERT INTO taggings (pid, tagger, tag) VALUES(?, ?, ?)', $id, $user, $tag); 29*f61105deSAdrian Lang } 30*f61105deSAdrian Lang 31*f61105deSAdrian Lang foreach ($queries as $query) { 32*f61105deSAdrian Lang if (!call_user_func_array(array($db, 'query'), $query)) { 33*f61105deSAdrian Lang $db->query('ROLLBACK TRANSACTION'); 34*f61105deSAdrian Lang return false; 35*f61105deSAdrian Lang } 36*f61105deSAdrian Lang } 37*f61105deSAdrian Lang return $db->query('COMMIT TRANSACTION'); 38*f61105deSAdrian Lang } 39*f61105deSAdrian Lang 40*f61105deSAdrian Lang public function getTags($search, $return) { 41*f61105deSAdrian Lang $where = '1=1'; 42*f61105deSAdrian Lang foreach($search as $k => $v) { 43*f61105deSAdrian Lang if (strpos($v, '%') === 0 || strrpos($v, '%') === strlen($v)) { 44*f61105deSAdrian Lang $where .= " AND $k LIKE ?"; 45*f61105deSAdrian Lang } else { 46*f61105deSAdrian Lang $where .= " AND $k = ?"; 47*f61105deSAdrian Lang } 48*f61105deSAdrian Lang } 49*f61105deSAdrian Lang $db = $this->getDB(); 50*f61105deSAdrian Lang $res = $db->query('SELECT ' . $return . ', COUNT(*) ' . 51*f61105deSAdrian Lang 'FROM taggings WHERE ' . $where . ' GROUP BY ' . $return, 52*f61105deSAdrian Lang array_values($search)); 53*f61105deSAdrian Lang 54*f61105deSAdrian Lang $res = $db->res2arr($res); 55*f61105deSAdrian Lang $ret = array(); 56*f61105deSAdrian Lang foreach ($res as $v) { 57*f61105deSAdrian Lang $ret[$v[$return]] = $v['COUNT(*)']; 58*f61105deSAdrian Lang } 59*f61105deSAdrian Lang return $ret; 60*f61105deSAdrian Lang } 61*f61105deSAdrian Lang 62*f61105deSAdrian Lang public function getTagSearchURL($tag) { 63*f61105deSAdrian Lang return '?do=search&id=' . $tag . '#' . 64*f61105deSAdrian Lang str_replace(' ', '_', strtolower($this->getLang('search_section_title'))); 65*f61105deSAdrian Lang } 66*f61105deSAdrian Lang 67*f61105deSAdrian Lang public function cloudData($tags, $levels = 10) { 68*f61105deSAdrian Lang $min = min($tags); 69*f61105deSAdrian Lang $max = max($tags); 70*f61105deSAdrian Lang 71*f61105deSAdrian Lang // calculate tresholds 72*f61105deSAdrian Lang $tresholds = array(); 73*f61105deSAdrian Lang for($i=0; $i<=$levels; $i++){ 74*f61105deSAdrian Lang $tresholds[$i] = pow($max - $min + 1, $i/$levels) + $min - 1; 75*f61105deSAdrian Lang } 76*f61105deSAdrian Lang 77*f61105deSAdrian Lang // assign weights 78*f61105deSAdrian Lang foreach($tags as $tag => $cnt){ 79*f61105deSAdrian Lang foreach($tresholds as $tresh => $val){ 80*f61105deSAdrian Lang if($cnt <= $val){ 81*f61105deSAdrian Lang $tags[$tag] = $tresh; 82*f61105deSAdrian Lang break; 83*f61105deSAdrian Lang } 84*f61105deSAdrian Lang $tags[$tag] = $levels; 85*f61105deSAdrian Lang } 86*f61105deSAdrian Lang } 87*f61105deSAdrian Lang return $tags; 88*f61105deSAdrian Lang } 89*f61105deSAdrian Lang 90*f61105deSAdrian Lang public function html_cloud($tags, $type, $func, $wrap = true, $return = false) { 91*f61105deSAdrian Lang $ret = ''; 92*f61105deSAdrian Lang if ($wrap) $ret .= '<ul class="tagging_cloud">'; 93*f61105deSAdrian Lang if (count($tags) === 0) { 94*f61105deSAdrian Lang // Produce valid XHTML (ul needs a child) 95*f61105deSAdrian Lang $this->setupLocale(); 96*f61105deSAdrian Lang $ret .= '<li><div class="li">' . $this->lang['js']['no' . $type . 's'] . '</div></li>'; 97*f61105deSAdrian Lang } else { 98*f61105deSAdrian Lang $tags = $this->cloudData($tags); 99*f61105deSAdrian Lang foreach ($tags as $val => $size) { 100*f61105deSAdrian Lang $ret .= '<li class="t' . $size . '"><div class="li">'; 101*f61105deSAdrian Lang $ret .= call_user_func($func, $val); 102*f61105deSAdrian Lang $ret .= '</div></li> '; 103*f61105deSAdrian Lang } 104*f61105deSAdrian Lang } 105*f61105deSAdrian Lang if ($wrap) $ret .= '</ul>'; 106*f61105deSAdrian Lang if ($return) return $ret; 107*f61105deSAdrian Lang echo $ret; 108*f61105deSAdrian Lang } 109*f61105deSAdrian Lang 110*f61105deSAdrian Lang private function linkToSearch($tag) { 111*f61105deSAdrian Lang return '<a href="' . hsc($this->getTagSearchURL($tag)) . '">' . 112*f61105deSAdrian Lang $tag . '</a>'; 113*f61105deSAdrian Lang } 114*f61105deSAdrian Lang 115*f61105deSAdrian Lang public function tpl_tags() { 116*f61105deSAdrian Lang global $ID; 117*f61105deSAdrian Lang global $INFO; 118*f61105deSAdrian Lang global $lang; 119*f61105deSAdrian Lang $tags = $this->getTags(array('pid' => $ID), 'tag'); 120*f61105deSAdrian Lang $this->html_cloud($tags, 'tag', array($this, 'linkToSearch')); 121*f61105deSAdrian Lang 122*f61105deSAdrian Lang if (isset($_SERVER['REMOTE_USER']) && $INFO['writable']) { 123*f61105deSAdrian Lang $lang['btn_tagging_edit'] = $lang['btn_secedit']; 124*f61105deSAdrian Lang echo html_btn('tagging_edit', $ID, '', array()); 125*f61105deSAdrian Lang $form = new Doku_Form(array('id' => 'tagging_edit', 'style' => 'display: none;')); 126*f61105deSAdrian Lang $form->addHidden('id', $ID); 127*f61105deSAdrian Lang $form->addElement(form_makeTextField('tags', implode(', ', array_keys($this->getTags(array('pid' => $ID, 'tagger' => $_SERVER['REMOTE_USER']), 'tag'))))); 128*f61105deSAdrian Lang $form->addElement(form_makeButton('submit', 'save', $lang['btn_save'], array('id' => 'tagging_edit_save'))); 129*f61105deSAdrian Lang $form->addElement(form_makeButton('submit', 'cancel', $lang['btn_cancel'], array('id' => 'tagging_edit_cancel'))); 130*f61105deSAdrian Lang $form->printForm(); 131*f61105deSAdrian Lang } 132*f61105deSAdrian Lang } 133*f61105deSAdrian Lang} 134