xref: /plugin/struct/meta/ValueValidator.php (revision 7234bfb14e712ff548d9266ef32fdcc8eaf2d04e)
1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4
5use dokuwiki\plugin\struct\types\AbstractBaseType;
6
7/**
8 * Validator to validate a single value
9 */
10class ValueValidator
11{
12    /** @var  \helper_plugin_struct_db */
13    protected $hlp;
14
15    /** @var  array list of validation errors */
16    protected $errors = [];
17
18    /**
19     * ValueValidator constructor.
20     */
21    public function __construct()
22    {
23        $this->hlp = plugin_load('helper', 'struct_db');
24    }
25
26    /**
27     * Validate a single value
28     *
29     * @param Column $col the column of that value
30     * @param mixed &$rawvalue the value, will be fixed according to the type
31     * @return bool
32     */
33    public function validateValue(Column $col, &$rawvalue)
34    {
35        if ($rawvalue === null) $rawvalue = ''; // no data was passed
36
37        // fix multi value types
38        $type = $col->getType();
39        $trans = $type->getTranslatedLabel();
40        if ($type->isMulti() && !is_array($rawvalue)) {
41            $rawvalue = $type->splitValues($rawvalue);
42        }
43        // strip empty fields from multi vals
44        // but keep at least one so we can properly delete multivalues on update
45        if (is_array($rawvalue) && count($rawvalue) > 1) {
46            $rawvalue = array_filter($rawvalue, [$this, 'filter']);
47            $rawvalue = array_values($rawvalue); // reset the array keys
48        }
49
50        // validate data
51        return $this->validateField($type, $trans, $rawvalue);
52    }
53
54    /**
55     * The errors that occured during validation
56     *
57     * @return string[] already translated error messages
58     */
59    public function getErrors()
60    {
61        return $this->errors;
62    }
63
64    /**
65     * Validate the given data for a single field
66     *
67     * Catches the Validation exceptions and transforms them into proper error messages.
68     *
69     * Blank values are not validated and always pass
70     *
71     * @param AbstractBaseType $type
72     * @param string $label
73     * @param array|string|int &$data may be modified by the validation function
74     * @return bool true if the data validates, otherwise false
75     */
76    protected function validateField(AbstractBaseType $type, $label, &$data)
77    {
78        $prefix = sprintf($this->hlp->getLang('validation_prefix'), $label);
79
80        $ok = true;
81        if (is_array($data)) {
82            foreach ($data as &$value) {
83                if (!blank($value)) {
84                    try {
85                        $value = $type->validate($value);
86                    } catch (ValidationException $e) {
87                        $this->errors[] = $prefix . $e->getMessage();
88                        $ok = false;
89                    }
90                }
91            }
92            return $ok;
93        }
94
95        if (!blank($data)) {
96            try {
97                $data = $type->validate($data);
98            } catch (ValidationException $e) {
99                $this->errors[] = $prefix . $e->getMessage();
100                $ok = false;
101            }
102        }
103        return $ok;
104    }
105
106    /**
107     * Simple filter to remove blank values
108     *
109     * @param string $val
110     * @return bool
111     */
112    public function filter($val)
113    {
114        return !blank($val);
115    }
116}
117