init('tagging',dirname(__FILE__).'/db/'); $db->create_function('CLEANTAG', array($this, 'cleanTag'), 1); return $db; } /** * Canonicalizes the tag to its lower case nospace form * * @param $tag * @return string */ public function cleanTag($tag) { $tag = str_replace(' ', '', $tag); $tag = utf8_strtolower($tag); return $tag; } public function replaceTags($id, $user, $tags) { $db = $this->getDB(); $db->query('BEGIN TRANSACTION'); $queries = array(array('DELETE FROM taggings WHERE pid = ? AND tagger = ?', $id, $user)); foreach ($tags as $tag) { $queries[] = array('INSERT INTO taggings (pid, tagger, tag) VALUES(?, ?, ?)', $id, $user, $tag); } foreach ($queries as $query) { if (!call_user_func_array(array($db, 'query'), $query)) { $db->query('ROLLBACK TRANSACTION'); return false; } } return $db->query('COMMIT TRANSACTION'); } /** * Get a list of Tags or Pages matching a search criteria * * @param array $search What to search for array('field' => 'searchterm') * @param string $return What field to return 'tag'|'pid' * @return array associative array in form of value => count * @todo this is a really ugly function. It should be split into separate ones */ public function getTags($search, $return) { $where = '1=1'; foreach($search as $k => $v) { if ($k === 'tag') { $k = 'CLEANTAG(tag)'; } if ($this->useLike($v)) { $where .= " AND $k LIKE"; } else { $where .= " AND $k ="; } if ($k === 'CLEANTAG(tag)') { $where .= ' CLEANTAG(?)'; } else { $where .= ' ?'; } } if($return == 'tag') { $groupby = 'CLEANTAG(tag)'; } else { $groupby = $return; } $db = $this->getDB(); $res = $db->query('SELECT ' . $return . ', COUNT(*) ' . 'FROM taggings WHERE ' . $where . ' GROUP BY ' . $groupby . ' ORDER BY tag', array_values($search)); $res = $db->res2arr($res); $ret = array(); foreach ($res as $v) { $ret[$v[$return]] = $v['COUNT(*)']; } return $ret; } private function useLike($v) { return strpos($v, '%') === 0 || strrpos($v, '%') === strlen($v) - 1; } /** * Constructs the URL to search for a tag * * @param $tag * @return string */ public function getTagSearchURL($tag) { return '?do=search&id=' . rawurlencode($tag); } public function cloudData($tags, $levels = 10) { $min = min($tags); $max = max($tags); // calculate tresholds $tresholds = array(); for($i=0; $i<=$levels; $i++){ $tresholds[$i] = pow($max - $min + 1, $i/$levels) + $min - 1; } // assign weights foreach($tags as $tag => $cnt){ foreach($tresholds as $tresh => $val){ if($cnt <= $val){ $tags[$tag] = $tresh; break; } $tags[$tag] = $levels; } } return $tags; } public function html_cloud($tags, $type, $func, $wrap = true, $return = false) { $ret = ''; if ($wrap) $ret .= '