1<?php 2 3if(!defined('DOKU_INC')) die(); 4class helper_plugin_tagging extends DokuWiki_Plugin { 5 6 private function getDB() { 7 static $db; 8 if (!is_null($db)) { 9 return $db; 10 } 11 12 $db = plugin_load('helper', 'sqlite'); 13 if (is_null($db)) { 14 msg('The tagging plugin needs the sqlite plugin', -1); 15 return false; 16 } 17 $db->init('tagging',dirname(__FILE__).'/db/'); 18 return $db; 19 } 20 21 public function replaceTags($id, $user, $tags) { 22 $db = $this->getDB(); 23 $db->query('BEGIN TRANSACTION'); 24 $queries = array(array('DELETE FROM taggings WHERE pid = ? AND tagger = ?', $id, $user)); 25 foreach ($tags as $tag) { 26 $queries[] = array('INSERT INTO taggings (pid, tagger, tag) VALUES(?, ?, ?)', $id, $user, $tag); 27 } 28 29 foreach ($queries as $query) { 30 if (!call_user_func_array(array($db, 'query'), $query)) { 31 $db->query('ROLLBACK TRANSACTION'); 32 return false; 33 } 34 } 35 return $db->query('COMMIT TRANSACTION'); 36 } 37 38 public function getTags($search, $return) { 39 $where = '1=1'; 40 foreach($search as $k => $v) { 41 if ($k === 'tag') { 42 $k = 'UPPER(tag)'; 43 } 44 45 if ($this->useLike($v)) { 46 $where .= " AND $k LIKE"; 47 } else { 48 $where .= " AND $k ="; 49 } 50 51 if ($k === 'UPPER(tag)') { 52 $where .= ' UPPER(?)'; 53 } else { 54 $where .= ' ?'; 55 } 56 } 57 58 $db = $this->getDB(); 59 $res = $db->query('SELECT ' . $return . ', COUNT(*) ' . 60 'FROM taggings WHERE ' . $where . ' GROUP BY ' . $return . 61 ' ORDER BY tag', 62 array_values($search)); 63 64 $res = $db->res2arr($res); 65 $ret = array(); 66 foreach ($res as $v) { 67 $ret[$v[$return]] = $v['COUNT(*)']; 68 } 69 return $ret; 70 } 71 72 private function useLike($v) { 73 return strpos($v, '%') === 0 || strrpos($v, '%') === strlen($v) - 1; 74 } 75 76 public function getTagSearchURL($tag) { 77 return '?do=search&id=' . $tag . '#' . 78 str_replace(' ', '_', strtolower($this->getLang('search_section_title'))); 79 } 80 81 public function cloudData($tags, $levels = 10) { 82 $min = min($tags); 83 $max = max($tags); 84 85 // calculate tresholds 86 $tresholds = array(); 87 for($i=0; $i<=$levels; $i++){ 88 $tresholds[$i] = pow($max - $min + 1, $i/$levels) + $min - 1; 89 } 90 91 // assign weights 92 foreach($tags as $tag => $cnt){ 93 foreach($tresholds as $tresh => $val){ 94 if($cnt <= $val){ 95 $tags[$tag] = $tresh; 96 break; 97 } 98 $tags[$tag] = $levels; 99 } 100 } 101 return $tags; 102 } 103 104 public function html_cloud($tags, $type, $func, $wrap = true, $return = false) { 105 $ret = ''; 106 if ($wrap) $ret .= '<ul class="tagging_cloud clearfix">'; 107 if (count($tags) === 0) { 108 // Produce valid XHTML (ul needs a child) 109 $this->setupLocale(); 110 $ret .= '<li><div class="li">' . $this->lang['js']['no' . $type . 's'] . '</div></li>'; 111 } else { 112 $tags = $this->cloudData($tags); 113 foreach ($tags as $val => $size) { 114 $ret .= '<li class="t' . $size . '"><div class="li">'; 115 $ret .= call_user_func($func, $val); 116 $ret .= '</div></li>'; 117 } 118 } 119 if ($wrap) $ret .= '</ul>'; 120 if ($return) return $ret; 121 echo $ret; 122 } 123 124 private function linkToSearch($tag) { 125 return '<a href="' . hsc($this->getTagSearchURL($tag)) . '">' . 126 $tag . '</a>'; 127 } 128 129 public function tpl_tags() { 130 global $ID; 131 global $INFO; 132 global $lang; 133 $tags = $this->getTags(array('pid' => $ID), 'tag'); 134 $this->html_cloud($tags, 'tag', array($this, 'linkToSearch')); 135 136 if (isset($_SERVER['REMOTE_USER']) && $INFO['writable']) { 137 $lang['btn_tagging_edit'] = $lang['btn_secedit']; 138 echo html_btn('tagging_edit', $ID, '', array()); 139 $form = new Doku_Form(array('id' => 'tagging_edit', 'style' => 'display: none;')); 140 $form->addHidden('tagging[id]', $ID); 141 $form->addElement(form_makeTextField('tagging[tags]', implode(', ', array_keys($this->getTags(array('pid' => $ID, 'tagger' => $_SERVER['REMOTE_USER']), 'tag'))))); 142 $form->addElement(form_makeButton('submit', 'save', $lang['btn_save'], array('id' => 'tagging_edit_save'))); 143 $form->addElement(form_makeButton('submit', 'cancel', $lang['btn_cancel'], array('id' => 'tagging_edit_cancel'))); 144 $form->printForm(); 145 } 146 } 147 148 public function getAllTags(){ 149 150 $db = $this->getDb(); 151 $res = $db->query('SELECT pid, tag FROM taggings ORDER BY tag'); 152 153 $tags_tmp = $db->res2arr($res); 154 $tags = array(); 155 foreach ($tags_tmp as $tag) { 156 157 $tags[$tag['tag']]['pid'][] = $tag['pid']; 158 159 if (isset($tags[$tag['tag']]['count'])) { 160 $tags[$tag['tag']]['count']++; 161 } else { 162 $tags[$tag['tag']]['count'] = 1; 163 } 164 } 165 return $tags; 166 } 167 168 public function renameTag($formerTagName, $newTagName) { 169 170 if(empty($formerTagName) || empty($newTagName)) { 171 return "admin enter tag names"; 172 } 173 174 $db = $this->getDb(); 175 176 $res = $db->query('SELECT pid FROM taggings WHERE tag="'. $formerTagName .'"'); 177 $check = $db->res2arr($res); 178 179 if (empty($check)) { 180 return "admin tag does not exists"; 181 } 182 183 $res = $db->query("UPDATE taggings SET tag='".$newTagName."' WHERE tag='" . $formerTagName . "'"); 184 $db->res2arr($res); 185 186 return "admin saved"; 187 } 188 189} 190