3 namespace Org\Mxchange\CoreFramework\Criteria;
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
7 use Org\Mxchange\CoreFramework\Criteria\Search\SearchCriteria;
8 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
9 use Org\Mxchange\CoreFramework\Utils\Strings\StringUtils;
12 use \BadMethodCallException;
13 use \InvalidArgumentException;
14 use \UnexpectedValueException;
17 * A general crtieria class
19 * @author Roland Haeder <webmaster@shipsimu.org>
21 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2022 Core Developer Team
22 * @license GNU GPL 3.0 or any newer version
23 * @link http://www.shipsimu.org
25 * This program is free software: you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation, either version 3 of the License, or
28 * (at your option) any later version.
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public License
36 * along with this program. If not, see <http://www.gnu.org/licenses/>.
38 abstract class BaseCriteria extends BaseFrameworkSystem implements Criteria {
40 * Frontend class name stored in config entry
42 private $frontendConfigEntry = '';
45 * All supported criteria types
47 private static $CRITERIA_TYPES = [];
50 * Protected constructor
52 * @param $className Name of the class
55 protected function __construct (string $className) {
56 // Call parent constructor
57 parent::__construct($className);
59 // Initialize valid criteria types array
60 self::$CRITERIA_TYPES = [Criteria::CRITERIA_TYPE_DEFAULT, Criteria::CRITERIA_TYPE_CHOICE, Criteria::CRITERIA_TYPE_EXCLUDE];
62 // Initialize all criteria arrays
63 foreach (self::$CRITERIA_TYPES as $criteriaType) {
65 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: Initializing criteriaType=%s ...', $criteriaType));
66 $this->initGenericArrayKey('criteria', $criteriaType, 'entries');
71 * Count the criteria, e.g. useful to find out if a database query has no
72 * limitation (search criteria).
74 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
75 * @return $count Count of all criteria entries
76 * @throws InvalidArgumentException If a parameter is not valid
78 protected final function count (string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
80 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaType));
81 if (empty($criteriaType)) {
83 throw new InvalidArgumentException('Parameter "criteriaType" is empty');
84 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
86 throw new InvalidArgumentException(sprintf('criteriaType=%s is not supported', $criteriaType));
89 // Invoke inner method
90 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: Invoking this->countGenericArrayGroup(criteria, %s) ...', strtoupper($criteriaType), $criteriaType));
91 return $this->countGenericArrayGroup('criteria', $criteriaType);
95 * Checks whether given key is set
97 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
98 * @param $criteriaKey Criteria key
99 * @return $isset Whether key is set
100 * @throws InvalidArgumentException If a parameter is not valid
101 * @throws UnexpectedValueException If a parameter contains an unexpected/unsupported value
103 public function isKeySet (string $criteriaType, string $criteriaKey) {
105 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaType=%s,criteriaKey=%s - CALLED!', strtoupper($criteriaType), $criteriaType, $criteriaKey));
106 if (empty($criteriaType)) {
108 throw new InvalidArgumentException('Parameter "criteriaType" is empty');
109 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
111 throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
112 } elseif (empty($criteriaKey)) {
114 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
115 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
117 throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
121 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: Invoking this->isGenericArrayElementSet(criteria,%s,entries,%s) ...', strtoupper($criteriaType), $criteriaType, $criteriaKey));
122 $isset = $this->isGenericArrayElementSet('criteria', $criteriaType, 'entries', $criteriaKey);
125 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: isset=%d - EXIT!', strtoupper($criteriaType), intval($isset)));
130 * Checks whether given key is set for 'choice' type
132 * @param $criteriaKey Criteria key
133 * @return $isset Whether key is set
134 * @throws InvalidArgumentException If a parameter is not valid
136 public function isChoiceKeySet (string $criteriaKey) {
137 // Validate parameter
138 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: criteriaKey=%s - CALLED!', $criteriaKey));
139 if (empty($criteriaKey)) {
141 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
144 // Invoke inner method
145 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: Invoking this->isKeySet(%s,%s) ...', Criteria::CRITERIA_TYPE_CHOICE, $criteriaKey));
146 return $this->isKeySet(Criteria::CRITERIA_TYPE_CHOICE, $criteriaKey);
150 * Checks whether given key is set for 'exclude' type
152 * @param $criteriaKey Criteria key
153 * @return $isset Whether key is set
154 * @throws InvalidArgumentException If a parameter is not valid
156 public function isExcludeKeySet (string $criteriaKey) {
157 // Validate parameter
158 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: criteriaKey=%s - CALLED!', $criteriaKey));
159 if (empty($criteriaKey)) {
161 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
164 // Invoke inner method
165 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: Invoking this->isKeySet(%s,%s) ...', Criteria::CRITERIA_TYPE_EXCLUDE, $criteriaKey));
166 return $this->isKeySet(Criteria::CRITERIA_TYPE_EXCLUDE, $criteriaKey);
170 * Setter for frontend class name
172 * @param $frontendConfigEntry Configuration entry which hold the frontend class' name
175 public final function setFrontendConfigEntry (string $frontendConfigEntry) {
176 $this->frontendConfigEntry = $frontendConfigEntry;
180 * Getter for frontend class name
182 * @return $frontendConfigEntry Configuration entry which hold the frontend class' name
184 public final function getFrontendConfigEntry () {
185 return $this->frontendConfigEntry;
189 * Getter for criteria array
191 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
193 * @throws InvalidArgumentException If a parameter is not valid
194 * @throws UnexpectedValueException If a parameter contains an unexpected/unsupported value
196 public final function getCriteriaArray (string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
198 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaType));
199 if (empty($criteriaType)) {
201 throw new InvalidArgumentException('Parameter "criteriaType" is empty');
202 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
204 throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
207 // Invoke inner method
208 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: Invoking this->getGenericArrayKey(criteria,%s,entries) ...', strtoupper($criteriaType), $criteriaType));
209 return $this->getGenericArrayKey('criteria', $criteriaType, 'entries');
213 * Getter for criteria array 'choice' type
217 public final function getCriteriaChoiceArray () {
218 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: CALLED!', strtoupper($criteriaType)));
219 return $this->getCriteriaArray(Criteria::CRITERIA_TYPE_CHOICE);
223 * Getter for criteria array 'exclude' type
227 public final function getCriteriaExcludeArray () {
228 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: CALLED!', strtoupper($criteriaType)));
229 return $this->getCriteriaArray(Criteria::CRITERIA_TYPE_EXCLUDE);
233 * Unsets a criteria key from all criteria types
235 * @param $criteriaKey Criteria key to unset
238 public final function unsetCriteria (string $criteriaKey) {
240 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: criteriaKey=%s - CALLED!', $criteriaKey));
241 if (empty($criteriaKey)) {
243 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
244 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
246 throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
249 // Convert dashes to underscore
250 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
252 // "Walk" through all criterias
253 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaKey=%s', strtoupper($criteriaType), $criteriaKey));
254 foreach ($this->getGenericArray('criteria') as $criteriaType => $dummy) {
256 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: Removing criteriaType=%s,criteriaKey=%s ...', strtoupper($criteriaType), $criteriaType, $criteriaKey));
257 $this->unsetGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
261 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-CRITERIA: EXIT!');
265 * Add criteria, this method converts dashes to underscores because dashes
266 * are not valid for criteria keys.
268 * @param $criteriaKey Criteria key
269 * @param $criteriaValue Criteria value
270 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
272 * @throws InvalidArgumentException If a parameter is not valid
273 * @throws UnexpectedValueException If a parameter contains an unexpected/unsupported value
275 public final function addCriteria (string $criteriaKey, $criteriaValue, string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
277 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaKey=%s,criteriaValue[]=%s,criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue), $criteriaType));
278 if (empty($criteriaKey)) {
280 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
281 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
283 throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
284 } elseif (is_array($criteriaValue) || is_bool($criteriaValue) || is_object($criteriaValue) || is_resource($criteriaValue)) {
286 throw new InvalidArgumentException(sprintf('value[]=%s is not supported', gettype($criteriaValue)));
287 } elseif (empty($criteriaType)) {
289 throw new InvalidArgumentException('Parameter "criteriaType" is empty');
290 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
292 throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
295 // Convert dashes to underscore
296 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
299 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: Invoking this->setGenericArrayElement(criteria,%s,entries,%s,criteriaValue[]=%s) ...', strtoupper($criteriaType), $criteriaType, $criteriaKey, gettype($criteriaValue)));
300 $this->setGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
303 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: EXIT!', strtoupper($criteriaType)));
307 * Set criteria, this method converts dashes to underscores because dashes
308 * are not valid for criteria keys.
310 * @param $criteriaKey Criteria key
311 * @param $criteriaValue Criteria value
312 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
314 * @throws InvalidArgumentException If a parameter is not valid
315 * @throws UnexpectedValueException If a parameter contains an unexpected/unsupported value
317 public final function setCriteria (string $criteriaKey, $criteriaValue, string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
319 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaKey=%s,criteriaValue[]=%s$criteriaValue,criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue), $criteriaType));
320 if (empty($criteriaKey)) {
322 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
323 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
325 throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
326 } elseif (is_array($criteriaValue) || is_bool($criteriaValue) || is_object($criteriaValue) || is_resource($criteriaValue)) {
328 throw new InvalidArgumentException(sprintf('value[]=%s is not supported', gettype($criteriaValue)));
329 } elseif (empty($criteriaType)) {
331 throw new InvalidArgumentException('Parameter "criteriaType" is empty');
332 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
334 throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
337 // Convert dashes to underscore
338 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
341 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: Invoking this->setGenericArrayElement(criteria,%s,entries,%s,criteriaValue[]=%s) ...', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue)));
342 $this->setGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
345 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-CRITERIA: EXIT!');
349 * Add "choice" criteria, this method converts dashes to underscores because
350 * dashes are not valid for criteria keys.
352 * @param $criteriaKey Criteria key
353 * @param $criteriaValue Criteria value
355 * @throws InvalidArgumentException If a parameter is not valid
356 * @throws UnexpectedValueException If $criteriaValue has an unexpected type
358 public final function addChoiceCriteria (string $criteriaKey, $criteriaValue) {
360 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: criteriaKey=%s,criteriaValue[]=%s - CALLED!', $criteriaKey, gettype($criteriaValue)));
361 if (empty($criteriaKey)) {
363 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
364 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
366 throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
367 } elseif (is_array($criteriaValue) || is_bool($criteriaValue) || is_object($criteriaValue) || is_resource($criteriaValue)) {
369 throw new UnexpectedValueException(sprintf('criteriaValue[]=%s is not accepted', gettype($criteriaValue)));
373 $this->pushValueToGenericArrayElement('criteria', Criteria::CRITERIA_TYPE_CHOICE, 'entries', StringUtils::convertDashesToUnderscores($criteriaKey), (string) $criteriaValue);
376 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-CRITERIA: EXIT!');
380 * Add "exclude" criteria, this method converts dashes to underscores because
381 * dashes are not valid for criteria keys.
383 * @param $criteriaKey Criteria key
384 * @param $criteriaValue Criteria value
386 * @throws InvalidArgumentException If a parameter is not valid
387 * @throws UnexpectedValueException If $criteriaValue has an unexpected type
389 public final function addExcludeCriteria (string $criteriaKey, $criteriaValue) {
391 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: criteriaKey=%s,criteriaValue[%s]=%s - CALLED!', $criteriaKey, gettype($criteriaValue), $criteriaValue));
392 if (empty($criteriaKey)) {
394 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
395 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
397 throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
398 } elseif (is_array($criteriaValue) || is_bool($criteriaValue) || is_object($criteriaValue) || is_resource($criteriaValue)) {
400 throw new UnexpectedValueException(sprintf('criteriaValue[]=%s is not accepted', gettype($criteriaValue)));
403 // Add it with generic method
404 $this->addCriteria($criteriaKey, $criteriaValue, Criteria::CRITERIA_TYPE_EXCLUDE);
407 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-CRITERIA: EXIT!');
411 * Add configured criteria
413 * @param $criteriaKey Criteria key
414 * @param $configEntry Configuration entry
415 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
417 * @throws InvalidArgumentException If a parameter is not valid
418 * @throws UnexpectedValueException If a parameter contains an unexpected/unsupported value
420 public final function addConfiguredCriteria (string $criteriaKey, string $configEntry, string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
422 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaKey=%s,configEntry=%s,criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaKey, $configEntry, $criteriaType));
423 if (empty($criteriaKey)) {
425 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
426 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
428 throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
429 } elseif (empty($configEntry)) {
431 throw new InvalidArgumentException('Parameter "configEntry" is empty');
432 } elseif (empty($criteriaType)) {
434 throw new InvalidArgumentException('Parameter "criteriaType" is empty');
435 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
437 throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
440 // Add the configuration entry as a criteria
441 $value = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry($configEntry);
443 // Invoke inner method
444 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: Invoking this->addCriteria(%s,value[%s]=%s,%s) ...', strtoupper($criteriaType), $criteriaKey, gettype($value), $value, $criteriaType));
445 $this->addCriteria($criteriaKey, $value, $criteriaType);
448 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: EXIT!', strtoupper($criteriaType)));
452 * Get criteria element or false if not found
454 * @param $criteriaKey The requested criteria key
455 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
456 * @return $value Whether the value of the critera or false
457 * @throws InvalidArgumentException If a parameter is not valid
458 * @throws UnexpectedValueException If a parameter contains an unexpected/unsupported value
460 public function getCriteriaElemnent (string $criteriaKey, string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
462 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaKey=%s,criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaKey, $criteriaType));
463 if (empty($criteriaKey)) {
465 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
466 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
468 throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
469 } elseif (empty($criteriaType)) {
471 throw new InvalidArgumentException('Parameter "criteriaType" is empty');
472 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
474 throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
477 // Convert dashes to underscore
478 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
480 // Default is not found
483 // Is the criteria there?
484 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaKey=%s,criteria()=%d', strtoupper($criteriaType), $criteriaKey, $this->countGenericArrayGroup('criteria', $criteriaType)));
485 if ($this->isKeySet($criteriaType, $criteriaKey)) {
487 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: Invoking this->getGenericArrayElement(criteria,%s,entries,%s) ...', strtoupper($criteriaType), $criteriaType, $criteriaKey));
488 $value = $this->getGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
492 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: value[]=%s - EXIT!', strtoupper($criteriaType), gettype($value)));
497 * Get criteria element or false if not found for 'choice' type
499 * @param $criteriaKey The requested criteria key
500 * @return $value Whether the value of the critera or false
501 * @throws InvalidArgumentException If a parameter is not valid
503 public function getCriteriaChoiceElemnent (string $criteriaKey) {
505 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: criteriaKey=%s - CALLED!', $criteriaKey));
506 if (empty($criteriaKey)) {
508 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
509 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
511 throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
514 // Invoke inner method
515 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: Invoking this->getCriteriaElemnent(%s,%s) ...', $criteriaKey, Criteria::CRITERIA_TYPE_CHOICE));
516 return $this->getCriteriaElemnent($criteriaKey, Criteria::CRITERIA_TYPE_CHOICE);
520 * Get criteria element or false if not found for 'exclude' type
522 * @param $criteriaKey The requested criteria key
523 * @return $value Whether the value of the critera or false
524 * @throws InvalidArgumentException If a parameter is not valid
526 public function getCriteriaExcludeElemnent (string $criteriaKey) {
528 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: criteriaKey=%s - CALLED!', $criteriaKey));
529 if (empty($criteriaKey)) {
531 throw new InvalidArgumentException('Parameter "criteriaKey" is empty');
532 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
534 throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
537 // Invoke inner method
538 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: Invoking this->getCriteriaElemnent(%s,%s) ...', $criteriaKey, Criteria::CRITERIA_TYPE_EXCLUDE));
539 return $this->getCriteriaElemnent($criteriaKey, Criteria::CRITERIA_TYPE_EXCLUDE);
543 * Checks whether given array entry matches
545 * @param $entryArray Array with the entries to find
546 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
547 * @return $matches Whether the entry matches or not
548 * @throws InvalidArgumentException If a parameter is not valid
549 * @throws UnexpectedValueException If a parameter contains an unexpected/unsupported value
551 public function ifEntryMatches (array $entryArray, string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
553 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: entryArray()=%d,criteriaType=%s - CALLED!', strtoupper($criteriaType), count($entryArray), $criteriaType));
554 if (count($entryArray) == 0) {
556 throw new InvalidArgumentException('entryArray cannot be an empty array');
557 } elseif (empty($criteriaType)) {
559 throw new InvalidArgumentException('Parameter "criteriaType" is empty');
560 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
562 throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
565 // First nothing matches and nothing is counted
569 // Walk through all entries
570 foreach ($entryArray as $key => $entry) {
571 // Make sure no 'my-' or 'my_' passes this point
572 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: key=%s,entry[%s]=%s', strtoupper($criteriaType), $key, gettype($entry), $entry));
573 if ((strpos($key, 'my-') !== false) || (strpos($key, 'my_') !== false)) {
575 throw new InvalidArgumentException(sprintf('key=%s has illegal prefix "my"', $key));
578 // Convert dashes to underscore
579 $key = StringUtils::convertDashesToUnderscores($key);
581 // Then walk through all search criteria
582 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
583 // Make sure no 'my-' or 'my_' passes this point
584 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaKey=%s,criteriaValue[%s]=%s', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue), $criteriaValue));
585 if ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
587 throw new UnexpectedValueException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
590 // Convert dashes to underscore
591 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
593 // Is the element found and does it match?
594 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
595 // Then count this one up
596 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: MATCHES!', strtoupper($criteriaType)));
602 // Now check if expected criteria counts match
603 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: counted=%d', strtoupper($criteriaType), $counted));
604 $matches = ($counted == $this->countGenericArrayGroup('criteria', $criteriaType));
607 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: matches=%d - EXIT!', strtoupper($criteriaType), intval($matches)));
612 * Checks whether given array 'choice' entry matches
614 * @param $entryArray Array with the entries to find
615 * @return $matches Whether the entry matches or not
616 * @throws InvalidArgumentException If a parameter is not valid
618 public function ifChoiceMatches (array $entryArray) {
620 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: entryArray()=%d - CALLED!', count($entryArray)));
621 if (count($entryArray) == 0) {
623 throw new InvalidArgumentException('entryArray cannot be an empty array');
626 // Invoke inner method
627 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: Invoking this->ifEntryMatches(%d,%s) ...', count($entryArray), Criteria::CRITERIA_TYPE_CHOICE));
628 return $this->ifEntryMatches($entryArray, Criteria::CRITERIA_TYPE_CHOICE);
632 * Checks whether given array 'exclude' entry matches
634 * @param $entryArray Array with the entries to find
635 * @return $matches Whether the entry matches or not
636 * @throws InvalidArgumentException If a parameter is not valid
638 public function ifExcludeMatches (array $entryArray) {
640 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: entryArray()=%d - CALLED!', count($entryArray)));
641 if (count($entryArray) == 0) {
643 throw new InvalidArgumentException('entryArray cannot be an empty array');
646 // Invoke inner method
647 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: Invoking this->ifEntryMatches(%d,%s) ...', count($entryArray), Criteria::CRITERIA_TYPE_EXCLUDE));
648 return $this->ifEntryMatches($entryArray, Criteria::CRITERIA_TYPE_EXCLUDE);
652 * "Getter" for a cache key
654 * @param $onlyKeys Only use these keys for a cache key
655 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
656 * @return $cacheKey The key suitable for the cache system
657 * @throws InvalidArgumentException If a parameter is not valid
658 * @throws UnexpectedValueException If a parameter contains an unexpected/unsupported value
659 * @throws BadMethodCallException If this method is invoked before $criteriaType has been initialized
661 public function getCacheKey (array $onlyKeys = [], string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
663 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: onlyKeys()=%d,criteriaType=%s - CALLED!', strtoupper($criteriaType), count($onlyKeys), $criteriaType));
664 if (empty($criteriaType)) {
666 throw new InvalidArgumentException('Parameter "criteriaType" is empty');
667 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
669 throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
670 } elseif (!$this->isValidGenericArrayGroup('criteria', $criteriaType)) {
671 // Not intialized yet
672 throw new BadMethodCallException(sprintf('Method cannot be invoked before criteriaType=%s is initialized!', $criteriaType));
675 // Initialize the key
678 // Now walk through all criterias
679 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
680 // Make sure no 'my-' or 'my_' passes this point
681 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaKey=%s,criteriaValue[%s]=%s', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue), $criteriaValue));
682 if ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
684 throw new UnexpectedValueException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
685 } elseif (is_array($criteriaValue) || is_bool($criteriaValue) || is_object($criteriaValue) || is_resource($criteriaValue)) {
687 throw new UnexpectedValueException(sprintf('criteriaValue[]=%s is not supported', gettype($criteriaValue)));
690 // Convert dashes to underscore
691 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
693 // Is the value in array or is $onlyKeys empty?
694 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: criteriaKey=%s', strtoupper($criteriaType), $criteriaKey));
695 if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
696 // Add the value URL encoded to avoid any trouble with special characters
697 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: Adding criteriaKey=%s,criteriaValue[%s]=%s to cache key ...', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue), $criteriaValue));
698 $cacheKey .= sprintf('%s=%s;',
700 urlencode($criteriaValue)
705 // Remove last semicolon
706 $cacheKey = substr($cacheKey, 0, -1);
708 // Is the instance SearchCriteria?
709 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: cacheKey=%s,this=%s', strtoupper($criteriaType), $cacheKey, $this->__toString()));
710 if ($this instanceof SearchCriteria) {
711 // Check if 'limit' and 'skip' are in
712 if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
713 // Add limit and skip values
714 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: Adding this->limit=%d,this->skip=%d to cache key ...', strtoupper($criteriaType), $this->getLimit(), $this->getSkip()));
715 $cacheKey .= sprintf(';%%limit%%=%s;%%skip%%=%s',
722 // Return the cache key
723 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-CRITERIA: cacheKey=%s - EXIT!', strtoupper($criteriaType), $cacheKey));
728 * "Getter" for a cache key ('choice' type)
730 * @param $onlyKeys Only use these keys for a cache key
731 * @return $cacheKey The key suitable for the cache system
733 public function getCacheKeyChoice (array $onlyKeys = []) {
735 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: onlyKeys()=%d - CALLED!', count($onlyKeys)));
737 // Invoke inner method
738 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: Invoking this->getCacheKey(onlyKeys()=%d,%s) ...', count($onlyKeys),Criteria::CRITERIA_TYPE_CHOICE));
739 return $this->getCacheKey($onlyKeys, Criteria::CRITERIA_TYPE_CHOICE);
743 * "Getter" for a cache key ('exclude' type)
745 * @param $onlyKeys Only use these keys for a cache key
746 * @return $cacheKey The key suitable for the cache system
748 public function getCacheKeyExclude (array $onlyKeys = []) {
750 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: onlyKeys()=%d - CALLED!', count($onlyKeys)));
752 // Invoke inner method
753 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-CRITERIA: Invoking this->getCacheKey(onlyKeys()=%d,%s) ...', count($onlyKeys),Criteria::CRITERIA_TYPE_EXCLUDE));
754 return $this->getCacheKey($onlyKeys, Criteria::CRITERIA_TYPE_EXCLUDE);
758 * Count 'choice' criteria, e.g. useful to find out if a database query
759 * has no limitation (search criteria).
761 * @return $count Count of all criteria entries
763 public final function countChoice () {
765 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-CRITERIA: CALLED!');
766 return $this->count(Criteria::CRITERIA_TYPE_CHOICE);
770 * Count 'exclude' criteria, e.g. useful to find out if a database query
771 * has no limitation (search criteria).
773 * @return $count Count of all criteria entries
775 public final function countExclude () {
777 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-CRITERIA: CALLED!');
778 return $this->count(Criteria::CRITERIA_TYPE_EXCLUDE);