1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4
5/**
6 * Validate the data for a whole schema
7 *
8 * Should be aquired through AccessDataTable::getValidator()
9 */
10class AccessDataValidator extends ValueValidator
11{
12    /** @var AccessTable */
13    protected $access;
14
15    /** @var array */
16    protected $data;
17
18    /**
19     * ValidationResult constructor.
20     * @param AccessTable $access
21     * @param array $data the data to validate (and save)
22     */
23    public function __construct(AccessTable $access, $data)
24    {
25        parent::__construct();
26        $this->access = $access;
27        $this->data = $data;
28    }
29
30    /**
31     * Validate the given data
32     *
33     * checks for assignments
34     * validates
35     * returns changed data only
36     *
37     * @param array $data array('schema' => ( 'fieldlabel' => 'value', ...))
38     * @param string $pageid
39     * @param string[] $errors validation errors
40     * @return AccessDataValidator[]|bool savable data or false on validation error
41     */
42    public static function validateDataForPage($data, $pageid, &$errors)
43    {
44        $tosave = [];
45        $valid = true;
46        $errors = [];
47
48        $assignments = Assignments::getInstance();
49        $tables = $assignments->getPageAssignments($pageid);
50        foreach ($tables as $table) {
51            $access = AccessTable::getPageAccess($table, $pageid);
52            $validation = $access->getValidator($data[$table]);
53            if (!$validation->validate()) {
54                $valid = false;
55                $errors = array_merge($errors, $validation->getErrors());
56            } elseif ($validation->hasChanges()) {
57                $tosave[] = $validation;
58            }
59        }
60        if ($valid) return $tosave;
61        return false;
62    }
63
64    /**
65     * Validate the data. This will clean the data according to type!
66     *
67     * @return bool
68     */
69    public function validate()
70    {
71        $result = true;
72        foreach ($this->access->getSchema()->getColumns() as $col) {
73            $label = $col->getType()->getLabel();
74            $result = $result && $this->validateValue($col, $this->data[$label]);
75        }
76        return $result;
77    }
78
79    /**
80     * Check if the data changed (selects current data)
81     *
82     * @return bool
83     */
84    public function hasChanges()
85    {
86        $olddata = $this->access->getDataArray();
87        return ($olddata != $this->data);
88    }
89
90    /**
91     * @return AccessTable
92     */
93    public function getAccessTable()
94    {
95        return $this->access;
96    }
97
98    /**
99     * Access the data after it has been cleand in the validation process
100     *
101     * @return array
102     */
103    public function getCleanData()
104    {
105        return $this->data;
106    }
107
108    /**
109     * Saves the data
110     *
111     * This saves no matter what. You have to chcek validation results and changes on your own!
112     *
113     * @param int $ts the timestamp to use when saving the data
114     * @return bool
115     */
116    public function saveData($ts = 0)
117    {
118        $this->access->setTimestamp($ts);
119        return $this->access->saveData($this->data);
120    }
121}
122