]> git.mxchange.org Git - core.git/blob - framework/main/classes/criteria/class_BaseCriteria.php
Continued:
[core.git] / framework / main / classes / criteria / class_BaseCriteria.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Criteria;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
7 use Org\Mxchange\CoreFramework\Criteria\Search\SearchCriteria;
8 use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
9 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
10 use Org\Mxchange\CoreFramework\Utils\Strings\StringUtils;
11
12 // Import SPL stuff
13 use \BadMethodCallException;
14 use \InvalidArgumentException;
15 use \UnexpectedValueException;
16
17 /**
18  * A general crtieria class
19  *
20  * @author              Roland Haeder <webmaster@shipsimu.org>
21  * @version             0.0.0
22  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
23  * @license             GNU GPL 3.0 or any newer version
24  * @link                http://www.shipsimu.org
25  *
26  * This program is free software: you can redistribute it and/or modify
27  * it under the terms of the GNU General Public License as published by
28  * the Free Software Foundation, either version 3 of the License, or
29  * (at your option) any later version.
30  *
31  * This program is distributed in the hope that it will be useful,
32  * but WITHOUT ANY WARRANTY; without even the implied warranty of
33  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34  * GNU General Public License for more details.
35  *
36  * You should have received a copy of the GNU General Public License
37  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
38  */
39 abstract class BaseCriteria extends BaseFrameworkSystem implements Criteria {
40         /**
41          * Frontend class name stored in config entry
42          */
43         private $frontendConfigEntry = '';
44
45         /**
46          * All supported criteria types
47          */
48         private static $CRITERIA_TYPES = [];
49
50         /**
51          * Protected constructor
52          *
53          * @param       $className      Name of the class
54          * @return      void
55          */
56         protected function __construct (string $className) {
57                 // Call parent constructor
58                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: className=%s - CONSTRUCTED!', $className));
59                 parent::__construct($className);
60
61                 // Initialize valid criteria types array
62                 self::$CRITERIA_TYPES = [Criteria::CRITERIA_TYPE_DEFAULT, Criteria::CRITERIA_TYPE_CHOICE, Criteria::CRITERIA_TYPE_EXCLUDE];
63
64                 // Initialize all criteria arrays
65                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-CRITERIA: self::CRITERIA_TYPES()=%d', count(self::$CRITERIA_TYPES)));
66                 foreach (self::$CRITERIA_TYPES as $criteriaType) {
67                         // Init it
68                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->initGenericArrayKey(criteria,%s,entries) ...', $criteriaType));
69                         $this->initGenericArrayKey('criteria', $criteriaType, 'entries');
70                 }
71
72                 // Trace message
73                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CRITERIA: EXIT!');
74         }
75
76         /**
77          * Count the criteria, e.g. useful to find out if a database query has no
78          * limitation (search criteria).
79          *
80          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
81          * @return      $count  Count of all criteria entries
82          * @throws      InvalidArgumentException        If a parameter is not valid
83          */
84         protected final function count (string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
85                 // Check parameter
86                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaType));
87                 if (empty($criteriaType)) {
88                         // Throw it again
89                         throw new InvalidArgumentException('Parameter "criteriaType" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
90                 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
91                         // Throw it again
92                         throw new InvalidArgumentException(sprintf('criteriaType=%s is not supported', $criteriaType));
93                 }
94
95                 // Invoke inner method
96                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking this->countGenericArrayGroup(criteria, %s) ... - EXIT!', strtoupper($criteriaType), $criteriaType));
97                 return $this->countGenericArrayGroup('criteria', $criteriaType);
98         }
99
100         /**
101          * Checks whether given key is set
102          *
103          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
104          * @param       $criteriaKey    Criteria key
105          * @return      $isset                  Whether key is set
106          * @throws      InvalidArgumentException        If a parameter is not valid
107          * @throws      UnexpectedValueException        If a parameter contains an unexpected/unsupported value
108          */
109         public function isKeySet (string $criteriaType, string $criteriaKey) {
110                 // Check parameters
111                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: criteriaType=%s,criteriaKey=%s - CALLED!', strtoupper($criteriaType), $criteriaType, $criteriaKey));
112                 if (empty($criteriaType)) {
113                         // Throw it again
114                         throw new InvalidArgumentException('Parameter "criteriaType" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
115                 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
116                         // Throw it again
117                         throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
118                 } elseif (empty($criteriaKey)) {
119                         // Throw it again
120                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
121                 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
122                         // Throw it again
123                         throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
124                 }
125
126                 // Determine it
127                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: Invoking this->isGenericArrayElementSet(criteria,%s,entries,%s) ...', strtoupper($criteriaType), $criteriaType, $criteriaKey));
128                 $isset = $this->isGenericArrayElementSet('criteria', $criteriaType, 'entries', $criteriaKey);
129
130                 // Return it
131                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: isset=%d - EXIT!', strtoupper($criteriaType), intval($isset)));
132                 return $isset;
133         }
134
135         /**
136          * Checks whether given key is set for 'choice' type
137          *
138          * @param       $criteriaKey    Criteria key
139          * @return      $isset                  Whether key is set
140          * @throws      InvalidArgumentException        If a parameter is not valid
141          */
142         public function isChoiceKeySet (string $criteriaKey) {
143                 // Validate parameter
144                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: criteriaKey=%s - CALLED!', $criteriaKey));
145                 if (empty($criteriaKey)) {
146                         // Throw it again
147                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
148                 }
149
150                 // Invoke inner method
151                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->isKeySet(%s,%s) ...', Criteria::CRITERIA_TYPE_CHOICE, $criteriaKey));
152                 return $this->isKeySet(Criteria::CRITERIA_TYPE_CHOICE, $criteriaKey);
153         }
154
155         /**
156          * Checks whether given key is set for 'exclude' type
157          *
158          * @param       $criteriaKey    Criteria key
159          * @return      $isset                  Whether key is set
160          * @throws      InvalidArgumentException        If a parameter is not valid
161          */
162         public function isExcludeKeySet (string $criteriaKey) {
163                 // Validate parameter
164                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: criteriaKey=%s - CALLED!', $criteriaKey));
165                 if (empty($criteriaKey)) {
166                         // Throw it again
167                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
168                 }
169
170                 // Invoke inner method
171                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->isKeySet(%s,%s) ... - EXIT!', Criteria::CRITERIA_TYPE_EXCLUDE, $criteriaKey));
172                 return $this->isKeySet(Criteria::CRITERIA_TYPE_EXCLUDE, $criteriaKey);
173         }
174
175         /**
176          * Setter for frontend class name
177          *
178          * @param       $frontendConfigEntry            Configuration entry which hold the frontend class' name
179          * @return      void
180          */
181         public final function setFrontendConfigEntry (string $frontendConfigEntry) {
182                 $this->frontendConfigEntry = $frontendConfigEntry;
183         }
184
185         /**
186          * Getter for frontend class name
187          *
188          * @return      $frontendConfigEntry            Configuration entry which hold the frontend class' name
189          */
190         public final function getFrontendConfigEntry () {
191                 return $this->frontendConfigEntry;
192         }
193
194         /**
195          * Getter for criteria array
196          *
197          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
198          * @return      $criteria
199          * @throws      InvalidArgumentException        If a parameter is not valid
200          * @throws      UnexpectedValueException        If a parameter contains an unexpected/unsupported value
201          */
202         public final function getCriteriaArray (string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
203                 // Check parameters
204                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaType));
205                 if (empty($criteriaType)) {
206                         // Throw it again
207                         throw new InvalidArgumentException('Parameter "criteriaType" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
208                 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
209                         // Throw it again
210                         throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
211                 }
212
213                 // Invoke inner method
214                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking this->getGenericArrayKey(criteria,%s,entries) ... - EXIT!', strtoupper($criteriaType), $criteriaType));
215                 return $this->getGenericArrayKey('criteria', $criteriaType, 'entries');
216         }
217
218         /**
219          * Getter for criteria array 'choice' type
220          *
221          * @return      $criteria
222          */
223         public final function getCriteriaChoiceArray () {
224                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: CALLED!', strtoupper($criteriaType)));
225                 return $this->getCriteriaArray(Criteria::CRITERIA_TYPE_CHOICE);
226         }
227
228         /**
229          * Getter for criteria array 'exclude' type
230          *
231          * @return      $criteria
232          */
233         public final function getCriteriaExcludeArray () {
234                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CRITERIA: CALLED!');
235                 return $this->getCriteriaArray(Criteria::CRITERIA_TYPE_EXCLUDE);
236         }
237
238         /**
239          * Unsets a criteria key from all criteria types
240          *
241          * @param       $criteriaKey    Criteria key to unset
242          * @return      void
243          */
244         public final function unsetCriteria (string $criteriaKey) {
245                 // Check parameter
246                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: criteriaKey=%s - CALLED!', $criteriaKey));
247                 if (empty($criteriaKey)) {
248                         // Throw it again
249                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
250                 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
251                         // Throw it again
252                         throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
253                 }
254
255                 // Convert dashes to underscore
256                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking StringUtils::convertDashesToUnderscores(%s) ...', strtoupper($criteriaType), $criteriaKey));
257                 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
258
259                 // "Walk" through all criterias
260                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: criteriaKey=%s', strtoupper($criteriaType), $criteriaKey));
261                 foreach ($this->getGenericArray('criteria') as $criteriaType => $dummy) {
262                         // Remove it
263                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Removing criteriaType=%s,criteriaKey=%s ...', strtoupper($criteriaType), $criteriaType, $criteriaKey));
264                         $this->unsetGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
265                 }
266
267                 // Trace message
268                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CRITERIA: EXIT!');
269         }
270
271         /**
272          * Add criteria, this method converts dashes to underscores because dashes
273          * are not valid for criteria keys.
274          *
275          * @param       $criteriaKey    Criteria key
276          * @param       $criteriaValue  Criteria value
277          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
278          * @return      void
279          * @throws      InvalidArgumentException        If a parameter is not valid
280          * @throws      UnexpectedValueException        If a parameter contains an unexpected/unsupported value
281          */
282         public final function addCriteria (string $criteriaKey, $criteriaValue, string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
283                 // Check parameter
284                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: criteriaKey=%s,criteriaValue[]=%s,criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue), $criteriaType));
285                 if (empty($criteriaKey)) {
286                         // Throw IAE
287                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
288                 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
289                         // Throw it again
290                         throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
291                 } elseif (is_array($criteriaValue) || is_bool($criteriaValue) || is_object($criteriaValue) || is_resource($criteriaValue)) {
292                         // Throw it again
293                         throw new InvalidArgumentException(sprintf('value[]=%s is not supported', gettype($criteriaValue)));
294                 } elseif (empty($criteriaType)) {
295                         // Throw it again
296                         throw new InvalidArgumentException('Parameter "criteriaType" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
297                 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
298                         // Throw it again
299                         throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
300                 }
301
302                 // Convert dashes to underscore
303                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking StringUtils::convertDashesToUnderscores(%s) ...', strtoupper($criteriaType), $criteriaKey));
304                 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
305
306                 // Set it
307                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking this->setGenericArrayElement(criteria,%s,entries,%s,criteriaValue[]=%s) ...', strtoupper($criteriaType), $criteriaType, $criteriaKey, gettype($criteriaValue)));
308                 $this->setGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
309
310                 // Trace message
311                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: EXIT!', strtoupper($criteriaType)));
312         }
313
314         /**
315          * Set criteria, this method converts dashes to underscores because dashes
316          * are not valid for criteria keys.
317          *
318          * @param       $criteriaKey    Criteria key
319          * @param       $criteriaValue  Criteria value
320          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
321          * @return      void
322          * @throws      InvalidArgumentException        If a parameter is not valid
323          * @throws      UnexpectedValueException        If a parameter contains an unexpected/unsupported value
324          */
325         public final function setCriteria (string $criteriaKey, $criteriaValue, string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
326                 // Check parameter
327                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: criteriaKey=%s,criteriaValue[]=%s$criteriaValue,criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue), $criteriaType));
328                 if (empty($criteriaKey)) {
329                         // Throw IAE
330                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
331                 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
332                         // Throw it again
333                         throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
334                 } elseif (is_array($criteriaValue) || is_bool($criteriaValue) || is_object($criteriaValue) || is_resource($criteriaValue)) {
335                         // Throw it again
336                         throw new InvalidArgumentException(sprintf('value[]=%s is not supported', gettype($criteriaValue)));
337                 } elseif (empty($criteriaType)) {
338                         // Throw it again
339                         throw new InvalidArgumentException('Parameter "criteriaType" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
340                 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
341                         // Throw it again
342                         throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
343                 }
344
345                 // Convert dashes to underscore
346                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking StringUtils::convertDashesToUnderscores(%s) ...', strtoupper($criteriaType), $criteriaKey));
347                 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
348
349                 // Set it
350                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking this->setGenericArrayElement(criteria,%s,entries,%s,criteriaValue[]=%s) ...', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue)));
351                 $this->setGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
352
353                 // Trace message
354                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CRITERIA: EXIT!');
355         }
356
357         /**
358          * Add "choice" criteria, this method converts dashes to underscores because
359          * dashes are not valid for criteria keys.
360          *
361          * @param       $criteriaKey    Criteria key
362          * @param       $criteriaValue  Criteria value
363          * @return      void
364          * @throws      InvalidArgumentException        If a parameter is not valid
365          * @throws      UnexpectedValueException        If $criteriaValue has an unexpected type
366          */
367         public final function addChoiceCriteria (string $criteriaKey, $criteriaValue) {
368                 // Check parameter
369                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: criteriaKey=%s,criteriaValue[]=%s - CALLED!', $criteriaKey, gettype($criteriaValue)));
370                 if (empty($criteriaKey)) {
371                         // Throw IAE
372                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
373                 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
374                         // Throw it again
375                         throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
376                 } elseif (is_array($criteriaValue) || is_bool($criteriaValue) || is_object($criteriaValue) || is_resource($criteriaValue)) {
377                         // Throw UAE
378                         throw new UnexpectedValueException(sprintf('criteriaValue[]=%s is not accepted', gettype($criteriaValue)));
379                 }
380
381                 // Convert dashes to underscore
382                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking StringUtils::convertDashesToUnderscores(%s) ...', $criteriaKey));
383                 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
384
385                 // Add it
386                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->pushValueToGenericArrayElement(criteria,%s,entries,%s,criteriaValue[]=%s) ...', Criteria::CRITERIA_TYPE_CHOICE, $criteriaKey, gettype($criteriaValue)));
387                 $this->pushValueToGenericArrayElement('criteria', Criteria::CRITERIA_TYPE_CHOICE, 'entries', $criteriaKey, $criteriaValue);
388
389                 // Trace message
390                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CRITERIA: EXIT!');
391         }
392
393         /**
394          * Add "exclude" criteria, this method converts dashes to underscores because
395          * dashes are not valid for criteria keys.
396          *
397          * @param       $criteriaKey    Criteria key
398          * @param       $criteriaValue  Criteria value
399          * @return      void
400          * @throws      InvalidArgumentException        If a parameter is not valid
401          * @throws      UnexpectedValueException        If $criteriaValue has an unexpected type
402          */
403         public final function addExcludeCriteria (string $criteriaKey, $criteriaValue) {
404                 // Check parameter
405                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: criteriaKey=%s,criteriaValue[%s]=%s - CALLED!', $criteriaKey, gettype($criteriaValue), $criteriaValue));
406                 if (empty($criteriaKey)) {
407                         // Throw IAE
408                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
409                 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
410                         // Throw it again
411                         throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
412                 } elseif (is_array($criteriaValue) || is_bool($criteriaValue) || is_object($criteriaValue) || is_resource($criteriaValue)) {
413                         // Throw UAE
414                         throw new UnexpectedValueException(sprintf('criteriaValue[]=%s is not accepted', gettype($criteriaValue)));
415                 }
416
417                 // Add it with generic method
418                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->addCriteria(%s,criteriaValue[]=%s,%s) ...', $criteriaKey, gettype($criteriaValue), Criteria::CRITERIA_TYPE_EXCLUDE));
419                 $this->addCriteria($criteriaKey, $criteriaValue, Criteria::CRITERIA_TYPE_EXCLUDE);
420
421                 // Trace message
422                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CRITERIA: EXIT!');
423         }
424
425         /**
426          * Add configured criteria
427          *
428          * @param       $criteriaKey    Criteria key
429          * @param       $configEntry    Configuration entry
430          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
431          * @return      void
432          * @throws      InvalidArgumentException        If a parameter is not valid
433          * @throws      UnexpectedValueException        If a parameter contains an unexpected/unsupported value
434          */
435         public final function addConfiguredCriteria (string $criteriaKey, string $configEntry, string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
436                 // Check parameter
437                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: criteriaKey=%s,configEntry=%s,criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaKey, $configEntry, $criteriaType));
438                 if (empty($criteriaKey)) {
439                         // Throw IAE
440                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
441                 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
442                         // Throw it again
443                         throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
444                 } elseif (empty($configEntry)) {
445                         // Throw it again
446                         throw new InvalidArgumentException('Parameter "configEntry" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
447                 } elseif (empty($criteriaType)) {
448                         // Throw it again
449                         throw new InvalidArgumentException('Parameter "criteriaType" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
450                 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
451                         // Throw it again
452                         throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
453                 }
454
455                 // Add the configuration entry as a criteria
456                 $value = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry($configEntry);
457
458                 // Invoke inner method
459                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking this->addCriteria(%s,value[%s]=%s,%s) ...', strtoupper($criteriaType), $criteriaKey, gettype($value), $value, $criteriaType));
460                 $this->addCriteria($criteriaKey, $value, $criteriaType);
461
462                 // Trace message
463                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: EXIT!', strtoupper($criteriaType)));
464         }
465
466         /**
467          * Get criteria element or false if not found
468          *
469          * @param       $criteriaKey    The requested criteria key
470          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
471          * @return      $value                  Whether the value of the critera or false
472          * @throws      InvalidArgumentException        If a parameter is not valid
473          * @throws      UnexpectedValueException        If a parameter contains an unexpected/unsupported value
474          */
475         public function getCriteriaElemnent (string $criteriaKey, string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
476                 // Check parameter
477                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: criteriaKey=%s,criteriaType=%s - CALLED!', strtoupper($criteriaType), $criteriaKey, $criteriaType));
478                 if (empty($criteriaKey)) {
479                         // Throw IAE
480                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
481                 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
482                         // Throw it again
483                         throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
484                 } elseif (empty($criteriaType)) {
485                         // Throw it again
486                         throw new InvalidArgumentException('Parameter "criteriaType" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
487                 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
488                         // Throw it again
489                         throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
490                 }
491
492                 // Convert dashes to underscore
493                 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
494
495                 // Default is not found
496                 $value = false;
497
498                 // Is the criteria there?
499                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: criteriaKey=%s,criteria()=%d', strtoupper($criteriaType), $criteriaKey, $this->countGenericArrayGroup('criteria', $criteriaType)));
500                 if ($this->isKeySet($criteriaType, $criteriaKey)) {
501                         // Then use it
502                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking this->getGenericArrayElement(criteria,%s,entries,%s) ...', strtoupper($criteriaType), $criteriaType, $criteriaKey));
503                         $value = $this->getGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
504                 }
505
506                 // Return the value
507                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: value[]=%s - EXIT!', strtoupper($criteriaType), gettype($value)));
508                 return $value;
509         }
510
511         /**
512          * Get criteria element or false if not found for 'choice' type
513          *
514          * @param       $criteriaKey    The requested criteria key
515          * @return      $value                  Whether the value of the critera or false
516          * @throws      InvalidArgumentException        If a parameter is not valid
517          */
518         public function getCriteriaChoiceElemnent (string $criteriaKey) {
519                 // Check parameter
520                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: criteriaKey=%s - CALLED!', $criteriaKey));
521                 if (empty($criteriaKey)) {
522                         // Throw IAE
523                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
524                 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
525                         // Throw it again
526                         throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
527                 }
528
529                 // Invoke inner method
530                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->getCriteriaElemnent(%s,%s) ...', $criteriaKey, Criteria::CRITERIA_TYPE_CHOICE));
531                 return $this->getCriteriaElemnent($criteriaKey, Criteria::CRITERIA_TYPE_CHOICE);
532         }
533
534         /**
535          * Get criteria element or false if not found for 'exclude' type
536          *
537          * @param       $criteriaKey    The requested criteria key
538          * @return      $value                  Whether the value of the critera or false
539          * @throws      InvalidArgumentException        If a parameter is not valid
540          */
541         public function getCriteriaExcludeElemnent (string $criteriaKey) {
542                 // Check parameter
543                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: criteriaKey=%s - CALLED!', $criteriaKey));
544                 if (empty($criteriaKey)) {
545                         // Throw IAE
546                         throw new InvalidArgumentException('Parameter "criteriaKey" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
547                 } elseif ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
548                         // Throw it again
549                         throw new InvalidArgumentException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
550                 }
551
552                 // Invoke inner method
553                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->getCriteriaElemnent(%s,%s) ...', $criteriaKey, Criteria::CRITERIA_TYPE_EXCLUDE));
554                 return $this->getCriteriaElemnent($criteriaKey, Criteria::CRITERIA_TYPE_EXCLUDE);
555         }
556
557         /**
558          * Checks whether given array entry matches
559          *
560          * @param       $entryArray             Array with the entries to find
561          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
562          * @return      $matches                Whether the entry matches or not
563          * @throws      InvalidArgumentException        If a parameter is not valid
564          * @throws      UnexpectedValueException        If a parameter contains an unexpected/unsupported value
565          */
566         public function ifEntryMatches (array $entryArray, string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
567                 // Check parameters
568                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: entryArray()=%d,criteriaType=%s - CALLED!', strtoupper($criteriaType), count($entryArray), $criteriaType));
569                 if (count($entryArray) == 0) {
570                         // Throw IAE
571                         throw new InvalidArgumentException('entryArray cannot be an empty array');
572                 } elseif (empty($criteriaType)) {
573                         // Throw it again
574                         throw new InvalidArgumentException('Parameter "criteriaType" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
575                 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
576                         // Throw it again
577                         throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
578                 }
579
580                 // First nothing matches and nothing is counted
581                 $matches = false;
582                 $counted = 0;
583
584                 // Walk through all entries
585                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: Walking over entryArray()=%d ...', strtoupper($criteriaType), count($entryArray)));
586                 foreach ($entryArray as $key => $entry) {
587                         // Make sure no 'my-' or 'my_' passes this point
588                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: key=%s,entry[%s]=%s', strtoupper($criteriaType), $key, gettype($entry), $entry));
589                         if ((strpos($key, 'my-') !== false) || (strpos($key, 'my_') !== false)) {
590                                 // Throw it again
591                                 throw new InvalidArgumentException(sprintf('key=%s has illegal prefix "my"', $key));
592                         }
593
594                         // Convert dashes to underscore
595                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking StringUtils::convertDashesToUnderscores(%s) ...', strtoupper($criteriaType), $key));
596                         $key = StringUtils::convertDashesToUnderscores($key);
597
598                         // Then walk through all search criteria
599                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: key=%s - AFTER!', strtoupper($criteriaType), $key));
600                         foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
601                                 // Make sure no 'my-' or 'my_' passes this point
602                                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: criteriaKey=%s,criteriaValue[%s]=%s', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue), $criteriaValue));
603                                 if ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
604                                         // Throw it again
605                                         throw new UnexpectedValueException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
606                                 }
607
608                                 // Convert dashes to underscore
609                                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking StringUtils::convertDashesToUnderscores(%s) ...', strtoupper($criteriaType), $criteriaKey));
610                                 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
611
612                                 // Is the element found and does it match?
613                                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: key=%s,criteriaKey=%s', strtoupper($criteriaType), $key, $criteriaKey));
614                                 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
615                                         // Then count this one up
616                                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: MATCHES!', strtoupper($criteriaType)));
617                                         $counted++;
618                                 }
619                         }
620                 }
621
622                 // Now check if expected criteria counts match
623                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: counted=%d', strtoupper($criteriaType), $counted));
624                 $matches = ($counted == $this->countGenericArrayGroup('criteria', $criteriaType));
625
626                 // Return the result
627                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: matches=%d - EXIT!', strtoupper($criteriaType), intval($matches)));
628                 return $matches;
629         }
630
631         /**
632          * Checks whether given array 'choice' entry matches
633          *
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
637          */
638         public function ifChoiceMatches (array $entryArray) {
639                 // Check parameter
640                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: entryArray()=%d - CALLED!', count($entryArray)));
641                 if (count($entryArray) == 0) {
642                         // Throw IAE
643                         throw new InvalidArgumentException('entryArray cannot be an empty array');
644                 }
645
646                 // Invoke inner method
647                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->ifEntryMatches(%d,%s) ...', count($entryArray), Criteria::CRITERIA_TYPE_CHOICE));
648                 return $this->ifEntryMatches($entryArray, Criteria::CRITERIA_TYPE_CHOICE);
649         }
650
651         /**
652          * Checks whether given array 'exclude' entry matches
653          *
654          * @param       $entryArray             Array with the entries to find
655          * @return      $matches                Whether the entry matches or not
656          * @throws      InvalidArgumentException        If a parameter is not valid
657          */
658         public function ifExcludeMatches (array $entryArray) {
659                 // Check parameter
660                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: entryArray()=%d - CALLED!', count($entryArray)));
661                 if (count($entryArray) == 0) {
662                         // Throw IAE
663                         throw new InvalidArgumentException('entryArray cannot be an empty array');
664                 }
665
666                 // Invoke inner method
667                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->ifEntryMatches(%d,%s) ...', count($entryArray), Criteria::CRITERIA_TYPE_EXCLUDE));
668                 return $this->ifEntryMatches($entryArray, Criteria::CRITERIA_TYPE_EXCLUDE);
669         }
670
671         /**
672          * "Getter" for a cache key
673          *
674          * @param       $onlyKeys       Only use these keys for a cache key
675          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
676          * @return      $cacheKey       The key suitable for the cache system
677          * @throws      InvalidArgumentException        If a parameter is not valid
678          * @throws      UnexpectedValueException        If a parameter contains an unexpected/unsupported value
679          * @throws      BadMethodCallException  If this method is invoked before $criteriaType has been initialized
680          */
681         public function getCacheKey (array $onlyKeys = [], string $criteriaType = Criteria::CRITERIA_TYPE_DEFAULT) {
682                 // Check parameters
683                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: onlyKeys()=%d,criteriaType=%s - CALLED!', strtoupper($criteriaType), count($onlyKeys), $criteriaType));
684                 if (empty($criteriaType)) {
685                         // Throw it again
686                         throw new InvalidArgumentException('Parameter "criteriaType" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
687                 } elseif (!in_array($criteriaType, self::$CRITERIA_TYPES)) {
688                         // Throw it again
689                         throw new UnexpectedValueException(sprintf('criteriaType=%s is not supported', $criteriaType));
690                 } elseif (!$this->isValidGenericArrayGroup('criteria', $criteriaType)) {
691                         // Not intialized yet
692                         throw new BadMethodCallException(sprintf('Method cannot be invoked before criteriaType=%s is initialized!', $criteriaType), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
693                 }
694
695                 // Initialize the key
696                 $cacheKey = '';
697
698                 // Now walk through all criterias
699                 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
700                         // Make sure no 'my-' or 'my_' passes this point
701                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: criteriaKey=%s,criteriaValue[%s]=%s', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue), $criteriaValue));
702                         if ((strpos($criteriaKey, 'my-') !== false) || (strpos($criteriaKey, 'my_') !== false)) {
703                                 // Throw UAE
704                                 throw new UnexpectedValueException(sprintf('criteriaKey=%s has illegal prefix "my"', $criteriaKey));
705                         } elseif (is_array($criteriaValue) || is_bool($criteriaValue) || is_object($criteriaValue) || is_resource($criteriaValue)) {
706                                 // Throw it again
707                                 throw new UnexpectedValueException(sprintf('criteriaValue[]=%s is not supported', gettype($criteriaValue)));
708                         }
709
710                         // Convert dashes to underscore
711                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: Invoking StringUtils::convertDashesToUnderscores(%s) ...', strtoupper($criteriaType), $criteriaKey));
712                         $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
713
714                         // Is the value in array or is $onlyKeys empty?
715                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: criteriaKey=%s', strtoupper($criteriaType), $criteriaKey));
716                         if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
717                                 // Add the value URL encoded to avoid any trouble with special characters
718                                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: Adding criteriaKey=%s,criteriaValue[%s]=%s to cache key ...', strtoupper($criteriaType), $criteriaKey, gettype($criteriaValue), $criteriaValue));
719                                 $cacheKey .= sprintf('%s=%s;',
720                                         $criteriaKey,
721                                         urlencode($criteriaValue)
722                                 );
723                         }
724                 }
725
726                 // Remove last semicolon
727                 $cacheKey = substr($cacheKey, 0, -1);
728
729                 // Is the instance SearchCriteria?
730                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: cacheKey=%s,this=%s', strtoupper($criteriaType), $cacheKey, $this->__toString()));
731                 if ($this instanceof SearchCriteria) {
732                         // Check if 'limit' and 'skip' are in
733                         if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
734                                 // Add limit and skip values
735                                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('%s-CRITERIA: Adding this->limit=%d,this->skip=%d to cache key ...', strtoupper($criteriaType), $this->getLimit(), $this->getSkip()));
736                                 $cacheKey .= sprintf(';%%limit%%=%s;%%skip%%=%s',
737                                         $this->getLimit(),
738                                         $this->getSkip()
739                                 );
740                         }
741                 }
742
743                 // Return the cache key
744                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('%s-CRITERIA: cacheKey=%s - EXIT!', strtoupper($criteriaType), $cacheKey));
745                 return $cacheKey;
746         }
747
748         /**
749          * "Getter" for a cache key ('choice' type)
750          *
751          * @param       $onlyKeys       Only use these keys for a cache key
752          * @return      $cacheKey       The key suitable for the cache system
753          */
754         public function getCacheKeyChoice (array $onlyKeys = []) {
755                 // Trace message
756                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: onlyKeys()=%d - CALLED!', count($onlyKeys)));
757
758                 // Invoke inner method
759                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->getCacheKey(onlyKeys()=%d,%s) ...', count($onlyKeys),Criteria::CRITERIA_TYPE_CHOICE));
760                 return $this->getCacheKey($onlyKeys, Criteria::CRITERIA_TYPE_CHOICE);
761         }
762
763         /**
764          * "Getter" for a cache key ('exclude' type)
765          *
766          * @param       $onlyKeys       Only use these keys for a cache key
767          * @return      $cacheKey       The key suitable for the cache system
768          */
769         public function getCacheKeyExclude (array $onlyKeys = []) {
770                 // Trace message
771                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: onlyKeys()=%d - CALLED!', count($onlyKeys)));
772
773                 // Invoke inner method
774                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-CRITERIA: Invoking this->getCacheKey(onlyKeys()=%d,%s) ...', count($onlyKeys),Criteria::CRITERIA_TYPE_EXCLUDE));
775                 return $this->getCacheKey($onlyKeys, Criteria::CRITERIA_TYPE_EXCLUDE);
776         }
777
778         /**
779          * Count 'choice' criteria, e.g. useful to find out if a database query
780          * has no limitation (search criteria).
781          *
782          * @return      $count  Count of all criteria entries
783          */
784         public final function countChoice () {
785                 // Trace message
786                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CRITERIA: CALLED!');
787                 return $this->count(Criteria::CRITERIA_TYPE_CHOICE);
788         }
789
790         /**
791          * Count 'exclude' criteria, e.g. useful to find out if a database query
792          * has no limitation (search criteria).
793          *
794          * @return      $count  Count of all criteria entries
795          */
796         public final function countExclude () {
797                 // Trace message
798                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-CRITERIA: CALLED!');
799                 return $this->count(Criteria::CRITERIA_TYPE_EXCLUDE);
800         }
801
802 }