1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4
5/**
6 * Class InlineConfigParser
7 *
8 * Wrapper to convert inline syntax to full before instantiating ConfigParser
9 *
10 * {{$schema.field}}
11 * {{$pageid.schema.field}}
12 * {{$... ? filter: ... and: ... or: ...}} or {{$... ? & ... | ...}}
13 * TODO: {{$... ? sum}} or {{$... ? +}}
14 * TODO: {{$... ? default: ...}} or {{$... ? ! ...}}
15 * Colons following key words must have no space preceding them.
16 * If no page ID or filter is supplied, filter: "%pageid% = $ID$" is added.
17 * Any component can be placed in double quotes (needed to allow space, dot or question mark in components).
18 *
19 * @package dokuwiki\plugin\struct\meta
20 */
21class InlineConfigParser extends ConfigParser
22{
23    /**
24     * Parser constructor.
25     *
26     * parses the given inline configuration
27     *
28     * @param string $inline
29     */
30    public function __construct($inline)
31    {
32        // Start to build the main config array
33        $lines = array();  // Config lines to pass to full parser
34
35        // Extract components
36        $parts = explode('?', $inline, 2);
37        $n_parts = count($parts);
38        $components = str_getcsv(trim($parts[0]), '.');
39        $n_components = count($components);
40
41        // Extract parameters if given
42        $filtering = false;  // First initialisation of the variable
43        if ($n_parts == 2) {
44            $filtering = false;  // Whether to filter result to current page
45            $parameters = str_getcsv(trim($parts[1]), ' ');
46            $n_parameters = count($parameters);
47
48            // Process parameters and add to config lines
49            for ($i = 0; $i < $n_parameters; $i++) {
50                $p = trim($parameters[$i]);
51                switch ($p) {
52                    // Empty (due to extra spaces)
53                    case '':
54                        // Move straight to next parameter
55                        continue 2;
56                        break;
57                    // Pass full text ending in : straight to config
58                    case $p[-1] == ':' ? $p : '':
59                        if (in_array($p, ['filter', 'where', 'filterand', 'and', 'filteror', 'or'])) {
60                            $filtering = true;
61                        }
62                        $lines[] = $p . ' ' . trim($parameters[$i + 1]);
63                        $i++;
64                        break;
65                    // Short alias for filterand
66                    case '&':
67                        $filtering = true;
68                        $lines[] = 'filterand: ' . trim($parameters[$i + 1]);
69                        $i++;
70                        break;
71                    // Short alias for filteror
72                    case '|':
73                        $filtering = true;
74                        $lines[] = 'filteror: ' . trim($parameters[$i + 1]);
75                        $i++;
76                        break;
77                    default:
78                        // Move straight to next parameter
79                        continue 2;
80                        break;
81                }
82            }
83        }
84
85        // Check whether a page was specified
86        if (count($components) == 3) {
87            // At least page, schema and field supplied
88            $lines[] = 'schema: ' . trim($components[1]);
89            $lines[] = 'field: ' . trim($components[2]);
90            $lines[] = 'filter: %pageid% = ' . trim($components[0]);
91        } elseif (count($components) == 2) {
92            // At least schema and field supplied
93            $lines[] = 'schema: ' . trim($components[0]);
94            $lines[] = 'field: ' . trim($components[1]);
95            if (!$filtering) {
96                $lines[] = 'filter: %pageid% = $ID$';
97            }
98        }
99
100        // Call original ConfigParser's constructor
101        parent::__construct($lines);
102    }
103}
104