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 * A general crtieria class
14 * @author Roland Haeder <webmaster@shipsimu.org>
16 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2022 Core Developer Team
17 * @license GNU GPL 3.0 or any newer version
18 * @link http://www.shipsimu.org
20 * This program is free software: you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation, either version 3 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program. If not, see <http://www.gnu.org/licenses/>.
33 abstract class BaseCriteria extends BaseFrameworkSystem implements Criteria {
35 * Frontend class name stored in config entry
37 private $frontendConfigEntry = '';
40 * Protected constructor
42 * @param $className Name of the class
45 protected function __construct (string $className) {
46 // Call parent constructor
47 parent::__construct($className);
49 // Initialize all criteria arrays
50 foreach (array('default', 'choice', 'exclude') as $criteriaType) {
52 $this->initGenericArrayKey('criteria', $criteriaType, 'entries');
57 * Count the criteria, e.g. useful to find out if a database query has no
58 * limitation (search criteria).
60 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
61 * @return $count Count of all criteria entries
63 protected final function count (string $criteriaType = 'default') {
65 return $this->countGenericArrayGroup('criteria', $criteriaType);
69 * Checks whether given key is set
71 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
72 * @param $criteriaKey Criteria key
73 * @return $isSet Whether key is set
75 public function isKeySet (string $criteriaType, string $criteriaKey) {
76 // Make sure no 'my-' or 'my_' passes this point
77 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
80 $isSet = $this->isGenericArrayElementSet('criteria', $criteriaType, 'entries', $criteriaKey);
87 * Checks whether given key is set for 'choice' type
89 * @param $criteriaKey Criteria key
90 * @return $isSet Whether key is set
92 public function isChoiceKeySet (string $criteriaKey) {
94 return $this->isKeySet('choice', $criteriaKey);
98 * Checks whether given key is set for 'exclude' type
100 * @param $criteriaKey Criteria key
101 * @return $isSet Whether key is set
103 public function isExcludeKeySet (string $criteriaKey) {
105 return $this->isKeySet('exclude', $criteriaKey);
109 * Setter for frontend class name
111 * @param $frontendConfigEntry Configuration entry which hold the frontend class' name
114 public final function setFrontendConfigEntry (string $frontendConfigEntry) {
115 $this->frontendConfigEntry = $frontendConfigEntry;
119 * Getter for frontend class name
121 * @return $frontendConfigEntry Configuration entry which hold the frontend class' name
123 public final function getFrontendConfigEntry () {
124 return $this->frontendConfigEntry;
128 * Getter for criteria array
130 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
133 public final function getCriteriaArray (string $criteriaType = 'default') {
134 return $this->getGenericArrayKey('criteria', $criteriaType, 'entries');
138 * Getter for criteria array 'choice' type
142 public final function getCriteriaChoiceArray () {
143 return $this->getCriteriaArray('choice');
147 * Getter for criteria array 'exclude' type
151 public final function getCriteriaExcludeArray () {
152 return $this->getCriteriaArray('exclude');
156 * Unsets a criteria key from all criteria types
158 * @param $criteriaKey Criteria key to unset
161 public final function unsetCriteria (string $criteriaKey) {
162 // Make sure no 'my-' or 'my_' passes this point
163 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
165 // Convert dashes to underscore
166 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
168 // "Walk" through all criterias
169 foreach ($this->getGenericArray('criteria') as $criteriaType => $dummy) {
171 $this->unsetGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
176 * Add criteria, this method converts dashes to underscores because dashes
177 * are not valid for criteria keys.
179 * @param $criteriaKey Criteria key
180 * @param $criteriaValue Criteria value
181 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
184 public final function addCriteria (string $criteriaKey, $criteriaValue, string $criteriaType = 'default') {
186 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
188 // Make sure no 'my-' or 'my_' passes this point
189 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
191 // Convert dashes to underscore
192 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
195 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA: criteriaKey=' . $criteriaKey);
198 $this->appendStringToGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
202 * Set criteria, this method converts dashes to underscores because dashes
203 * are not valid for criteria keys.
205 * @param $criteriaKey Criteria key
206 * @param $criteriaValue Criteria value
207 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
210 public final function setCriteria (string $criteriaKey, $criteriaValue, string $criteriaType = 'default') {
212 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
214 // Make sure no 'my-' or 'my_' passes this point
215 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
217 // Convert dashes to underscore
218 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
221 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA: criteriaKey=' . $criteriaKey);
224 $this->setStringGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
228 * Add "choice" criteria, this method converts dashes to underscores because
229 * dashes are not valid for criteria keys.
231 * @param $criteriaKey Criteria key
232 * @param $criteriaValue Criteria value
235 public final function addChoiceCriteria (string $criteriaKey, $criteriaValue) {
236 // Make sure no 'my-' or 'my_' passes this point
237 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
240 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
241 $this->pushValueToGenericArrayElement('criteria', 'choice', 'entries', StringUtils::convertDashesToUnderscores($criteriaKey), (string) $criteriaValue);
245 * Add "exclude" criteria, this method converts dashes to underscores because
246 * dashes are not valid for criteria keys.
248 * @param $criteriaKey Criteria key
249 * @param $criteriaValue Criteria value
252 public final function addExcludeCriteria (string $criteriaKey, $criteriaValue) {
253 // Add it with generic method
254 $this->addCriteria($criteriaKey, $criteriaValue, 'exclude');
258 * Add configured criteria
260 * @param $criteriaKey Criteria key
261 * @param $configEntry Configuration entry
262 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
265 public final function addConfiguredCriteria (string $criteriaKey, string $configEntry, string $criteriaType = 'default') {
266 // Add the configuration entry as a criteria
267 $value = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry($configEntry);
268 $this->addCriteria($criteriaKey, $value, $criteriaType);
272 * Get criteria element or false if not found
274 * @param $criteriaKey The requested criteria key
275 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
276 * @return $value Whether the value of the critera or false
278 public function getCriteriaElemnent (string $criteriaKey, string $criteriaType = 'default') {
279 // Make sure no 'my-' or 'my_' passes this point
280 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaType=' . $criteriaType . ' - CALLED!');
281 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
283 // Convert dashes to underscore
284 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
286 // Default is not found
287 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteria()=' . $this->countGenericArrayGroup('criteria', $criteriaType));
290 // Is the criteria there?
291 if ($this->isKeySet($criteriaType, $criteriaKey)) {
293 $value = $this->getGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
297 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: value=' . $value . ' - EXIT!');
302 * Get criteria element or false if not found for 'choice' type
304 * @param $criteriaKey The requested criteria key
305 * @return $value Whether the value of the critera or false
307 public function getCriteriaChoiceElemnent (string $criteriaKey) {
309 return $this->getCriteriaElemnent($criteriaKey, 'choice');
313 * Get criteria element or false if not found for 'exclude' type
315 * @param $criteriaKey The requested criteria key
316 * @return $value Whether the value of the critera or false
318 public function getCriteriaExcludeElemnent (string $criteriaKey) {
320 return $this->getCriteriaElemnent($criteriaKey, 'exclude');
324 * Checks whether given array entry matches
326 * @param $entryArray Array with the entries to find
327 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
328 * @return $matches Whether the entry matches or not
330 public function ifEntryMatches (array $entryArray, string $criteriaType = 'default') {
331 // First nothing matches and nothing is counted
335 // Walk through all entries
336 foreach ($entryArray as $key => $entry) {
337 // Make sure no 'my-' or 'my_' passes this point
338 assert((strpos($key, 'my-') === false) && (strpos($key, 'my_') === false));
340 // Convert dashes to underscore
341 $key = StringUtils::convertDashesToUnderscores($key);
343 // Then walk through all search criteria
344 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
345 // Make sure no 'my-' or 'my_' passes this point
346 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
348 // Convert dashes to underscore
349 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
351 // Is the element found and does it match?
352 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
353 // Then count this one up
359 // Now check if expected criteria counts match
360 $matches = ($counted == $this->countGenericArrayGroup('criteria', $criteriaType));
367 * Checks whether given array 'choice' entry matches
369 * @param $entryArray Array with the entries to find
370 * @return $matches Whether the entry matches or not
372 public function ifChoiceMatches (array $entryArray) {
374 return $this->ifEntryMatches($entryArray, 'choice');
378 * Checks whether given array 'exclude' entry matches
380 * @param $entryArray Array with the entries to find
381 * @return $matches Whether the entry matches or not
383 public function ifExcludeMatches (array $entryArray) {
385 return $this->ifEntryMatches($entryArray, 'exclude');
389 * "Getter" for a cache key
391 * @param $onlyKeys Only use these keys for a cache key
392 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
393 * @return $cacheKey The key suitable for the cache system
395 public function getCacheKey (array $onlyKeys = [], string $criteriaType = 'default') {
397 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . ': criteriaType=' . $criteriaType . ',count()=' . $this->countGenericArray('criteria')));
399 // Make sure the criteria is there
400 assert($this->isValidGenericArrayGroup('criteria', $criteriaType));
402 // Initialize the key
405 // Now walk through all criterias
406 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
407 // Make sure no 'my-' or 'my_' passes this point
408 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
410 // $criteriaValue cannot be an array
411 assert(!is_array($criteriaValue));
413 // Convert dashes to underscore
414 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
416 // Is the value in array or is $onlyKeys empty?
417 if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
418 // Add the value URL encoded to avoid any trouble with special characters
419 $cacheKey .= sprintf('%s=%s;',
421 urlencode($criteriaValue)
426 // Remove last semicolon
427 $cacheKey = substr($cacheKey, 0, -1);
429 // Is the instance SearchCriteria?
430 if ($this instanceof SearchCriteria) {
431 // Check if 'limit' and 'skip' are in
432 if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
433 // Add limit and skip values
434 $cacheKey .= sprintf(';%%limit%%=%s;%%skip%%=%s',
441 // Return the cache key
446 * "Getter" for a cache key ('choice' type)
448 * @param $onlyKeys Only use these keys for a cache key
449 * @return $cacheKey The key suitable for the cache system
451 public function getCacheKeyChoice (array $onlyKeys = []) {
453 return $this->getCacheKey($onlyKeys, 'choice');
457 * "Getter" for a cache key ('exclude' type)
459 * @param $onlyKeys Only use these keys for a cache key
460 * @return $cacheKey The key suitable for the cache system
462 public function getCacheKeyExclude (array $onlyKeys = []) {
464 return $this->getCacheKey($onlyKeys, 'exclude');
468 * Count 'choice' criteria, e.g. useful to find out if a database query
469 * has no limitation (search criteria).
471 * @return $count Count of all criteria entries
473 public final function countChoice () {
474 return $this->count('choice');
478 * Count 'exclude' criteria, e.g. useful to find out if a database query
479 * has no limitation (search criteria).
481 * @return $count Count of all criteria entries
483 public final function countExclude () {
484 return $this->count('exclude');