3 namespace Org\Mxchange\CoreFramework\Criteria;
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Criteria\Search\SearchCriteria;
7 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
8 use Org\Mxchange\CoreFramework\String\Utils\StringUtils;
11 * A general crtieria class
13 * @author Roland Haeder <webmaster@shipsimu.org>
15 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team
16 * @license GNU GPL 3.0 or any newer version
17 * @link http://www.shipsimu.org
19 * This program is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation, either version 3 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 abstract class BaseCriteria extends BaseFrameworkSystem implements Criteria {
34 * Wrapper class name stored in config entry
36 private $wrapperConfigEntry = '';
39 * Protected constructor
41 * @param $className Name of the class
44 protected function __construct ($className) {
45 // Call parent constructor
46 parent::__construct($className);
48 // Initialize all criteria arrays
49 foreach (array('default', 'choice', 'exclude') as $criteriaType) {
51 $this->initGenericArrayKey('criteria', $criteriaType, 'entries');
56 * Checks whether given key is set
58 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
59 * @param $criteriaKey Criteria key
60 * @return $isSet Whether key is set
62 public function isKeySet ($criteriaType, $criteriaKey) {
63 // Make sure no 'my-' or 'my_' passes this point
64 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
67 $isSet = $this->isGenericArrayElementSet('criteria', $criteriaType, 'entries', $criteriaKey);
74 * Checks whether given key is set for 'choice' type
76 * @param $criteriaKey Criteria key
77 * @return $isSet Whether key is set
79 public function isChoiceKeySet ($criteriaKey) {
81 return $this->isKeySet('choice', $criteriaKey);
85 * Checks whether given key is set for 'exclude' type
87 * @param $criteriaKey Criteria key
88 * @return $isSet Whether key is set
90 public function isExcludeKeySet ($criteriaKey) {
92 return $this->isKeySet('exclude', $criteriaKey);
96 * Setter for wrapper class name
98 * @param $wrapperConfigEntry Configuration entry which hold the wrapper class' name
101 public final function setWrapperConfigEntry ($wrapperConfigEntry) {
102 $this->wrapperConfigEntry = (string) $wrapperConfigEntry;
106 * Getter for wrapper class name
108 * @return $wrapperConfigEntry Configuration entry which hold the wrapper class' name
110 public final function getWrapperConfigEntry () {
111 return $this->wrapperConfigEntry;
115 * Getter for criteria array
117 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
120 public final function getCriteriaArray ($criteriaType = 'default') {
121 return $this->getGenericArrayKey('criteria', $criteriaType, 'entries');
125 * Getter for criteria array 'choice' type
129 public final function getCriteriaChoiceArray () {
130 return $this->getCriteriaArray('choice');
134 * Getter for criteria array 'exclude' type
138 public final function getCriteriaExcludeArray () {
139 return $this->getCriteriaArray('exclude');
143 * Unsets a criteria key from all criteria types
145 * @param $criteriaKey Criteria key to unset
148 public final function unsetCriteria ($criteriaKey) {
149 // Make sure no 'my-' or 'my_' passes this point
150 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
152 // Convert dashes to underscore
153 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
155 // "Walk" through all criterias
156 foreach ($this->getGenericArray('criteria') as $criteriaType => $dummy) {
158 $this->unsetGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
163 * Add criteria, this method converts dashes to underscores because dashes
164 * are not valid for criteria keys.
166 * @param $criteriaKey Criteria key
167 * @param $criteriaValue Criteria value
168 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
171 public final function addCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
173 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
175 // Make sure no 'my-' or 'my_' passes this point
176 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
178 // Convert dashes to underscore
179 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
182 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA: criteriaKey=' . $criteriaKey);
185 $this->appendStringToGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
189 * Set criteria, this method converts dashes to underscores because dashes
190 * are not valid for criteria keys.
192 * @param $criteriaKey Criteria key
193 * @param $criteriaValue Criteria value
194 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
197 public final function setCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
199 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
201 // Make sure no 'my-' or 'my_' passes this point
202 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
204 // Convert dashes to underscore
205 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
208 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA: criteriaKey=' . $criteriaKey);
211 $this->setStringGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
215 * Add "choice" criteria, this method converts dashes to underscores because
216 * dashes are not valid for criteria keys.
218 * @param $criteriaKey Criteria key
219 * @param $criteriaValue Criteria value
222 public final function addChoiceCriteria ($criteriaKey, $criteriaValue) {
223 // Make sure no 'my-' or 'my_' passes this point
224 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
227 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
230 $this->pushValueToGenericArrayElement('criteria', 'choice', 'entries', StringUtils::convertDashesToUnderscores($criteriaKey), (string) $criteriaValue);
234 * Add "exclude" criteria, this method converts dashes to underscores because
235 * dashes are not valid for criteria keys.
237 * @param $criteriaKey Criteria key
238 * @param $criteriaValue Criteria value
241 public final function addExcludeCriteria ($criteriaKey, $criteriaValue) {
242 // Add it with generic method
243 $this->addCriteria($criteriaKey, $criteriaValue, 'exclude');
247 * Add configured criteria
249 * @param $criteriaKey Criteria key
250 * @param $configEntry Configuration entry
251 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
254 public final function addConfiguredCriteria ($criteriaKey, $configEntry, $criteriaType = 'default') {
255 // Add the configuration entry as a criteria
256 $value = $this->getConfigInstance()->getConfigEntry($configEntry);
257 $this->addCriteria($criteriaKey, $value, $criteriaType);
261 * Get criteria element or false if not found
263 * @param $criteriaKey The requested criteria key
264 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
265 * @return $value Whether the value of the critera or false
267 public function getCriteriaElemnent ($criteriaKey, $criteriaType = 'default') {
269 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaType=' . $criteriaType . ' - CALLED!');
271 // Make sure no 'my-' or 'my_' passes this point
272 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
274 // Convert dashes to underscore
275 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
278 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteria()=' . $this->countGenericArrayGroup('criteria', $criteriaType));
280 // Default is not found
283 // Is the criteria there?
284 if ($this->isKeySet($criteriaType, $criteriaKey)) {
286 $value = $this->getGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
290 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: value=' . $value . ' - EXIT!');
297 * Get criteria element or false if not found for 'choice' type
299 * @param $criteriaKey The requested criteria key
300 * @return $value Whether the value of the critera or false
302 public function getCriteriaChoiceElemnent ($criteriaKey) {
304 return $this->getCriteriaElemnent($criteriaKey, 'choice');
308 * Get criteria element or false if not found for 'exclude' type
310 * @param $criteriaKey The requested criteria key
311 * @return $value Whether the value of the critera or false
313 public function getCriteriaExcludeElemnent ($criteriaKey) {
315 return $this->getCriteriaElemnent($criteriaKey, 'exclude');
319 * Checks whether given array entry matches
321 * @param $entryArray Array with the entries to find
322 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
323 * @return $matches Whether the entry matches or not
325 public function ifEntryMatches (array $entryArray, $criteriaType = 'default') {
326 // First nothing matches and nothing is counted
330 // Walk through all entries
331 foreach ($entryArray as $key => $entry) {
332 // Make sure no 'my-' or 'my_' passes this point
333 assert((strpos($key, 'my-') === false) && (strpos($key, 'my_') === false));
335 // Convert dashes to underscore
336 $key = StringUtils::convertDashesToUnderscores($key);
338 // Then walk through all search criteria
339 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
340 // Make sure no 'my-' or 'my_' passes this point
341 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
343 // Convert dashes to underscore
344 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
346 // Is the element found and does it match?
347 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
348 // Then count this one up
354 // Now check if expected criteria counts match
355 $matches = ($counted == $this->countGenericArrayGroup('criteria', $criteriaType));
362 * Checks whether given array 'choice' entry matches
364 * @param $entryArray Array with the entries to find
365 * @return $matches Whether the entry matches or not
367 public function ifChoiceMatches (array $entryArray) {
369 return $this->ifEntryMatches($entryArray, 'choice');
373 * Checks whether given array 'exclude' entry matches
375 * @param $entryArray Array with the entries to find
376 * @return $matches Whether the entry matches or not
378 public function ifExcludeMatches (array $entryArray) {
380 return $this->ifEntryMatches($entryArray, 'exclude');
384 * "Getter" for a cache key
386 * @param $onlyKeys Only use these keys for a cache key
387 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
388 * @return $cacheKey The key suitable for the cache system
390 public function getCacheKey ($onlyKeys = array(), $criteriaType = 'default') {
392 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . ': criteriaType=' . $criteriaType . ',count()=' . $this->countGenericArray('criteria')));
394 // Make sure the criteria is there
395 assert($this->isValidGenericArrayGroup('criteria', $criteriaType));
397 // Initialize the key
400 // Now walk through all criterias
401 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
402 // Make sure no 'my-' or 'my_' passes this point
403 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
405 // $criteriaValue cannot be an array
406 assert(!is_array($criteriaValue));
408 // Convert dashes to underscore
409 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
411 // Is the value in array or is $onlyKeys empty?
412 if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
413 // Add the value URL encoded to avoid any trouble with special characters
414 $cacheKey .= sprintf('%s=%s;',
416 urlencode($criteriaValue)
421 // Remove last semicolon
422 $cacheKey = substr($cacheKey, 0, -1);
424 // Is the instance SearchCriteria?
425 if ($this instanceof SearchCriteria) {
426 // Check if 'limit' and 'skip' are in
427 if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
428 // Add limit and skip values
429 $cacheKey .= sprintf(';%%limit%%=%s;%%skip%%=%s',
436 // Return the cache key
441 * "Getter" for a cache key ('choice' type)
443 * @param $onlyKeys Only use these keys for a cache key
444 * @return $cacheKey The key suitable for the cache system
446 public function getCacheKeyChoice ($onlyKeys = array()) {
448 return $this->getCacheKey($onlyKeys, 'choice');
452 * "Getter" for a cache key ('exclude' type)
454 * @param $onlyKeys Only use these keys for a cache key
455 * @return $cacheKey The key suitable for the cache system
457 public function getCacheKeyExclude ($onlyKeys = array()) {
459 return $this->getCacheKey($onlyKeys, 'exclude');
463 * Count the criteria, e.g. useful to find out if a database query has no
464 * limitation (search criteria).
466 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
467 * @return $count Count of all criteria entries
469 public final function count ($criteriaType = 'default') {
471 return $this->countGenericArrayGroup('criteria', $criteriaType);
475 * Count 'choice' criteria, e.g. useful to find out if a database query
476 * has no limitation (search criteria).
478 * @return $count Count of all criteria entries
480 public final function countChoice () {
481 return $this->count('choice');
485 * Count 'exclude' criteria, e.g. useful to find out if a database query
486 * has no limitation (search criteria).
488 * @return $count Count of all criteria entries
490 public final function countExclude () {
491 return $this->count('exclude');