xref: /plugin/tagging/helper.php (revision f61105de9ace77a621f8fceeec1bf53648efc9d7)
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