1<?php 2/* 3** Zabbix 4** Copyright (C) 2001-2021 Zabbix SIA 5** 6** This program is free software; you can redistribute it and/or modify 7** it under the terms of the GNU General Public License as published by 8** the Free Software Foundation; either version 2 of the License, or 9** (at your option) any later version. 10** 11** This program is distributed in the hope that it will be useful, 12** but WITHOUT ANY WARRANTY; without even the implied warranty of 13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14** GNU General Public License for more details. 15** 16** You should have received a copy of the GNU General Public License 17** along with this program; if not, write to the Free Software 18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19**/ 20 21 22class CSchemaValidator extends CValidator { 23 24 /** 25 * Array of required field names. 26 * 27 * @var array 28 */ 29 public $required = []; 30 31 /** 32 * Error message if a required field is missing. 33 * 34 * @var string 35 */ 36 public $messageRequired; 37 38 /** 39 * Error message if an unsupported field is given. 40 * 41 * @var string 42 */ 43 public $messageUnsupported; 44 45 /** 46 * Array of validators where keys are object field names and values are either CValidator objects or nulls. 47 * 48 * If the value is set to null, it will not be validated, but no $messageUnsupported error will be triggered. 49 * 50 * @var array 51 */ 52 protected $validators = []; 53 54 /** 55 * Array of validators to validate the whole object. 56 * 57 * @var array 58 */ 59 protected $postValidators = []; 60 61 public function __construct(array $options = []) { 62 // set validators via the public setter method 63 if (isset($options['validators'])) { 64 foreach ($options['validators'] as $field => $validator) { 65 $this->setValidator($field, $validator); 66 } 67 } 68 unset($options['validator']); 69 70 // set post validators via the public setter method 71 if (isset($options['postValidators'])) { 72 foreach ($options['postValidators'] as $validator) { 73 $this->addPostValidator($validator); 74 } 75 } 76 unset($options['validator']); 77 78 parent::__construct($options); 79 } 80 81 /** 82 * Checks each object field against the given validator, and then the whole object against the post validators. 83 * 84 * @param array $array 85 * 86 * @return bool 87 */ 88 public function validate($array) { 89 $required = array_flip($this->required); 90 $unvalidatedFields = array_flip(array_keys($array)); 91 92 // field validators 93 foreach ($this->validators as $field => $validator) { 94 unset($unvalidatedFields[$field]); 95 96 // if the value is present 97 if (isset($array[$field])) { 98 // validate it if a validator is given, skip it otherwise 99 if ($validator && !$validator->validate($array[$field])) { 100 $this->setError($validator->getError()); 101 102 return false; 103 } 104 } 105 // if no value is given, check if it's required 106 elseif (isset($required[$field])) { 107 $this->error($this->messageRequired, $field); 108 109 return false; 110 } 111 } 112 113 // check if any unsupported fields remain 114 if ($unvalidatedFields) { 115 reset($unvalidatedFields); 116 $field = key($unvalidatedFields); 117 $this->error($this->messageUnsupported, $field); 118 119 return false; 120 } 121 122 // post validators 123 foreach ($this->postValidators as $validator) { 124 if (!$validator->validate($array)) { 125 $this->setError($validator->getError()); 126 127 return false; 128 } 129 } 130 131 return true; 132 } 133 134 /** 135 * Set a validator for a field. 136 * 137 * @param $field 138 * @param CValidator $validator 139 */ 140 public function setValidator($field, CValidator $validator = null) { 141 $this->validators[$field] = $validator; 142 } 143 144 /** 145 * Add a post validator. 146 * 147 * @param CValidator $validator 148 */ 149 public function addPostValidator(CValidator $validator) { 150 $this->postValidators[] = $validator; 151 } 152 153 /** 154 * Set the object name for the current validator and all included validators. 155 * 156 * @param string $name 157 */ 158 public function setObjectName($name) { 159 parent::setObjectName($name); 160 161 foreach ($this->validators as $validator) { 162 if ($validator) { 163 $validator->setObjectName($name); 164 } 165 } 166 167 foreach ($this->postValidators as $validator) { 168 $validator->setObjectName($name); 169 } 170 } 171 172} 173