PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 1.5.21
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v1.5.21
2.4.0 2.3.0 2.2.5 2.2.0 2.1.2 2.1.1 trunk 1.10.0 1.10.01 1.10.02 1.5.0 1.5.01 1.5.02 1.5.1 1.5.10 1.5.20 1.5.21 1.5.22 1.5.23 1.5.24 1.5.25 1.6.0 1.7.0 1.7.1 1.7.2 All 33 releases
fluent-booking / vendor / wpfluent / framework / src / WPFluent / Validator / ValidateDatabaseRulesTrait.php

ValidateDatabaseRulesTrait.php in Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution 1.5.21, at vendor/wpfluent/framework/src/WPFluent/Validator/ValidateDatabaseRulesTrait.php

292 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBooking\Framework\Validator;
4
5 use Closure;
6 use FluentBooking\Framework\Support\Str;
7 use FluentBooking\Framework\Foundation\App;
8 use FluentBooking\Framework\Database\Orm\Model;
9 use FluentBooking\Framework\Validator\Rules\Exists;
10 use FluentBooking\Framework\Validator\Rules\Unique;
11
12 trait ValidateDatabaseRulesTrait
13 {
14 /**
15 * Validate the existence of an attribute value in a database table.
16 *
17 * @param string $attribute
18 * @param mixed $value
19 * @param array $parameters
20 * @return bool
21 */
22 public function validateExists($attribute, $value, $parameters)
23 {
24 $this->requireParameterCount(1, $parameters, 'exists');
25
26 [$connection, $table] = $this->parseTable($parameters[0]);
27
28 $column = isset($parameters[1]) ? $parameters[1] : $attribute;
29
30 $expected = is_array($value) ? count(array_unique($value)) : 1;
31
32 return $this->getExistCount(
33 $connection, $table, $column, $value, $parameters
34 ) >= $expected;
35 }
36
37 /**
38 * Parse the connection / table for the unique / exists rules.
39 *
40 * @param string $table
41 * @return array
42 */
43 public function parseTable($table)
44 {
45 [$connection, $table] = Str::contains($table, '.')
46 ? explode('.', $table, 2)
47 : [null, $table];
48
49 if (Str::contains($table, '\\') && class_exists($table) && is_a($table, Model::class, true)) {
50 $model = new $table;
51
52 $table = $model->getTable();
53 $connection = $connection ?: $model->getConnectionName();
54
55 if (Str::contains($table, '.') && Str::startsWith($table, $connection)) {
56 $connection = null;
57 }
58
59 $idColumn = $model->getKeyName();
60 }
61
62 return [$connection, $table, isset($idColumn) ? $idColumn : null];
63 }
64
65 /**
66 * Get the number of records that exist in storage.
67 *
68 * @param mixed $connection
69 * @param string $table
70 * @param string $column
71 * @param mixed $value
72 * @param array $parameters
73 * @return int
74 */
75 protected function getExistCount($connection, $table, $column, $value, $parameters)
76 {
77 $extra = $this->getExtraConditions(
78 array_values(array_slice($parameters, 2))
79 );
80
81 if ($this->currentRule instanceof Exists) {
82 $extra = array_merge($extra, $this->currentRule->queryCallbacks());
83 }
84
85 return is_array($value)
86 ? $this->getMultiCount($table, $column, $value, $extra)
87 : $this->getCount($table, $column, $value, null, null, $extra);
88 }
89
90 /**
91 * Get the extra conditions for a unique / exists rule.
92 *
93 * @param array $segments
94 * @return array
95 */
96 protected function getExtraConditions(array $segments)
97 {
98 $extra = [];
99
100 $count = count($segments);
101
102 for ($i = 0; $i < $count; $i += 2) {
103 $extra[$segments[$i]] = $segments[$i + 1];
104 }
105
106 return $extra;
107 }
108
109 /**
110 * Count the number of objects in a collection having the given value.
111 *
112 * @param string $collection
113 * @param string $column
114 * @param string $value
115 * @param int|null $excludeId
116 * @param string|null $idColumn
117 * @param array $extra
118 * @return int
119 */
120 public function getCount($collection, $column, $value, $excludeId = null, $idColumn = null, array $extra = [])
121 {
122 $query = $this->table($collection)->where($column, '=', $value);
123
124 if (! is_null($excludeId) && $excludeId !== 'NULL') {
125 $query->where($idColumn ?: 'id', '<>', $excludeId);
126 }
127
128 return $this->addConditions($query, $extra)->count();
129 }
130
131 /**
132 * Count the number of objects in a collection with the given values.
133 *
134 * @param string $collection
135 * @param string $column
136 * @param array $values
137 * @param array $extra
138 * @return int
139 */
140 public function getMultiCount($collection, $column, array $values, array $extra = [])
141 {
142 $query = $this->table($collection)->whereIn($column, $values);
143
144 return $this->addConditions($query, $extra)->distinct()->count($column);
145 }
146
147 /**
148 * Add the given conditions to the query.
149 *
150 * @param \Illuminate\Database\Query\Builder $query
151 * @param array $conditions
152 * @return \Illuminate\Database\Query\Builder
153 */
154 protected function addConditions($query, $conditions)
155 {
156 foreach ($conditions as $key => $value) {
157 if ($value instanceof Closure) {
158 $query->where(function ($query) use ($value) {
159 $value($query);
160 });
161 } else {
162 $this->addWhere($query, $key, $value);
163 }
164 }
165
166 return $query;
167 }
168
169 /**
170 * Add a "where" clause to the given query.
171 *
172 * @param \Illuminate\Database\Query\Builder $query
173 * @param string $key
174 * @param string $extraValue
175 * @return void
176 */
177 protected function addWhere($query, $key, $extraValue)
178 {
179 if ($extraValue === 'NULL') {
180 $query->whereNull($key);
181 } elseif ($extraValue === 'NOT_NULL') {
182 $query->whereNotNull($key);
183 } elseif (Str::startsWith($extraValue, '!')) {
184 $query->where($key, '!=', mb_substr($extraValue, 1));
185 } else {
186 $query->where($key, $extraValue);
187 }
188 }
189
190 /**
191 * Get a query builder for the given table.
192 *
193 * @param string $table
194 * @return \Illuminate\Database\Query\Builder
195 */
196 protected function table($table)
197 {
198 return App::make('db')->table($table);
199 }
200
201 /**
202 * Validate the uniqueness of an attribute value on a given database table.
203 *
204 * If a database column is not specified, the attribute will be used.
205 *
206 * @param string $attribute
207 * @param mixed $value
208 * @param array $parameters
209 * @return bool
210 */
211 public function validateUnique($attribute, $value, $parameters)
212 {
213 $this->requireParameterCount(1, $parameters, 'unique');
214
215 [$connection, $table, $idColumn] = $this->parseTable($parameters[0]);
216
217 $column = isset($parameters[1]) ? $parameters[1] : $attribute;
218
219 $id = null;
220
221 if (isset($parameters[2])) {
222 [$idColumn, $id] = $this->getUniqueIds($idColumn, $parameters);
223
224 if (! is_null($id)) {
225 $id = stripslashes($id);
226 }
227 }
228
229 $extra = $this->getUniqueExtra($parameters);
230
231 if ($this->currentRule instanceof Unique) {
232 $extra = array_merge($extra, $this->currentRule->queryCallbacks());
233 }
234
235 return $this->getCount(
236 $table, $column, $value, $id, $idColumn, $extra
237 ) == 0;
238 }
239
240 /**
241 * Get the excluded ID column and value for the unique rule.
242 *
243 * @param string|null $idColumn
244 * @param array $parameters
245 * @return array
246 */
247 protected function getUniqueIds($idColumn, $parameters)
248 {
249 $idColumn = $idColumn ?: ($parameters[3] ?: 'id');
250
251 return [$idColumn, $this->prepareUniqueId($parameters[2])];
252 }
253
254 /**
255 * Prepare the given ID for querying.
256 *
257 * @param mixed $id
258 * @return int
259 */
260 protected function prepareUniqueId($id)
261 {
262 if (preg_match('/\[(.*)\]/', $id, $matches)) {
263 $id = $this->getValue($matches[1]);
264 }
265
266 if (strtolower($id) === 'null') {
267 $id = null;
268 }
269
270 if (filter_var($id, FILTER_VALIDATE_INT) !== false) {
271 $id = (int) $id;
272 }
273
274 return $id;
275 }
276
277 /**
278 * Get the extra conditions for a unique rule.
279 *
280 * @param array $parameters
281 * @return array
282 */
283 protected function getUniqueExtra($parameters)
284 {
285 if (isset($parameters[4])) {
286 return $this->getExtraConditions(array_slice($parameters, 4));
287 }
288
289 return [];
290 }
291 }
292