1<?php
2/**
3 * DokuWiki Plugin metaeditor (Action Component)
4 *
5 * Simple Meta Data Editor, heavily AJAX/jQuery based.
6 *
7 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
8 * @author  Andreas Böhler <dev@aboehler.at>
9 */
10
11
12// must be run within Dokuwiki
13if(!defined('DOKU_INC')) die();
14
15class action_plugin_metaeditor extends DokuWiki_Action_Plugin {
16  // Register our hooks
17  function register(Doku_Event_Handler $controller) {
18    $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call_unknown');
19  }
20
21  function handle_ajax_call_unknown($event, $param) {
22    if($event->data != 'plugin_metaeditor') return;
23
24    $event->preventDefault();
25    $event->stopPropagation();
26    global $INPUT;
27
28    $action = trim($INPUT->post->str('q'));
29    $pageid = trim($INPUT->post->str('r'));
30    $opts = $INPUT->post->arr('opts');
31    $data = array();
32    $useJson = true;
33
34    if(!checkSecurityToken())
35    {
36        echo "CSRF Attack.";
37        return;
38    }
39
40    $perm = auth_quickaclcheck($pageid);
41    if($perm == AUTH_ADMIN)
42    {
43        switch($action)
44        {
45          case 'getMeta':
46            $data = $this->getMetaForPage($pageid);
47            break;
48          case 'getMetaValue':
49            $useJson = false;
50            $data = $this->getMetaValueForPage($pageid, $opts['key']);
51            break;
52          case 'setMetaValue':
53            $data = $this->setMetaValueForPage($pageid, $opts['key'], $opts['oldval'], $opts['newval']);
54            break;
55          case 'deleteMetaValue':
56            $data = $this->deleteMetaValueForPage($pageid, $opts['key']);
57            break;
58          case 'createMetaArray':
59            $data = $this->createMetaArrayForPage($pageid, $opts['key'], $opts['newval']);
60            break;
61          case 'createMetaValue':
62            $data = $this->createMetaValueForPage($pageid, $opts['key'], $opts['newkey'], $opts['newval']);
63            break;
64        }
65    }
66    else
67    {
68      $data = array(false, "You are not an admin");
69    }
70
71
72    if($useJson)
73    {
74      //set content type
75      header('Content-Type: application/json');
76      echo json_encode($data);
77    }
78    else
79    {
80      echo $data;
81    }
82  }
83
84  function createMetaArrayForPage($pageid, $key, $newval)
85  {
86    $cache = false;
87    $meta = p_read_metadata($pageid, $cache);
88    $m = &$meta;
89    foreach($key as $k)
90    {
91      $m = &$m[$k];
92    }
93    $m[$newval] = array();
94    if(p_save_metadata($pageid, $meta))
95        return array(true, "Successfully saved: $newval");
96    else
97      return array(false, "Error saving value: $newval");
98  }
99
100  function createMetaValueForPage($pageid, $key, $newkey, $newval)
101  {
102    $cache = false;
103    $meta = p_read_metadata($pageid, $cache);
104    $m = &$meta;
105    foreach($key as $k)
106    {
107      $m = &$m[$k];
108    }
109    $m[$newkey] = $newval;
110    if(p_save_metadata($pageid, $meta))
111        return array(true, "Successfully saved: $newval");
112    else
113      return array(false, "Error saving value: $newval");
114  }
115
116  function setMetaValueForPage($pageid, $key, $oldval, $newval)
117  {
118    $cache = false;
119    $meta = p_read_metadata($pageid, $cache);
120    $m = &$meta;
121    foreach($key as $k)
122      $m = &$m[$k];
123    if($m == $oldval)
124    {
125      $m = $newval;
126      if(p_save_metadata($pageid, $meta))
127        return array(true, "Successfully saved: $newval");
128      else
129        return array(false, "Error saving value: $newval");
130    }
131    else
132    {
133      return array(false, "Key has changed in the meantime, expected $oldval but got $m. Nothing was saved!");
134    }
135
136  }
137
138  function deleteMetaValueForPage($pageid, $key)
139  {
140    $cache = false;
141    $meta = p_read_metadata($pageid, $cache);
142    $m = &$meta;
143    for($i=0;$i<count($key);$i++)
144    {
145      if($i == count($key)-1)
146        unset($m[$key[$i]]);
147      else
148        $m = &$m[$key[$i]];
149    }
150    if(p_save_metadata($pageid, $meta))
151      return array(true, "Successfully deleted key: " . join(':', $key));
152    else
153      return array(false, "Error deleting key: " . join(':', $key));
154  }
155
156  function parseMetaTree($meta)
157  {
158    $out = array();
159    foreach($meta as $k => $v)
160    {
161      $a = array();
162      if(is_numeric($k))
163        $a['text'] = strval($k);
164      else
165        $a['text'] = $k;
166      if(is_array($v))
167      {
168        $a['children'] = $this->parseMetaTree($v);
169        $a['li_attr'] = array('data-type' => 'folder');
170      }
171      else
172      {
173        $a['li_attr'] = array('data-type' => 'file');
174        $a['icon'] = DOKU_URL."/lib/images/page.png";
175      }
176      $out[] = $a;
177    }
178    return $out;
179  }
180
181  function getMetaForPage($pageid)
182  {
183    $cache = false;
184    $meta = p_read_metadata($pageid, $cache);
185    $out = $this->parseMetaTree($meta);
186    return $out;
187  }
188
189  function getMetaValueForPage($pageid, $key)
190  {
191    $cache = false;
192    $meta = p_read_metadata($pageid, $cache);
193    foreach($key as $k)
194    {
195      $meta = $meta[$k];
196    }
197    return $meta;
198  }
199
200
201
202
203}
204