1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4
5/**
6 * Class Value
7 *
8 * Holds the value for a single "cell". That value may be an array for multi value columns
9 *
10 * @package dokuwiki\plugin\struct\meta
11 */
12class Value
13{
14
15    /** @var Column */
16    protected $column;
17
18    /** @var  array|int|string */
19    protected $value;
20
21    /** @var  array|int|string */
22    protected $rawvalue = null;
23
24    /** @var array|int|string */
25    protected $display = null;
26
27    /** @var array|int|string */
28    protected $compare = null;
29
30    /** @var bool is this a raw value only? */
31    protected $rawonly = false;
32
33    /**
34     * Value constructor.
35     *
36     * @param Column $column
37     * @param array|int|string $value
38     */
39    public function __construct(Column $column, $value)
40    {
41        $this->column = $column;
42        $this->setValue($value);
43    }
44
45    /**
46     * @return Column
47     */
48    public function getColumn()
49    {
50        return $this->column;
51    }
52
53    /**
54     * @return array|int|string
55     */
56    public function getValue()
57    {
58        if ($this->rawonly) {
59            throw new StructException('Accessing value of rawonly value forbidden');
60        }
61        return $this->value;
62    }
63
64    /**
65     * Access the raw value
66     *
67     * @return array|string (array on multi)
68     */
69    public function getRawValue()
70    {
71        return $this->rawvalue;
72    }
73
74    /**
75     * Access the display value
76     *
77     * @return array|string (array on multi)
78     */
79    public function getDisplayValue()
80    {
81        if ($this->rawonly) {
82            throw new StructException('Accessing displayvalue of rawonly value forbidden');
83        }
84        return $this->display;
85    }
86
87    /**
88     * Access the compare value
89     *
90     * @return array|string (array on multi)
91     */
92    public function getCompareValue()
93    {
94        if ($this->rawonly) {
95            throw new StructException('Accessing comparevalue of rawonly value forbidden');
96        }
97        return $this->compare;
98    }
99
100    /**
101     * Allows overwriting the current value
102     *
103     * Cleans the value(s) of empties
104     *
105     * @param array|int|string $value
106     * @param bool $israw is the passed value a raw value? turns Value into rawonly
107     */
108    public function setValue($value, $israw = false)
109    {
110        $this->rawonly = $israw;
111
112        // treat all givens the same
113        if (!is_array($value)) {
114            $value = array($value);
115        }
116
117        // reset/init
118        $this->value = array();
119        $this->rawvalue = array();
120        $this->display = array();
121        $this->compare = array();
122
123        // remove all blanks
124        foreach ($value as $val) {
125            if ($israw) {
126                $raw = $val;
127            } else {
128                $raw = $this->column->getType()->rawValue($val);
129            }
130            if ('' === (string) trim($raw)) continue;
131            $this->value[] = $val;
132            $this->rawvalue[] = $raw;
133            if ($israw) {
134                $this->display[] = $val;
135                $this->compare[] = $val;
136            } else {
137                $this->display[] = $this->column->getType()->displayValue($val);
138                $this->compare[] = $this->column->getType()->compareValue($val);
139            }
140        }
141
142        // make single value again
143        if (!$this->column->isMulti()) {
144            $this->value = (string) array_shift($this->value);
145            $this->rawvalue = (string) array_shift($this->rawvalue);
146            $this->display = (string) array_shift($this->display);
147            $this->compare = (string) array_shift($this->compare);
148        }
149    }
150
151    /**
152     * Is this empty?
153     *
154     * @return bool
155     */
156    public function isEmpty()
157    {
158        return ($this->rawvalue === '' || $this->rawvalue === array());
159    }
160
161    /**
162     * Render the value using the given renderer and mode
163     *
164     * automativally picks the right mechanism depending on multi or single value
165     *
166     * values are only rendered when there is a value
167     *
168     * @param \Doku_Renderer $R
169     * @param string $mode
170     * @return bool
171     */
172    public function render(\Doku_Renderer $R, $mode)
173    {
174        if ($this->column->isMulti()) {
175            if (count($this->value)) {
176                return $this->column->getType()->renderMultiValue($this->value, $R, $mode);
177            }
178        } else {
179            if ($this->value !== '') {
180                return $this->column->getType()->renderValue($this->value, $R, $mode);
181            }
182        }
183        return true;
184    }
185
186    /**
187     * Render this value as a tag-link in a struct cloud
188     *
189     * @param \Doku_Renderer $R
190     * @param string $mode
191     * @param string $page
192     * @param string $filterQuery
193     * @param int $weight
194     */
195    public function renderAsTagCloudLink(\Doku_Renderer $R, $mode, $page, $filterQuery, $weight)
196    {
197        $value = is_array($this->value) ? $this->value[0] : $this->value;
198        $this->column->getType()->renderTagCloudLink($value, $R, $mode, $page, $filterQuery, $weight);
199    }
200
201    /**
202     * Return the value editor for this value field
203     *
204     * @param string $name The field name to use in the editor
205     * @return string The HTML for the editor
206     */
207    public function getValueEditor($name, $id)
208    {
209        if ($this->column->isMulti()) {
210            return $this->column->getType()->multiValueEditor($name, $this->rawvalue, $id);
211        } else {
212            return $this->column->getType()->valueEditor($name, $this->rawvalue, $id);
213        }
214    }
215
216    /**
217     * Filter callback to strip empty values
218     *
219     * @param string $input
220     * @return bool
221     */
222    public function filter($input)
223    {
224        return '' !== ((string) $input);
225    }
226}
227