1<?php
2
3/**
4 * DokuWiki Plugin struct (Helper Component)
5 *
6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7 * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
8 */
9
10// must be run within Dokuwiki
11use dokuwiki\plugin\struct\meta\ConfigParser;
12use dokuwiki\plugin\struct\meta\SearchConfig;
13use dokuwiki\plugin\struct\meta\StructException;
14
15class remote_plugin_struct extends DokuWiki_Remote_Plugin
16{
17    /** @var helper_plugin_struct hlp */
18    protected $hlp;
19
20    /**
21     * remote_plugin_struct constructor.
22     */
23    public function __construct()
24    {
25        parent::__construct();
26
27        /** @var helper_plugin_struct hlp */
28        $this->hlp = plugin_load('helper', 'struct');
29    }
30
31    /**
32     * Get the structured data of a given page
33     *
34     * @param string $page The page to get data for
35     * @param string $schema The schema to use empty for all
36     * @param int $time A timestamp if you want historic data (0 for now)
37     * @return array ('schema' => ( 'fieldlabel' => 'value', ...))
38     * @throws RemoteAccessDeniedException
39     * @throws RemoteException
40     */
41    public function getData($page, $schema, $time)
42    {
43        $page = cleanID($page);
44
45        if (auth_quickaclcheck($page) < AUTH_READ) {
46            throw new RemoteAccessDeniedException('no permissions to access data of that page');
47        }
48
49        if (!$schema) $schema = null;
50
51        try {
52            return $this->hlp->getData($page, $schema, $time);
53        } catch (StructException $e) {
54            throw new RemoteException($e->getMessage(), 0, $e);
55        }
56    }
57
58
59    /**
60     * Saves data for a given page (creates a new revision)
61     *
62     * If this call succeeds you can assume your data has either been saved or it was
63     * not necessary to save it because the data already existed in the wanted form or
64     * the given schemas are no longer assigned to that page.
65     *
66     * @param string $page
67     * @param array $data ('schema' => ( 'fieldlabel' => 'value', ...))
68     * @param string $summary
69     * @param bool $minor
70     * @return bool returns always true
71     * @throws RemoteAccessDeniedException
72     * @throws RemoteException
73     */
74    public function saveData($page, $data, $summary, $minor = false)
75    {
76        $page = cleanID($page);
77
78        if (auth_quickaclcheck($page) < AUTH_EDIT) {
79            throw new RemoteAccessDeniedException('no permissions to save data for that page');
80        }
81
82        try {
83            $this->hlp->saveData($page, $data, $summary, $minor);
84            return true;
85        } catch (StructException $e) {
86            throw new RemoteException($e->getMessage(), 0, $e);
87        }
88    }
89
90    /**
91     * Get info about existing schemas columns
92     *
93     * Returns only current, enabled columns
94     *
95     * @param string $schema the schema to query, empty for all
96     * @return array
97     * @throws RemoteAccessDeniedException
98     * @throws RemoteException
99     */
100    public function getSchema($schema = null)
101    {
102        if (!auth_ismanager()) {
103            throw new RemoteAccessDeniedException('you need to be manager to access schema info');
104        }
105
106        try {
107            $result = array();
108            $schemas = $this->hlp::getSchema($schema ?: null);
109            foreach ($schemas as $name => $schema) {
110                $result[$name] = array();
111                foreach ($schema->getColumns(false) as $column) {
112                    $result[$name][] = array(
113                        'name' => $column->getLabel(),
114                        'type' => array_pop(explode('\\', get_class($column->getType()))),
115                        'ismulti' => $column->isMulti()
116                    );
117                }
118            }
119            return $result;
120        } catch (StructException $e) {
121            throw new RemoteException($e->getMessage(), 0, $e);
122        }
123    }
124
125    /**
126     * Get the data that would be shown in an aggregation
127     *
128     * @param array $schemas array of strings with the schema-names
129     * @param array $cols array of strings with the columns
130     * @param array $filter array of arrays with ['logic'=> 'and'|'or', 'condition' => 'your condition']
131     * @param string $sort string indicating the column to sort by
132     *
133     * @return array array of rows, each row is an array of the column values
134     * @throws RemoteException
135     */
136    public function getAggregationData(array $schemas, array $cols, array $filter = [], $sort = '')
137    {
138        $schemaLine = 'schema: ' . implode(', ', $schemas);
139        $columnLine = 'cols: ' . implode(', ', $cols);
140        $filterLines = array_map(function ($filter) {
141            return 'filter' . $filter['logic'] . ': ' . $filter['condition'];
142        }, $filter);
143        $sortLine = 'sort: ' . $sort;
144        // schemas, cols, REV?, filter, order
145
146        try {
147            $parser = new ConfigParser(array_merge([$schemaLine, $columnLine, $sortLine], $filterLines));
148            $config = $parser->getConfig();
149            $search = new SearchConfig($config);
150            $results = $search->execute();
151            $data = [];
152            /** @var \dokuwiki\plugin\struct\meta\Value[] $rowValues */
153            foreach ($results as $rowValues) {
154                $row = [];
155                foreach ($rowValues as $value) {
156                    $row[$value->getColumn()->getFullQualifiedLabel()] = $value->getDisplayValue();
157                }
158                $data[] = $row;
159            }
160            return $data;
161        } catch (StructException $e) {
162            throw new RemoteException($e->getMessage(), 0, $e);
163        }
164    }
165}
166