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