Added the zend framework 2 library, the path is specified in line no.26 in zend_modul...
[openemr.git] / interface / modules / zend_modules / library / Zend / InputFilter / BaseInputFilter.php
blob7064c1568119bbd2ae153a7725c96ba680dd6a89
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\InputFilter;
12 use ArrayAccess;
13 use Traversable;
14 use Zend\Stdlib\ArrayUtils;
15 use Zend\Stdlib\InitializableInterface;
17 /**
18 * @todo How should we deal with required input when data is missing?
19 * should a message be returned? if so, what message?
21 class BaseInputFilter implements InputFilterInterface, UnknownInputsCapableInterface, InitializableInterface
23 protected $data;
24 protected $inputs = array();
25 protected $invalidInputs;
26 protected $validationGroup;
27 protected $validInputs;
29 /**
30 * This function is automatically called when creating element with factory. It
31 * allows to perform various operations (add elements...)
33 * @return void
35 public function init()
39 /**
40 * Countable: number of inputs in this input filter
42 * Only details the number of direct children.
44 * @return int
46 public function count()
48 return count($this->inputs);
51 /**
52 * Add an input to the input filter
54 * @param InputInterface|InputFilterInterface $input
55 * @param null|string $name Name used to retrieve this input
56 * @throws Exception\InvalidArgumentException
57 * @return InputFilterInterface
59 public function add($input, $name = null)
61 if (!$input instanceof InputInterface && !$input instanceof InputFilterInterface) {
62 throw new Exception\InvalidArgumentException(sprintf(
63 '%s expects an instance of %s or %s as its first argument; received "%s"',
64 __METHOD__,
65 'Zend\InputFilter\InputInterface',
66 'Zend\InputFilter\InputFilterInterface',
67 (is_object($input) ? get_class($input) : gettype($input))
68 ));
71 if ($input instanceof InputInterface && (empty($name) || is_int($name))) {
72 $name = $input->getName();
75 if (isset($this->inputs[$name]) && $this->inputs[$name] instanceof InputInterface) {
76 // The element already exists, so merge the config. Please note
77 // that this merges the new input into the original.
78 $original = $this->inputs[$name];
79 $original->merge($input);
80 return $this;
83 $this->inputs[$name] = $input;
84 return $this;
87 /**
88 * Retrieve a named input
90 * @param string $name
91 * @throws Exception\InvalidArgumentException
92 * @return InputInterface|InputFilterInterface
94 public function get($name)
96 if (!array_key_exists($name, $this->inputs)) {
97 throw new Exception\InvalidArgumentException(sprintf(
98 '%s: no input found matching "%s"',
99 __METHOD__,
100 $name
103 return $this->inputs[$name];
107 * Test if an input or input filter by the given name is attached
109 * @param string $name
110 * @return bool
112 public function has($name)
114 return (array_key_exists($name, $this->inputs));
118 * Remove a named input
120 * @param string $name
121 * @return InputFilterInterface
123 public function remove($name)
125 unset($this->inputs[$name]);
126 return $this;
130 * Set data to use when validating and filtering
132 * @param array|Traversable $data
133 * @throws Exception\InvalidArgumentException
134 * @return InputFilterInterface
136 public function setData($data)
138 if (!is_array($data) && !$data instanceof Traversable) {
139 throw new Exception\InvalidArgumentException(sprintf(
140 '%s expects an array or Traversable argument; received %s',
141 __METHOD__,
142 (is_object($data) ? get_class($data) : gettype($data))
145 if (is_object($data) && !$data instanceof ArrayAccess) {
146 $data = ArrayUtils::iteratorToArray($data);
148 $this->data = $data;
149 $this->populate();
150 return $this;
154 * Is the data set valid?
156 * @throws Exception\RuntimeException
157 * @return bool
159 public function isValid()
161 $data = $this->getRawValues();
162 if (null === $data) {
163 throw new Exception\RuntimeException(sprintf(
164 '%s: no data present to validate!',
165 __METHOD__
169 $inputs = $this->validationGroup ?: array_keys($this->inputs);
170 return $this->validateInputs($inputs, $data);
174 * Validate a set of inputs against the current data
176 * @param array $inputs
177 * @param array $data
178 * @return bool
180 protected function validateInputs(array $inputs, array $data = array())
182 // backwards compatibility
183 if (empty($data)) {
184 $data = $this->getRawValues();
187 $this->validInputs = array();
188 $this->invalidInputs = array();
189 $valid = true;
191 foreach ($inputs as $name) {
192 $input = $this->inputs[$name];
193 $dataExists = array_key_exists($name, $data);
195 // key doesn't exist, but input is not required; valid
196 if (!$dataExists
197 && $input instanceof InputInterface
198 && !$input->isRequired()
200 $this->validInputs[$name] = $input;
201 continue;
204 // key doesn't exist, input is required, allows empty; valid if
205 // continueIfEmpty is false or input doesn't implement
206 // that interface; otherwise validation chain continues
207 if (!$dataExists
208 && $input instanceof InputInterface
209 && $input->isRequired()
210 && $input->allowEmpty()
212 if(!($input instanceOf EmptyContextInterface && $input->continueIfEmpty())) {
213 $this->validInputs[$name] = $input;
214 continue;
218 // key exists, is null, input is not required; valid
219 if ($dataExists
220 && null === $data[$name]
221 && $input instanceof InputInterface
222 && !$input->isRequired()
224 $this->validInputs[$name] = $input;
225 continue;
228 // key exists, is null, input is required, allows empty; valid if
229 // continueIfEmpty is false or input doesn't implement
230 // that interface; otherwise validation chain continues
231 if ($dataExists
232 && null === $data[$name]
233 && $input instanceof InputInterface
234 && $input->isRequired()
235 && $input->allowEmpty()
237 if (!($input instanceof EmptyContextInterface && $input->continueIfEmpty())) {
238 $this->validInputs[$name] = $input;
239 continue;
243 // key exists, empty string, input is not required, allows empty; valid
244 if ($dataExists
245 && '' === $data[$name]
246 && $input instanceof InputInterface
247 && !$input->isRequired()
248 && $input->allowEmpty()
250 $this->validInputs[$name] = $input;
251 continue;
254 // key exists, empty string, input is required, allows empty; valid
255 // if continueIfEmpty is false, otherwise validation continues
256 if ($dataExists
257 && '' === $data[$name]
258 && $input instanceof InputInterface
259 && $input->isRequired()
260 && $input->allowEmpty()
262 if (!($input instanceof EmptyContextInterface && $input->continueIfEmpty())) {
263 $this->validInputs[$name] = $input;
264 continue;
268 // key exists, is array representing file, no file present, input not
269 // required or allows empty; valid
270 if ($dataExists
271 && is_array($data[$name])
272 && (
273 (isset($data[$name]['error'])
274 && $data[$name]['error'] === UPLOAD_ERR_NO_FILE)
275 || (count($data[$name]) === 1
276 && isset($data[$name][0])
277 && is_array($data[$name][0])
278 && isset($data[$name][0]['error'])
279 && $data[$name][0]['error'] === UPLOAD_ERR_NO_FILE)
281 && $input instanceof InputInterface
282 && (!$input->isRequired() || $input->allowEmpty())
284 $this->validInputs[$name] = $input;
285 continue;
288 // make sure we have a value (empty) for validation
289 if (!$dataExists) {
290 $data[$name] = null;
293 // Validate an input filter
294 if ($input instanceof InputFilterInterface) {
295 if (!$input->isValid()) {
296 $this->invalidInputs[$name] = $input;
297 $valid = false;
298 continue;
300 $this->validInputs[$name] = $input;
301 continue;
304 // Validate an input
305 if ($input instanceof InputInterface) {
306 if (!$input->isValid($data)) {
307 // Validation failure
308 $this->invalidInputs[$name] = $input;
309 $valid = false;
311 if ($input->breakOnFailure()) {
312 return false;
314 continue;
316 $this->validInputs[$name] = $input;
317 continue;
321 return $valid;
325 * Provide a list of one or more elements indicating the complete set to validate
327 * When provided, calls to {@link isValid()} will only validate the provided set.
329 * If the initial value is {@link VALIDATE_ALL}, the current validation group, if
330 * any, should be cleared.
332 * Implementations should allow passing a single array value, or multiple arguments,
333 * each specifying a single input.
335 * @param mixed $name
336 * @return InputFilterInterface
338 public function setValidationGroup($name)
340 if ($name === self::VALIDATE_ALL) {
341 $this->validationGroup = null;
342 return $this;
345 if (is_array($name)) {
346 $inputs = array();
347 foreach ($name as $key => $value) {
348 if (!$this->has($key)) {
349 $inputs[] = $value;
350 } else {
351 $inputs[] = $key;
353 // Recursively populate validation groups for sub input filters
354 $this->inputs[$key]->setValidationGroup($value);
358 if (!empty($inputs)) {
359 $this->validateValidationGroup($inputs);
360 $this->validationGroup = $inputs;
363 return $this;
366 $inputs = func_get_args();
367 $this->validateValidationGroup($inputs);
368 $this->validationGroup = $inputs;
370 return $this;
374 * Return a list of inputs that were invalid.
376 * Implementations should return an associative array of name/input pairs
377 * that failed validation.
379 * @return InputInterface[]
381 public function getInvalidInput()
383 return (is_array($this->invalidInputs) ? $this->invalidInputs : array());
387 * Return a list of inputs that were valid.
389 * Implementations should return an associative array of name/input pairs
390 * that passed validation.
392 * @return InputInterface[]
394 public function getValidInput()
396 return (is_array($this->validInputs) ? $this->validInputs : array());
400 * Retrieve a value from a named input
402 * @param string $name
403 * @throws Exception\InvalidArgumentException
404 * @return mixed
406 public function getValue($name)
408 if (!array_key_exists($name, $this->inputs)) {
409 throw new Exception\InvalidArgumentException(sprintf(
410 '%s expects a valid input name; "%s" was not found in the filter',
411 __METHOD__,
412 $name
415 $input = $this->inputs[$name];
416 return $input->getValue();
420 * Return a list of filtered values
422 * List should be an associative array, with the values filtered. If
423 * validation failed, this should raise an exception.
425 * @return array
427 public function getValues()
429 $inputs = $this->validationGroup ?: array_keys($this->inputs);
430 $values = array();
431 foreach ($inputs as $name) {
432 $input = $this->inputs[$name];
434 if ($input instanceof InputFilterInterface) {
435 $values[$name] = $input->getValues();
436 continue;
438 $values[$name] = $input->getValue();
440 return $values;
444 * Retrieve a raw (unfiltered) value from a named input
446 * @param string $name
447 * @throws Exception\InvalidArgumentException
448 * @return mixed
450 public function getRawValue($name)
452 if (!array_key_exists($name, $this->inputs)) {
453 throw new Exception\InvalidArgumentException(sprintf(
454 '%s expects a valid input name; "%s" was not found in the filter',
455 __METHOD__,
456 $name
459 $input = $this->inputs[$name];
460 return $input->getRawValue();
464 * Return a list of unfiltered values
466 * List should be an associative array of named input/value pairs,
467 * with the values unfiltered.
469 * @return array
471 public function getRawValues()
473 $values = array();
474 foreach ($this->inputs as $name => $input) {
475 if ($input instanceof InputFilterInterface) {
476 $values[$name] = $input->getRawValues();
477 continue;
479 $values[$name] = $input->getRawValue();
481 return $values;
485 * Return a list of validation failure messages
487 * Should return an associative array of named input/message list pairs.
488 * Pairs should only be returned for inputs that failed validation.
490 * @return array
492 public function getMessages()
494 $messages = array();
495 foreach ($this->getInvalidInput() as $name => $input) {
496 $messages[$name] = $input->getMessages();
499 return $messages;
503 * Ensure all names of a validation group exist as input in the filter
505 * @param array $inputs
506 * @return void
507 * @throws Exception\InvalidArgumentException
509 protected function validateValidationGroup(array $inputs)
511 foreach ($inputs as $name) {
512 if (!array_key_exists($name, $this->inputs)) {
513 throw new Exception\InvalidArgumentException(sprintf(
514 'setValidationGroup() expects a list of valid input names; "%s" was not found',
515 $name
522 * Populate the values of all attached inputs
524 * @return void
526 protected function populate()
528 foreach (array_keys($this->inputs) as $name) {
529 $input = $this->inputs[$name];
531 if (!isset($this->data[$name])) {
532 // No value; clear value in this input
533 if ($input instanceof InputFilterInterface) {
534 $input->setData(array());
535 continue;
538 $input->setValue(null);
539 continue;
542 $value = $this->data[$name];
544 if ($input instanceof InputFilterInterface) {
545 $input->setData($value);
546 continue;
549 $input->setValue($value);
554 * Is the data set has unknown input ?
556 * @throws Exception\RuntimeException
557 * @return bool
559 public function hasUnknown()
561 if (null === $this->data) {
562 throw new Exception\RuntimeException(sprintf(
563 '%s: no data present!',
564 __METHOD__
568 $data = array_keys($this->data);
569 $inputs = array_keys($this->inputs);
570 $diff = array_diff($data, $inputs);
571 if (!empty($diff)) {
572 return count(array_intersect($diff, $inputs)) == 0;
575 return false;
579 * Return the unknown input
581 * @throws Exception\RuntimeException
582 * @return array
584 public function getUnknown()
586 if (null === $this->data) {
587 throw new Exception\RuntimeException(sprintf(
588 '%s: no data present!',
589 __METHOD__
593 $data = array_keys($this->data);
594 $inputs = array_keys($this->inputs);
595 $diff = array_diff($data, $inputs);
597 $unknownInputs = array();
598 $intersect = array_intersect($diff, $data);
599 if (!empty($intersect)) {
600 foreach ($intersect as $key) {
601 $unknownInputs[$key] = $this->data[$key];
605 return $unknownInputs;
609 * Get an array of all inputs
611 * @return array
613 public function getInputs()
615 return $this->inputs;