1<?php
2
3class helper_plugin_tagfilter_syntax extends DokuWiki_Plugin
4{
5    function getTagPageRelations($opt) {
6        /* @var $Htagfilter helper_plugin_tagfilter */
7        $Htagfilter = $this->loadHelper('tagfilter');
8
9        $flags = $opt['tfFlags'];
10
11        $tagselect_r = $opt['tagselect_r'];
12        foreach($tagselect_r['tag_expr'] as $key=>$tag_expr){ //build tag->pages relation
13            $tagselect_r['tagPages'][$key] = $Htagfilter->getRelationsByTagRegExp($tag_expr,$opt['ns']);
14        }
15
16        //extract all pageids
17        $pageids = array();
18        foreach($tagselect_r['tagPages'] as $select_r){
19            if(!is_array($select_r)) continue;
20            foreach($select_r as $tag => $pageid_r){
21                if(!empty($flags['withTags']) && !in_array($tag,$flags['withTags'])) continue;
22                if(!empty($flags['excludeTags']) && in_array($tag,$flags['excludeTags'])) continue;
23                $pageids = array_merge($pageids,$pageid_r);
24            }
25        }
26
27        //Template nicht anzeigen
28        $pageids = array_filter($pageids,function($val) use($opt){
29            if(strpos($val,'_template')!==false) return false;
30
31            foreach($opt['tfFlags']['excludeNs'] as $excludeNs) {
32                if(strpos($val, $excludeNs) === 0) return false;
33            }
34            return true;
35        });
36
37            $pageids = array_unique($pageids); //TODO cache this
38
39            //cache $pageids and $tagselect_r for all users
40            return array(
41                $tagselect_r,
42                $pageids
43
44            );
45    }
46
47    public function prepareList($pageids, $flags) {
48        global $ID;
49        global $INFO;
50
51        /* @var $Htagfilter helper_plugin_tagfilter */
52        $Htagfilter = $this->loadHelper('tagfilter');
53
54        if(!isset($flags['tagcolumn']))$flags['tagcolumn'] = array();
55
56
57
58        $pages = array();
59        $_uniqueid = 0;
60        foreach($pageids as $page){
61
62            $depends = array('files'=>array(
63                $INFO['filepath'],
64                wikiFN($page)
65            ));
66            $cache_key = 'plugin_tagfilter_'.$ID . '_' . $page;
67            $cache = new cache($cache_key, '.tpcache');
68            if(!$cache->useCache($depends)) {
69                $title = p_get_metadata($page, 'title', METADATA_DONT_RENDER);
70
71                $cache_page = array(
72                    'title' => $title?$title:$page,
73                    'id' => $page,
74                    'tmp_id' => $title?$title:(noNS($page)?noNS($page):$page),
75                );
76
77                foreach($flags['tagcolumn'] as $tagcolumn){
78                    $cache_page[hsc($tagcolumn)] = $Htagfilter->td($page,hsc($tagcolumn));
79                }
80                foreach($flags['tagimagecolumn'] as $tagimagecolumn){
81                    $cache_page[hsc($tagimagecolumn[0]).' '] = $Htagfilter->getTagImageColumn($page,$tagimagecolumn[0], $tagimagecolumn[1]);
82                }
83                $cache->storeCache(serialize($cache_page));
84            } else {
85                $cache_page = unserialize($cache->retrieveCache());
86            }
87
88            $tmp_id = $cache_page['tmp_id'];
89            if(isset($pages[$tmp_id])) {
90                $tmp_id .= '_'.$_uniqueid++;
91            }
92
93            $pages[$tmp_id] = $cache_page;
94        }
95
96
97        if($flags['rsort']) {
98            krsort($pages,SORT_NATURAL|SORT_FLAG_CASE);
99        } else {
100            ksort($pages,SORT_NATURAL|SORT_FLAG_CASE);
101        }
102        return $pages;
103    }
104
105
106    function renderList($pages, $flags,$pagelistflags) {
107        /* @var $Htagfilter helper_plugin_tagfilter */
108        $Htagfilter = $this->loadHelper('tagfilter');
109
110        if(!isset($flags['tagcolumn']))$flags['tagcolumn'] = array();
111
112
113
114        // let Pagelist Plugin do the work for us
115        if (plugin_isdisabled('pagelist')
116            || (!$Hpagelist = plugin_load('helper', 'pagelist'))) {
117                msg($this->getLang('missing_pagelistplugin'), -1);
118                return false;
119            }
120
121            foreach($flags['tagcolumn'] as $tagcolumn) {
122                $Hpagelist->addColumn('tagfilter',hsc($tagcolumn));
123            }
124            foreach($flags['tagimagecolumn'] as $tagimagecolumn) {
125                $Hpagelist->addColumn('tagfilter', hsc($tagimagecolumn[0] . ' '));
126            }
127
128            unset($flags['tagcolumn']);
129            $Hpagelist->setFlags($pagelistflags);
130            $Hpagelist->startList();
131
132            foreach ($pages as $page) {
133                $Hpagelist->addPage($page);
134            }
135
136
137            return $Hpagelist->finishList();
138    }
139
140
141    /*
142     * parseFlags checks for tagfilter flags and returns them as true/false
143     * @param $flags array
144     * @return array tagfilter flags
145     */
146    function parseFlags($flags){
147        if(!is_array($flags)) return false;
148        $conf = array(
149            'multi' => false,
150            'chosen' => false,
151            'tagimage' => false,
152            'pagesearch' => false,
153            'pagesearchlabel' => 'Seiten',
154            'cache' => false,
155            'rsort' => false,
156            'labels' => true,
157            'noneonclear' => false,
158            'tagimagecolumn' => array(),
159            'excludeNs' => array(),
160            'withTags' => array(),
161            'excludeTags' => array(),
162            'images' => false,
163            'count' => false,
164            'tagintersect' => false,
165        );
166
167        foreach($flags as $k=>$flag) {
168            list($flag,$value) = explode('=',$flag,2);
169            $flag = trim($flag);
170            $value = trim($value);
171            switch($flag) {
172                case 'multi':
173                    $conf['multi'] = true;
174                    break;
175                case 'chosen':
176                    $conf['chosen'] = true;
177                    break;
178                case 'tagimage':
179                    $conf['tagimage']= true;
180                    break;
181                case 'pagesearch':
182                    $conf['pagesearch']= true;
183                    if($value != ''){
184                        $conf['pagesearchlabel'] = hsc($value);
185                    }
186                    break;
187                case 'cacheage':
188                    $conf['cache'] = intval($value);
189                    break;
190                case 'nocache':
191                    $conf['cache'] = null;
192                    break;
193                case 'tagcolumn':
194                    $conf['tagcolumn'][] = $value;
195                    break;
196                case 'tagimagecolumn':
197                    $conf['tagimagecolumn'][] = explode('=', $value,2);
198                    break;
199                case 'rsort':
200                    $conf['rsort'] = true;
201                    break;
202                case 'nolabels':
203                    $conf['labels'] = false;
204                    break;
205                case 'noneonclear':
206                    $conf['noneonclear'] = true;
207                    break;
208                case 'excludeNs':
209                    $conf['excludeNs'] = explode(',', $value,2);
210                    break;
211                case 'withTags':
212                    $conf['withTags'] = explode(',', $value,2);
213                    break;
214                case 'excludeTags':
215                    $conf['excludeTags'] = explode(',', $value,2);
216                    break;
217                case 'images':
218                    $conf['images'] = true;
219                    break;
220                case 'count':
221                    $conf['count'] = true;
222                    break;
223                case 'tagintersect':
224                    $conf['tagintersect'] = true;
225                    break;
226            }
227        }
228
229        return $conf;
230    }
231
232
233    /**
234     * This function just lists documents (for RSS namespace export)
235     *
236     * @author  Andreas Gohr <andi@splitbrain.org>
237     */
238    function search_all_pages(&$data,$base,$file,$type,$lvl,$opts){
239        global $conf;
240
241        //we do nothing with directories
242        if($type == 'd') return true;
243
244        //only search txt files
245        if(substr($file,-4) == '.txt'){
246            foreach($opts['excludeNs'] as $excludeNs) {
247                if(strpos($file, str_replace(':','/',$excludeNs)) === 0) return true;
248            }
249
250            //check ACL
251            $data[] = $conf['datadir'].'/'.$file;
252        }
253        return false;
254    }
255}
256