xref: /plugin/struct/meta/ValueValidator.php (revision 5e29103a15bd9873f422f66a6a5239b6aec4651e)
193ca6f4fSAndreas Gohr<?php
293ca6f4fSAndreas Gohr
393ca6f4fSAndreas Gohrnamespace dokuwiki\plugin\struct\meta;
493ca6f4fSAndreas Gohr
593ca6f4fSAndreas Gohruse dokuwiki\plugin\struct\types\AbstractBaseType;
693ca6f4fSAndreas Gohr
793ca6f4fSAndreas Gohr/**
893ca6f4fSAndreas Gohr * Validator to validate a single value
993ca6f4fSAndreas Gohr */
10d6d97f60SAnna Dabrowskaclass ValueValidator
11d6d97f60SAnna Dabrowska{
1293ca6f4fSAndreas Gohr    /** @var  \helper_plugin_struct_db */
1393ca6f4fSAndreas Gohr    protected $hlp;
1493ca6f4fSAndreas Gohr
1593ca6f4fSAndreas Gohr    /** @var  array list of validation errors */
167234bfb1Ssplitbrain    protected $errors = [];
1793ca6f4fSAndreas Gohr
1893ca6f4fSAndreas Gohr    /**
1993ca6f4fSAndreas Gohr     * ValueValidator constructor.
2093ca6f4fSAndreas Gohr     */
21d6d97f60SAnna Dabrowska    public function __construct()
22d6d97f60SAnna Dabrowska    {
2393ca6f4fSAndreas Gohr        $this->hlp = plugin_load('helper', 'struct_db');
2493ca6f4fSAndreas Gohr    }
2593ca6f4fSAndreas Gohr
2693ca6f4fSAndreas Gohr    /**
2793ca6f4fSAndreas Gohr     * Validate a single value
2893ca6f4fSAndreas Gohr     *
2993ca6f4fSAndreas Gohr     * @param Column $col the column of that value
3093ca6f4fSAndreas Gohr     * @param mixed &$rawvalue the value, will be fixed according to the type
3193ca6f4fSAndreas Gohr     * @return bool
3293ca6f4fSAndreas Gohr     */
33d6d97f60SAnna Dabrowska    public function validateValue(Column $col, &$rawvalue)
34d6d97f60SAnna Dabrowska    {
3520292407SAndreas Gohr        if ($rawvalue === null) $rawvalue = ''; // no data was passed
3620292407SAndreas Gohr
3793ca6f4fSAndreas Gohr        // fix multi value types
3893ca6f4fSAndreas Gohr        $type = $col->getType();
3993ca6f4fSAndreas Gohr        $trans = $type->getTranslatedLabel();
4093ca6f4fSAndreas Gohr        if ($type->isMulti() && !is_array($rawvalue)) {
4193ca6f4fSAndreas Gohr            $rawvalue = $type->splitValues($rawvalue);
4293ca6f4fSAndreas Gohr        }
4393ca6f4fSAndreas Gohr        // strip empty fields from multi vals
44d680cb37SAnna Dabrowska        // but keep at least one so we can properly delete multivalues on update
4566055609SAnna Dabrowska        // some fields like media or date can post an array with multiple empty strings
4666055609SAnna Dabrowska        // because they use multiple inputs instead of comma separation in one input
4766055609SAnna Dabrowska        if (is_array($rawvalue)) {
487234bfb1Ssplitbrain            $rawvalue = array_filter($rawvalue, [$this, 'filter']);
4993ca6f4fSAndreas Gohr            $rawvalue = array_values($rawvalue); // reset the array keys
50*5e29103aSannda            if ($rawvalue === []) {
5166055609SAnna Dabrowska                $rawvalue = [''];
5266055609SAnna Dabrowska            }
5393ca6f4fSAndreas Gohr        }
5493ca6f4fSAndreas Gohr
5593ca6f4fSAndreas Gohr        // validate data
5693ca6f4fSAndreas Gohr        return $this->validateField($type, $trans, $rawvalue);
5793ca6f4fSAndreas Gohr    }
5893ca6f4fSAndreas Gohr
5993ca6f4fSAndreas Gohr    /**
6093ca6f4fSAndreas Gohr     * The errors that occured during validation
6193ca6f4fSAndreas Gohr     *
6293ca6f4fSAndreas Gohr     * @return string[] already translated error messages
6393ca6f4fSAndreas Gohr     */
64d6d97f60SAnna Dabrowska    public function getErrors()
65d6d97f60SAnna Dabrowska    {
6693ca6f4fSAndreas Gohr        return $this->errors;
6793ca6f4fSAndreas Gohr    }
6893ca6f4fSAndreas Gohr
6993ca6f4fSAndreas Gohr    /**
7093ca6f4fSAndreas Gohr     * Validate the given data for a single field
7193ca6f4fSAndreas Gohr     *
7293ca6f4fSAndreas Gohr     * Catches the Validation exceptions and transforms them into proper error messages.
7393ca6f4fSAndreas Gohr     *
7493ca6f4fSAndreas Gohr     * Blank values are not validated and always pass
7593ca6f4fSAndreas Gohr     *
7693ca6f4fSAndreas Gohr     * @param AbstractBaseType $type
7793ca6f4fSAndreas Gohr     * @param string $label
7893ca6f4fSAndreas Gohr     * @param array|string|int &$data may be modified by the validation function
7993ca6f4fSAndreas Gohr     * @return bool true if the data validates, otherwise false
8093ca6f4fSAndreas Gohr     */
81d6d97f60SAnna Dabrowska    protected function validateField(AbstractBaseType $type, $label, &$data)
82d6d97f60SAnna Dabrowska    {
8393ca6f4fSAndreas Gohr        $prefix = sprintf($this->hlp->getLang('validation_prefix'), $label);
8493ca6f4fSAndreas Gohr
8593ca6f4fSAndreas Gohr        $ok = true;
8693ca6f4fSAndreas Gohr        if (is_array($data)) {
8793ca6f4fSAndreas Gohr            foreach ($data as &$value) {
8893ca6f4fSAndreas Gohr                if (!blank($value)) {
8993ca6f4fSAndreas Gohr                    try {
9093ca6f4fSAndreas Gohr                        $value = $type->validate($value);
9193ca6f4fSAndreas Gohr                    } catch (ValidationException $e) {
9293ca6f4fSAndreas Gohr                        $this->errors[] = $prefix . $e->getMessage();
9393ca6f4fSAndreas Gohr                        $ok = false;
9493ca6f4fSAndreas Gohr                    }
9593ca6f4fSAndreas Gohr                }
9693ca6f4fSAndreas Gohr            }
9793ca6f4fSAndreas Gohr            return $ok;
9893ca6f4fSAndreas Gohr        }
9993ca6f4fSAndreas Gohr
10093ca6f4fSAndreas Gohr        if (!blank($data)) {
10193ca6f4fSAndreas Gohr            try {
10293ca6f4fSAndreas Gohr                $data = $type->validate($data);
10393ca6f4fSAndreas Gohr            } catch (ValidationException $e) {
10493ca6f4fSAndreas Gohr                $this->errors[] = $prefix . $e->getMessage();
10593ca6f4fSAndreas Gohr                $ok = false;
10693ca6f4fSAndreas Gohr            }
10793ca6f4fSAndreas Gohr        }
10893ca6f4fSAndreas Gohr        return $ok;
10993ca6f4fSAndreas Gohr    }
11093ca6f4fSAndreas Gohr
11193ca6f4fSAndreas Gohr    /**
11293ca6f4fSAndreas Gohr     * Simple filter to remove blank values
11393ca6f4fSAndreas Gohr     *
11493ca6f4fSAndreas Gohr     * @param string $val
11593ca6f4fSAndreas Gohr     * @return bool
11693ca6f4fSAndreas Gohr     */
117d6d97f60SAnna Dabrowska    public function filter($val)
118d6d97f60SAnna Dabrowska    {
11993ca6f4fSAndreas Gohr        return !blank($val);
12093ca6f4fSAndreas Gohr    }
12193ca6f4fSAndreas Gohr}
122