3 namespace CoreFramework\Criteria;
5 // Import framework stuff
6 use CoreFramework\Object\BaseFrameworkSystem;
9 * A general crtieria class
11 * @author Roland Haeder <webmaster@shipsimu.org>
13 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
14 * @license GNU GPL 3.0 or any newer version
15 * @link http://www.shipsimu.org
17 * This program is free software: you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, either version 3 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 class BaseCriteria extends BaseFrameworkSystem implements Criteria {
32 * Wrapper class name stored in config entry
34 private $wrapperConfigEntry = '';
37 * Protected constructor
39 * @param $className Name of the class
42 protected function __construct ($className) {
43 // Call parent constructor
44 parent::__construct($className);
46 // Initialize all criteria arrays
47 foreach (array('default', 'choice', 'exclude') as $criteriaType) {
49 $this->initGenericArrayKey('criteria', $criteriaType, 'entries');
54 * Checks whether given key is set
56 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
57 * @param $criteriaKey Criteria key
58 * @return $isSet Whether key is set
60 public function isKeySet ($criteriaType, $criteriaKey) {
61 // Make sure no 'my-' or 'my_' passes this point
62 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE));
65 $isSet = $this->isGenericArrayElementSet('criteria', $criteriaType, 'entries', $criteriaKey);
72 * Checks whether given key is set for 'choice' type
74 * @param $criteriaKey Criteria key
75 * @return $isSet Whether key is set
77 public function isChoiceKeySet ($criteriaKey) {
79 return $this->isKeySet('choice', $criteriaKey);
83 * Checks whether given key is set for 'exclude' type
85 * @param $criteriaKey Criteria key
86 * @return $isSet Whether key is set
88 public function isExcludeKeySet ($criteriaKey) {
90 return $this->isKeySet('exclude', $criteriaKey);
94 * Setter for wrapper class name
96 * @param $wrapperConfigEntry Configuration entry which hold the wrapper class' name
99 public final function setWrapperConfigEntry ($wrapperConfigEntry) {
100 $this->wrapperConfigEntry = (string) $wrapperConfigEntry;
104 * Getter for wrapper class name
106 * @return $wrapperConfigEntry Configuration entry which hold the wrapper class' name
108 public final function getWrapperConfigEntry () {
109 return $this->wrapperConfigEntry;
113 * Getter for criteria array
115 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
118 public final function getCriteriaArray ($criteriaType = 'default') {
119 return $this->getGenericArrayKey('criteria', $criteriaType, 'entries');
123 * Getter for criteria array 'choice' type
127 public final function getCriteriaChoiceArray () {
128 return $this->getCriteriaArray('choice');
132 * Getter for criteria array 'exclude' type
136 public final function getCriteriaExcludeArray () {
137 return $this->getCriteriaArray('exclude');
141 * Unsets a criteria key from all criteria types
143 * @param $criteriaKey Criteria key to unset
146 public final function unsetCriteria ($criteriaKey) {
147 // Make sure no 'my-' or 'my_' passes this point
148 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE));
150 // Convert dashes to underscore
151 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
153 // "Walk" through all criterias
154 foreach ($this->getGenericArray('criteria') as $criteriaType => $dummy) {
156 $this->unsetGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
161 * Add criteria, this method converts dashes to underscores because dashes
162 * are not valid for criteria keys.
164 * @param $criteriaKey Criteria key
165 * @param $criteriaValue Criteria value
166 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
169 public final function addCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
171 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
173 // Make sure no 'my-' or 'my_' passes this point
174 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
176 // Convert dashes to underscore
177 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
180 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey);
183 $this->appendStringToGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
187 * Set criteria, this method converts dashes to underscores because dashes
188 * are not valid for criteria keys.
190 * @param $criteriaKey Criteria key
191 * @param $criteriaValue Criteria value
192 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
195 public final function setCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
197 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
199 // Make sure no 'my-' or 'my_' passes this point
200 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
202 // Convert dashes to underscore
203 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
206 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey);
209 $this->setStringGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
213 * Add "choice" criteria, this method converts dashes to underscores because
214 * dashes are not valid for criteria keys.
216 * @param $criteriaKey Criteria key
217 * @param $criteriaValue Criteria value
220 public final function addChoiceCriteria ($criteriaKey, $criteriaValue) {
221 // Make sure no 'my-' or 'my_' passes this point
222 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
225 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
228 $this->pushValueToGenericArrayElement('criteria', 'choice', 'entries', self::convertDashesToUnderscores($criteriaKey), (string) $criteriaValue);
232 * Add "exclude" criteria, this method converts dashes to underscores because
233 * dashes are not valid for criteria keys.
235 * @param $criteriaKey Criteria key
236 * @param $criteriaValue Criteria value
239 public final function addExcludeCriteria ($criteriaKey, $criteriaValue) {
240 // Add it with generic method
241 $this->addCriteria($criteriaKey, $criteriaValue, 'exclude');
245 * Add configured criteria
247 * @param $criteriaKey Criteria key
248 * @param $configEntry Configuration entry
249 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
252 public final function addConfiguredCriteria ($criteriaKey, $configEntry, $criteriaType = 'default') {
253 // Add the configuration entry as a criteria
254 $value = $this->getConfigInstance()->getConfigEntry($configEntry);
255 $this->addCriteria($criteriaKey, $value, $criteriaType);
259 * Get criteria element or FALSE if not found
261 * @param $criteriaKey The requested criteria key
262 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
263 * @return $value Whether the value of the critera or FALSE
265 public function getCriteriaElemnent ($criteriaKey, $criteriaType = 'default') {
267 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaType=' . $criteriaType . ' - CALLED!');
269 // Make sure no 'my-' or 'my_' passes this point
270 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE));
272 // Convert dashes to underscore
273 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
276 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteria()=' . $this->countGenericArrayGroup('criteria', $criteriaType));
278 // Default is not found
281 // Is the criteria there?
282 if ($this->isKeySet($criteriaType, $criteriaKey)) {
284 $value = $this->getGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
288 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: value=' . $value . ' - EXIT!');
295 * Get criteria element or FALSE if not found for 'choice' type
297 * @param $criteriaKey The requested criteria key
298 * @return $value Whether the value of the critera or FALSE
300 public function getCriteriaChoiceElemnent ($criteriaKey) {
302 return $this->getCriteriaElemnent($criteriaKey, 'choice');
306 * Get criteria element or FALSE if not found for 'exclude' type
308 * @param $criteriaKey The requested criteria key
309 * @return $value Whether the value of the critera or FALSE
311 public function getCriteriaExcludeElemnent ($criteriaKey) {
313 return $this->getCriteriaElemnent($criteriaKey, 'exclude');
317 * Checks whether given array entry matches
319 * @param $entryArray Array with the entries to find
320 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
321 * @return $matches Whether the entry matches or not
323 public function ifEntryMatches (array $entryArray, $criteriaType = 'default') {
324 // First nothing matches and nothing is counted
328 // Walk through all entries
329 foreach ($entryArray as $key => $entry) {
330 // Make sure no 'my-' or 'my_' passes this point
331 assert((strpos($key, 'my-') === FALSE) && (strpos($key, 'my_') === FALSE));
333 // Convert dashes to underscore
334 $key = self::convertDashesToUnderscores($key);
336 // Then walk through all search criteria
337 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
338 // Make sure no 'my-' or 'my_' passes this point
339 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
341 // Convert dashes to underscore
342 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
344 // Is the element found and does it match?
345 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
346 // Then count this one up
352 // Now check if expected criteria counts match
353 $matches = ($counted == $this->countGenericArrayGroup('criteria', $criteriaType));
360 * Checks whether given array 'choice' entry matches
362 * @param $entryArray Array with the entries to find
363 * @return $matches Whether the entry matches or not
365 public function ifChoiceMatches (array $entryArray) {
367 return $this->ifEntryMatches($entryArray, 'choice');
371 * Checks whether given array 'exclude' entry matches
373 * @param $entryArray Array with the entries to find
374 * @return $matches Whether the entry matches or not
376 public function ifExcludeMatches (array $entryArray) {
378 return $this->ifEntryMatches($entryArray, 'exclude');
382 * "Getter" for a cache key
384 * @param $onlyKeys Only use these keys for a cache key
385 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
386 * @return $cacheKey The key suitable for the cache system
388 public function getCacheKey ($onlyKeys = array(), $criteriaType = 'default') {
390 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . ': criteriaType=' . $criteriaType . ',count()=' . $this->countGenericArray('criteria')));
392 // Make sure the criteria is there
393 assert($this->isValidGenericArrayGroup('criteria', $criteriaType));
395 // Initialize the key
398 // Now walk through all criterias
399 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
400 // Make sure no 'my-' or 'my_' passes this point
401 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
403 // $criteriaValue cannot be an array
404 assert(!is_array($criteriaValue));
406 // Convert dashes to underscore
407 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
409 // Is the value in array or is $onlyKeys empty?
410 if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
411 // Add the value URL encoded to avoid any trouble with special characters
412 $cacheKey .= sprintf('%s=%s;',
414 urlencode($criteriaValue)
419 // Remove last semicolon
420 $cacheKey = substr($cacheKey, 0, -1);
422 // Is the instance SearchCriteria?
423 if ($this instanceof SearchCriteria) {
424 // Check if 'limit' and 'skip' are in
425 if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
426 // Add limit and skip values
427 $cacheKey .= sprintf(';%%limit%%=%s;%%skip%%=%s',
434 // Return the cache key
439 * "Getter" for a cache key ('choice' type)
441 * @param $onlyKeys Only use these keys for a cache key
442 * @return $cacheKey The key suitable for the cache system
444 public function getCacheKeyChoice ($onlyKeys = array()) {
446 return $this->getCacheKey($onlyKeys, 'choice');
450 * "Getter" for a cache key ('exclude' type)
452 * @param $onlyKeys Only use these keys for a cache key
453 * @return $cacheKey The key suitable for the cache system
455 public function getCacheKeyExclude ($onlyKeys = array()) {
457 return $this->getCacheKey($onlyKeys, 'exclude');
461 * Count the criteria, e.g. useful to find out if a database query has no
462 * limitation (search criteria).
464 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
465 * @return $count Count of all criteria entries
467 public final function count ($criteriaType = 'default') {
469 return $this->countGenericArrayGroup('criteria', $criteriaType);
473 * Count 'choice' criteria, e.g. useful to find out if a database query
474 * has no limitation (search criteria).
476 * @return $count Count of all criteria entries
478 public final function countChoice () {
479 return $this->count('choice');
483 * Count 'exclude' criteria, e.g. useful to find out if a database query
484 * has no limitation (search criteria).
486 * @return $count Count of all criteria entries
488 public final function countExclude () {
489 return $this->count('exclude');