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