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\String\StringUtils;
12 * A general crtieria class
14 * @author Roland Haeder <webmaster@shipsimu.org>
16 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 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 * Wrapper class name stored in config entry
37 private $wrapperConfigEntry = '';
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 * Checks whether given key is set
59 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
60 * @param $criteriaKey Criteria key
61 * @return $isSet Whether key is set
63 public function isKeySet ($criteriaType, $criteriaKey) {
64 // Make sure no 'my-' or 'my_' passes this point
65 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
68 $isSet = $this->isGenericArrayElementSet('criteria', $criteriaType, 'entries', $criteriaKey);
75 * Checks whether given key is set for 'choice' type
77 * @param $criteriaKey Criteria key
78 * @return $isSet Whether key is set
80 public function isChoiceKeySet ($criteriaKey) {
82 return $this->isKeySet('choice', $criteriaKey);
86 * Checks whether given key is set for 'exclude' type
88 * @param $criteriaKey Criteria key
89 * @return $isSet Whether key is set
91 public function isExcludeKeySet ($criteriaKey) {
93 return $this->isKeySet('exclude', $criteriaKey);
97 * Setter for wrapper class name
99 * @param $wrapperConfigEntry Configuration entry which hold the wrapper class' name
102 public final function setWrapperConfigEntry ($wrapperConfigEntry) {
103 $this->wrapperConfigEntry = (string) $wrapperConfigEntry;
107 * Getter for wrapper class name
109 * @return $wrapperConfigEntry Configuration entry which hold the wrapper class' name
111 public final function getWrapperConfigEntry () {
112 return $this->wrapperConfigEntry;
116 * Getter for criteria array
118 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
121 public final function getCriteriaArray ($criteriaType = 'default') {
122 return $this->getGenericArrayKey('criteria', $criteriaType, 'entries');
126 * Getter for criteria array 'choice' type
130 public final function getCriteriaChoiceArray () {
131 return $this->getCriteriaArray('choice');
135 * Getter for criteria array 'exclude' type
139 public final function getCriteriaExcludeArray () {
140 return $this->getCriteriaArray('exclude');
144 * Unsets a criteria key from all criteria types
146 * @param $criteriaKey Criteria key to unset
149 public final function unsetCriteria ($criteriaKey) {
150 // Make sure no 'my-' or 'my_' passes this point
151 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
153 // Convert dashes to underscore
154 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
156 // "Walk" through all criterias
157 foreach ($this->getGenericArray('criteria') as $criteriaType => $dummy) {
159 $this->unsetGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
164 * Add criteria, this method converts dashes to underscores because dashes
165 * are not valid for criteria keys.
167 * @param $criteriaKey Criteria key
168 * @param $criteriaValue Criteria value
169 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
172 public final function addCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
174 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
176 // Make sure no 'my-' or 'my_' passes this point
177 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
179 // Convert dashes to underscore
180 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
183 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA: criteriaKey=' . $criteriaKey);
186 $this->appendStringToGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
190 * Set criteria, this method converts dashes to underscores because dashes
191 * are not valid for criteria keys.
193 * @param $criteriaKey Criteria key
194 * @param $criteriaValue Criteria value
195 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
198 public final function setCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
200 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
202 // Make sure no 'my-' or 'my_' passes this point
203 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
205 // Convert dashes to underscore
206 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
209 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA: criteriaKey=' . $criteriaKey);
212 $this->setStringGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
216 * Add "choice" criteria, this method converts dashes to underscores because
217 * dashes are not valid for criteria keys.
219 * @param $criteriaKey Criteria key
220 * @param $criteriaValue Criteria value
223 public final function addChoiceCriteria ($criteriaKey, $criteriaValue) {
224 // Make sure no 'my-' or 'my_' passes this point
225 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
228 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
231 $this->pushValueToGenericArrayElement('criteria', 'choice', 'entries', StringUtils::convertDashesToUnderscores($criteriaKey), (string) $criteriaValue);
235 * Add "exclude" criteria, this method converts dashes to underscores because
236 * dashes are not valid for criteria keys.
238 * @param $criteriaKey Criteria key
239 * @param $criteriaValue Criteria value
242 public final function addExcludeCriteria ($criteriaKey, $criteriaValue) {
243 // Add it with generic method
244 $this->addCriteria($criteriaKey, $criteriaValue, 'exclude');
248 * Add configured criteria
250 * @param $criteriaKey Criteria key
251 * @param $configEntry Configuration entry
252 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
255 public final function addConfiguredCriteria ($criteriaKey, $configEntry, $criteriaType = 'default') {
256 // Add the configuration entry as a criteria
257 $value = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry($configEntry);
258 $this->addCriteria($criteriaKey, $value, $criteriaType);
262 * Get criteria element or false if not found
264 * @param $criteriaKey The requested criteria key
265 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
266 * @return $value Whether the value of the critera or false
268 public function getCriteriaElemnent ($criteriaKey, $criteriaType = 'default') {
270 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaType=' . $criteriaType . ' - CALLED!');
272 // Make sure no 'my-' or 'my_' passes this point
273 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
275 // Convert dashes to underscore
276 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
279 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteria()=' . $this->countGenericArrayGroup('criteria', $criteriaType));
281 // Default is not found
284 // Is the criteria there?
285 if ($this->isKeySet($criteriaType, $criteriaKey)) {
287 $value = $this->getGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
291 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: value=' . $value . ' - EXIT!');
298 * Get criteria element or false if not found for 'choice' type
300 * @param $criteriaKey The requested criteria key
301 * @return $value Whether the value of the critera or false
303 public function getCriteriaChoiceElemnent ($criteriaKey) {
305 return $this->getCriteriaElemnent($criteriaKey, 'choice');
309 * Get criteria element or false if not found for 'exclude' type
311 * @param $criteriaKey The requested criteria key
312 * @return $value Whether the value of the critera or false
314 public function getCriteriaExcludeElemnent ($criteriaKey) {
316 return $this->getCriteriaElemnent($criteriaKey, 'exclude');
320 * Checks whether given array entry matches
322 * @param $entryArray Array with the entries to find
323 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
324 * @return $matches Whether the entry matches or not
326 public function ifEntryMatches (array $entryArray, $criteriaType = 'default') {
327 // First nothing matches and nothing is counted
331 // Walk through all entries
332 foreach ($entryArray as $key => $entry) {
333 // Make sure no 'my-' or 'my_' passes this point
334 assert((strpos($key, 'my-') === false) && (strpos($key, 'my_') === false));
336 // Convert dashes to underscore
337 $key = StringUtils::convertDashesToUnderscores($key);
339 // Then walk through all search criteria
340 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
341 // Make sure no 'my-' or 'my_' passes this point
342 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
344 // Convert dashes to underscore
345 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
347 // Is the element found and does it match?
348 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
349 // Then count this one up
355 // Now check if expected criteria counts match
356 $matches = ($counted == $this->countGenericArrayGroup('criteria', $criteriaType));
363 * Checks whether given array 'choice' entry matches
365 * @param $entryArray Array with the entries to find
366 * @return $matches Whether the entry matches or not
368 public function ifChoiceMatches (array $entryArray) {
370 return $this->ifEntryMatches($entryArray, 'choice');
374 * Checks whether given array 'exclude' entry matches
376 * @param $entryArray Array with the entries to find
377 * @return $matches Whether the entry matches or not
379 public function ifExcludeMatches (array $entryArray) {
381 return $this->ifEntryMatches($entryArray, 'exclude');
385 * "Getter" for a cache key
387 * @param $onlyKeys Only use these keys for a cache key
388 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
389 * @return $cacheKey The key suitable for the cache system
391 public function getCacheKey ($onlyKeys = array(), $criteriaType = 'default') {
393 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . ': criteriaType=' . $criteriaType . ',count()=' . $this->countGenericArray('criteria')));
395 // Make sure the criteria is there
396 assert($this->isValidGenericArrayGroup('criteria', $criteriaType));
398 // Initialize the key
401 // Now walk through all criterias
402 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
403 // Make sure no 'my-' or 'my_' passes this point
404 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
406 // $criteriaValue cannot be an array
407 assert(!is_array($criteriaValue));
409 // Convert dashes to underscore
410 $criteriaKey = StringUtils::convertDashesToUnderscores($criteriaKey);
412 // Is the value in array or is $onlyKeys empty?
413 if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
414 // Add the value URL encoded to avoid any trouble with special characters
415 $cacheKey .= sprintf('%s=%s;',
417 urlencode($criteriaValue)
422 // Remove last semicolon
423 $cacheKey = substr($cacheKey, 0, -1);
425 // Is the instance SearchCriteria?
426 if ($this instanceof SearchCriteria) {
427 // Check if 'limit' and 'skip' are in
428 if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
429 // Add limit and skip values
430 $cacheKey .= sprintf(';%%limit%%=%s;%%skip%%=%s',
437 // Return the cache key
442 * "Getter" for a cache key ('choice' type)
444 * @param $onlyKeys Only use these keys for a cache key
445 * @return $cacheKey The key suitable for the cache system
447 public function getCacheKeyChoice ($onlyKeys = array()) {
449 return $this->getCacheKey($onlyKeys, 'choice');
453 * "Getter" for a cache key ('exclude' type)
455 * @param $onlyKeys Only use these keys for a cache key
456 * @return $cacheKey The key suitable for the cache system
458 public function getCacheKeyExclude ($onlyKeys = array()) {
460 return $this->getCacheKey($onlyKeys, 'exclude');
464 * Count the criteria, e.g. useful to find out if a database query has no
465 * limitation (search criteria).
467 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
468 * @return $count Count of all criteria entries
470 public final function count ($criteriaType = 'default') {
472 return $this->countGenericArrayGroup('criteria', $criteriaType);
476 * Count 'choice' criteria, e.g. useful to find out if a database query
477 * has no limitation (search criteria).
479 * @return $count Count of all criteria entries
481 public final function countChoice () {
482 return $this->count('choice');
486 * Count 'exclude' criteria, e.g. useful to find out if a database query
487 * has no limitation (search criteria).
489 * @return $count Count of all criteria entries
491 public final function countExclude () {
492 return $this->count('exclude');