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