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