1<?php
2/**
3 * Plugin metadisplay"
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Myron Turner <turnermm02@shaw.ca
7 */
8if(!defined('DOKU_INC')) die();
9global $timezone, $current,$conf;
10
11class helper_plugin_metadisplay_html extends DokuWiki_Plugin {
12private $subdir = "";
13private $page;
14private $match = false;
15private $exact_page_match = false;
16private $timestamp;
17private $t_when;
18private $dtype;
19private $search;
20private $fuzzy;
21private $ltype = "";
22
23//function init($subdir="", $page="", $exact="off", $search="", $fuzzy="", $tm="", $dtype="") {
24function init($options) {
25  global $conf;
26 // $subdir=""; $page=""; $exact="off"; $search=""; $fuzzy=""; $tm=""; $dtype="";
27  $subdir=$options['namespace'];
28  $page=$options['page'];
29  $exact=$options['exact'];
30  $search=$options['search'];
31  $fuzzy=$options['fuzzy'];
32  $tm=$options['tm'];
33  $dtype=$options['dtype'];
34  $ltype=$options['ltype'];
35
36  if($conf['savedir'] == './data') {
37      chdir(DOKU_INC . trim($conf['savedir'],'.\/') . '/meta');
38      define ('PAGES', DOKU_INC . trim( $conf['savedir'],"\/\\\.") . '/pages');
39  }
40   else {
41      chdir( '/'.trim( $conf['savedir'],"\/\\") . '/meta');
42      define ('PAGES',  '/'.trim( $conf['savedir'],"\/\\") . '/pages') ;
43   }
44    if($subdir == '.') $subdir = "";
45    $this->page=str_replace(':', "",$page);
46    if($subdir) {
47         $subdir = trim($subdir,':\\\/');
48         $subdir = str_replace(':','/',$subdir);
49         $this->subdir ="/$subdir";
50         chdir($subdir);
51    }
52    if($exact == 'on') $this->exact_page_match = true;
53	if($tm) {
54	 list($this->timestamp,$this->t_when) = explode(':',$tm);
55	 $this->dtype = $dtype;
56	}
57    if($search) {
58       $this->search = $search;
59	}
60    else if($fuzzy) {
61       $this->fuzzy = $this->get_regex($fuzzy);
62    }
63    if($search || $fuzzy) {
64       if($ltype) $this->ltype = $ltype;
65    }
66
67    ob_start();
68    $this->recurse('.');
69    if(!$this->match){
70        echo "No match for  $subdir/$page" ."<br />\n";
71    }
72    $contents = ob_get_contents();
73    ob_end_clean();
74    $contents = str_replace("<table.*?>\n</table>","",$contents);
75    echo $contents;
76 }
77
78function recurse($dir) {
79
80    $dh = opendir($dir);
81    if (!$dh) return;
82
83    while (($file = readdir($dh)) !== false) {
84        if ($file == '.' || $file == '..') continue;
85        if (is_dir("$dir/$file")) $this->recurse("$dir/$file");
86        if (preg_match("/\.meta$/", $file)) {
87             if($this->page && !preg_match("/" . $this->page ."/",$file)) continue;
88             if($this->exact_page_match) {
89                if(!preg_match("/^" . $this->page ."\.meta$/",$file)) continue;
90             }
91
92             $store_name = preg_replace('/^\./', $this->subdir, "$dir/$file");
93             $id_name = PAGES . preg_replace("/\.meta$/","",$store_name) . '.txt';
94             if(!file_exists($id_name)) continue;
95             $success = $this->get_data("$dir/$file","$id_name",$store_name);
96             if($success) {
97             $this->match = true;
98             echo "\n<br />";
99        }
100    }
101    }
102
103    closedir($dh);
104}
105
106/*
107  @param string $file, the meta file
108  @param string $id_path, path to dokuwiki page
109*/
110function get_data($file,$id_path,$store_name="") {
111    global $current;
112    $description = "";
113    $data = file_get_contents($file);
114    $data_array = @unserialize(file_get_contents($file));
115    $creator =""; $creator_id="";
116    $contributors = array();
117    if ($data_array === false || !is_array($data_array)) return;
118    if (!isset($data_array['current'])) return false;
119
120    $current = $data_array['current'];
121	if($this->t_when) {
122		$tmstmp = $this->getcurrent('date', $this->dtype);
123		if($this->t_when == 'b' && $tmstmp > $this->timestamp) {
124			return false;
125		}
126		else if($this->t_when == 'a' && $tmstmp < $this->timestamp) {
127			return false;
128		}
129	}
130
131    $search = "";
132    $regex = "";
133    if($this->fuzzy) {
134        $search = $this->fuzzy;
135        $regex = '/(' . $search . ')/im';
136    }
137    else if($this->search) {
138        $search = $this->search;
139        $regex = '/(' . $search . ')/m';
140    }
141    if($regex) {
142        if($this->ltype == 'descr') {
143        $description = $this->getcurrent('description','abstract');
144        if(!preg_match($regex,$description)){
145            return false;
146        }
147        $description = preg_replace($regex,"<span style='color:blue'>$1</span>",$description);
148    }
149        else if($this->ltype == 'media') {
150            $media = $this->check_listtypes('media',$regex);
151            if(!$media) return false;
152        }
153        else if($this->ltype == 'links') {
154            $references = $this->check_listtypes('references',$regex);
155            if(!$references) return false;
156        }
157        else if($this->ltype == 'contrib') {
158            $contribs = $this->getcurrent('contributor', null);
159            if(!$contribs) return false;
160            if(!array_key_exists($search,$contribs)) return;
161            $val = $contribs[$search];
162            unset($contribs[$search]);
163            $search = "<span style='color:blue'>$search</span>";
164            $contribs[$search] = $val;
165            $contributors = $contribs;
166
167        }
168        else if($this->ltype == 'creator') {
169             $creator = $this->getcurrent('creator', null);
170             $creator_id = $this->getcurrent('user', null);
171             if(!$creator && !$creator_id) return false;
172             if(!preg_match($regex,$creator) && !preg_match($regex,$creator_id)) return;
173             $creator=preg_replace($regex,"<span style='color:blue'>$1</span>",$creator);
174             $creator_id=preg_replace($regex,"<span style='color:blue'>$1</span>",$creator_id);
175         }
176
177
178
179    }
180
181    $this->match = true;
182    echo $store_name ."\n";
183    echo "\n" . '<table style="border-top:2px solid">' ."\n";
184    echo "<tr><th colspan='2'>$id_path</th></tr>\n";
185    $keys =  array('title','date','creator','last_change','relation', 'description','contributor');
186    foreach ($keys AS $header) {
187        switch($header) {
188            case 'title':
189                 $title = $this->getcurrent($header, null);
190                 echo "<tr><td colspan='2'>Title: <b>$title</b></td></tr>\n";
191                 break;
192            case 'date':
193                 $this->process_dates($this->getcurrent('date', 'created'),$this->getcurrent('date', 'modified'));
194                 break;
195            case 'user':
196                if($creator || $creator_id) break;
197            case 'creator':
198            /*
199                creator: string, full name of the user who created the page
200                user: string, the login name of the user who created the page
201            */
202                if(!$creator) {
203                $creator = $this->getcurrent('creator', null);
204                }
205                if(!$creator_id) {
206                $creator_id = $this->getcurrent('user', null);
207                }
208                $this->process_users($creator,$creator_id);
209                 break;
210
211            case 'last_change':
212                $last_change = $this->getSimpleKeyValue($this->getcurrent($header, null),"last_change");
213                 if($last_change) {
214                    echo "<tr><th colspan='2'>Last Change</th>\n";
215                    echo "<td>$last_change</td></tr>\n";
216                }
217                break;
218            case 'contributor':
219                 if(empty($contributors)) {
220                 $contributors = $this->getcurrent($header, null);
221                 }
222                 if(!$contributors) break;
223                  echo "<tr><th colspan='2'>Contributors</th>\n";
224                  echo '<tr><td>';
225                  foreach($contributors as $userid=>$name) {
226                      $this->process_users($name,$userid, '');
227                  }
228                  echo '</td></tr>';
229                 break;
230            case 'relation':
231                $isreferencedby = $this->getcurrent($header,'isreferencedby');
232                if(!$references) {
233                $references = $this->getcurrent($header,'references');
234                }
235                if(!$media) {
236                $media = $this->getcurrent($header,'media');
237                }
238                $firstimage = $this->getcurrent($header,'firstimage');
239                $haspart = $this->getcurrent($header,'haspart');
240                $subject = $this->getcurrent($header,'subject');
241                $this->process_relation($isreferencedby,$references,$media,$firstimage,$haspart,$subject);
242                break;
243            case 'description':
244                echo "<tr><th colspan='2'>Description</th></tr>\n";
245                if(!$description) {
246                $description = htmlentities($this->getcurrent($header,'abstract'));
247                }
248                $description = preg_replace("/[\n]+/",'<br />', $description);
249                echo "<td colspan='2'>$description</td></tr>\n";
250                break;
251            default:
252                 break;
253            }
254
255        }
256       echo "\n</table>\n";
257       return true;
258       $current = array();
259}
260
261/*
262*  @param array $ar metadata field
263*  @param string $which which field
264*/
265function getSimpleKeyValue($ar,$which="") {
266    $retv = "";
267
268    $types = array('C'=>'<u>C</u>reate','E'=>'<u>E</u>dit','e' =>'minor <u>e</u>dit','D'=>'<u>D</u>elete',
269    'R'=>'<u>R</u>evert');
270    if(!is_array($ar)) return false;
271    foreach ($ar As $key=>$val) {
272        if(!empty($val)) {
273           if($which == 'last_change')  {
274               if($key == 'date') {
275                   $val = date("r", $val);
276                }
277                if($key == 'type')  {
278                    $val = $types[$val];
279                }
280           }
281
282           $retv .= "<tr><td>$key:</td><td>$val</td></tr>\n";
283       }
284    }
285    return $retv;
286}
287
288function process_users($creator,$user, $label = 'Created by') {
289        if(empty($creator)) {
290            echo "\n"; return;
291         }
292        if ($label) {
293            $label .= ':';
294            echo "<tr><td>$label</td><td> $creator (userid: $user)</tr></td>\n";
295        }
296        else echo "<tr><td colspan='2'> $creator (userid: $user)</tr></td>\n";
297}
298
299function process_dates($created, $modified) {
300    $retv = "";
301
302    if ($created) {
303        $rfc_cr = date("r", $created);
304        echo "<tr><td>Date created:</td><td>".$rfc_cr.
305        "</td><td>$created</td></tr>\n";
306        }
307
308    if ($modified) {
309        $rfc_mod = date("r", $modified);
310        echo "<tr><td>Last modified:</td><td>" . $rfc_mod .
311        "</td><td>$modified</td></tr>\n";
312     }
313
314}
315
316function insertListInTable($list,$type) {
317    if($list) echo "<tr><td>$type</td><td>$list</td></tr>\n";
318}
319function process_relation($isreferencedby,$references,$media,$firstimage,$haspart,$subject) {
320     echo "<tr><th colspan='2'>Relation</th></tr>\n";
321    if(!empty($isreferencedby)) {
322        $list = $this->create_list(array_keys($isreferencedby));
323        $this->insertListInTable($list,'Backlinks');
324    }
325    if(!empty($references)) {
326       $list = $this->create_list(array_keys($references));
327       $this->insertListInTable($list,'Links');
328    }
329    if(!empty($media)) {
330       $list = $this->create_list(array_keys($media));
331       $this->insertListInTable($list,'Media');
332    }
333    if(!empty($firstimage)) {
334       echo "<tr><td>First Image</td><td colspan='2'>$firstimage</td></tr>";
335    }
336    if(!empty($haspart)) {
337       $list = $this->create_list(array_keys($haspart));
338      $this->insertListInTable($list,'haspart');
339    }
340    if(!empty($subject)) {
341       $list = create_list(array_keys($subject));
342       $this->insertListInTable($list,'Subject');
343    }
344
345}
346
347function create_list($ar) {
348    $list = "\n<ol>\n";
349    for($i=0; $i<count($ar); $i++) {
350        $list .= '<li>'. $ar[$i] . "</li>\n";
351    }
352     $list .= "</ol>\n";
353     return $list;
354}
355function getcurrent($which, $other) {
356    global $current;
357    if (!isset($current)) return "";
358    if ($other) {
359        if (isset($current[$which][$other])) {
360            return $current[$which][$other];
361        }
362    }
363    if (isset($current[$which]) && $other === null) {
364        return $current[$which];
365    }
366    return "";
367}
368
369function get_regex($str) {
370    $str = preg_replace('{([aeiou])\1+}','$1',$str);
371    $a = str_split($str);
372
373    for($i = 0; $i < count($a); $i++) {
374        if(preg_match("/[aeiou]/",$a[$i])) {
375            $a[$i] = '[aeiou]+';
376        }
377    }
378    return implode("",$a);
379}
380
381function check_listtypes($which,$regex) {
382    if($which == 'references' || $which == 'media') {
383        $ar = $this->getcurrent('relation',$which);
384       // cli_plugin_metadisplay::write_debug($ar ."\n" . print_r($ar,1));
385       if(is_array($ar)) {
386        $references = array_keys($ar); // references here refers to either images or links
387       }
388       else $references = $ar;
389        if(!empty($references)) {
390            $str = implode('|',$references);
391            if(preg_match($regex,$str)) {
392                    $str = preg_replace($regex,"<span style='color:blue'>$1</span>",$str);
393                    if($str) {
394                        $arr = explode('|', $str);
395                        $vals = array_values($ar);
396                        $val_str = implode('|',$vals);
397                        $val_str = preg_replace($regex,"<span style='color:blue'>$1</span>",$val_str);
398                        $vals = explode('|',$val_str);
399                        return array_combine($arr,$vals);
400                    }
401                }
402                return false;
403            }
404          return false;
405        }
406    return $ar;
407}
408
409
410}