1 <?php
2
3 /**
4 * The MIT License
5 *
6 * Copyright 2014 George Marques <george at georgemarques.com.br>.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27 namespace Flikore\Validator;
28
29 use Flikore\Validator\Interfaces\IValidator;
30
31 /**
32 * This class can be used as a validation rule in a set to use the fields from the object
33 * being validate as an input to the constructor of a validator. This delegates the proper
34 * construction of the validation until there are an object to validate.
35 *
36 * @author George Marques <george at georgemarques.com.br>
37 * @version 0.5.2
38 * @since 0.4.0
39 * @license http://opensource.org/licenses/MIT MIT
40 * @copyright (c) 2014, George Marques
41 * @package Flikore\Validator
42 */
43 class ValidationValue
44 {
45
46 /**
47 * The validator to build.
48 * @var string The validator to build.
49 */
50 protected $validator;
51
52 /**
53 * The arguments to the validator constructor.
54 * @var array The arguments to the validator constructor.
55 */
56 protected $args;
57
58 /**
59 * A list of fields to fecth from the validated object.
60 * @var array A list of fields to fecth from the validated object.
61 */
62 protected $fields = array();
63
64 /**
65 * The error message to the generated validator.
66 * @var string The error message to the generated validator.
67 */
68 protected $message;
69
70 /**
71 * The key-value pairs to insert in the generated validator.
72 * @var array The key-value pairs to insert in the generated validator.
73 */
74 protected $values = array();
75
76 /**
77 * Creates a new validation value for a validation set.
78 *
79 * @param string|IValidator $validator The validator to build be it a class name (fully qualified)
80 * or a dummy validator object.
81 * @param mixed ...$params The parameters to the validator. To use a field from the validated
82 * object, set these as ValidationKey objects.
83 */
84 public function __construct($validator)
85 {
86 if (is_object($validator))
87 {
88 if (!($validator instanceof IValidator))
89 {
90 throw new \InvalidArgumentException(Intl\GetText::_d('Flikore.Validator', 'The validator object must be a implementation of IValidator'));
91 }
92 else
93 {
94 $this->validator = get_class($validator);
95 }
96 }
97 elseif (is_string($validator))
98 {
99 if (!is_subclass_of($validator, 'Flikore\Validator\Interfaces\IValidator'))
100 {
101 throw new \InvalidArgumentException(Intl\GetText::_d('Flikore.Validator', 'The validator object must be a implementation of IValidator'));
102 }
103 else
104 {
105 $this->validator = $validator;
106 }
107 }
108 else
109 {
110 throw new \InvalidArgumentException(Intl\GetText::_d('Flikore.Validator', 'The validator object must be a implementation of IValidator'));
111 }
112
113 $params = func_get_args();
114 array_shift($params);
115
116 foreach ($params as $arg)
117 {
118 if ($arg instanceof ValidationKey)
119 {
120 $this->fields[] = $arg->getKey();
121 }
122 }
123
124 $this->args = $params;
125 }
126
127 /**
128 * Adds a new key-value pair to be replaced by the templating engine of
129 * the generated validator. This does not check if it's replacing a
130 * specific validator value.
131 *
132 * @param string $key The key to replace (in the template as "%key%")
133 * @param mixed $value The value to be inserted instead of the key.
134 */
135 public function addKeyValue($key, $value)
136 {
137 $this->values[$key] = $value;
138 }
139
140 /**
141 * Sets the error message for the generated validator.
142 * @param string $message The message.
143 */
144 public function setErrorMessage($message)
145 {
146 $this->message = $message;
147 }
148
149 /**
150 * Creates a new concrete validator rule based on the given array.
151 * Such array is created automatically by ValidationSet.
152 *
153 * @param array $fields The key-value fileds
154 * @return Validator The built validator.
155 */
156 public function createRule($fields)
157 {
158 $params = $this->args;
159
160 foreach ($params as $i => $arg)
161 {
162 if ($arg instanceof ValidationKey)
163 {
164 $key = $arg->getKey();
165 if (!isset($fields[$key]))
166 {
167 throw new \OutOfBoundsException(sprintf(Intl\GetText::_d('Flikore.Validator', 'The "%s" key is missing in the input'), $key));
168 }
169 $params[$i] = $fields[$key];
170 }
171 }
172
173 $ref = new \ReflectionClass($this->validator);
174 $rule = $ref->newInstanceArgs($params);
175 if ($this->message)
176 {
177 $rule->setErrorMessage($this->message);
178 }
179 foreach ($this->values as $key => $value)
180 {
181 $rule->addKeyValue($key, $value);
182 }
183 return $rule;
184 }
185
186 /**
187 * Gets the fields needed to construct the delegated validator.
188 *
189 * @return array The list of fields.
190 */
191 public function getFields()
192 {
193 return $this->fields;
194 }
195
196 }
197