3 * A general crtieria class
5 * @author Roland Haeder <webmaster@shipsimu.org>
7 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 Core Developer Team
8 * @license GNU GPL 3.0 or any newer version
9 * @link http://www.shipsimu.org
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 class BaseCriteria extends BaseFrameworkSystem implements Criteria {
26 * Wrapper class name stored in config entry
28 private $wrapperConfigEntry = '';
31 * Protected constructor
33 * @param $className Name of the class
36 protected function __construct ($className) {
37 // Call parent constructor
38 parent::__construct($className);
40 // Initialize all criteria arrays
41 foreach (array('default', 'choice', 'exclude') as $criteriaType) {
43 $this->initGenericArrayKey('criteria', $criteriaType, 'entries');
48 * Checks whether given key is set
50 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
51 * @param $criteriaKey Criteria key
52 * @return $isSet Whether key is set
54 public function isKeySet ($criteriaType, $criteriaKey) {
55 // Make sure no 'my-' or 'my_' passes this point
56 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE));
59 $isSet = $this->isGenericArrayElementSet('criteria', $criteriaType, 'entries', $criteriaKey);
66 * Checks whether given key is set for 'choice' type
68 * @param $criteriaKey Criteria key
69 * @return $isSet Whether key is set
71 public function isChoiceKeySet ($criteriaKey) {
73 return $this->isKeySet('choice', $criteriaKey);
77 * Checks whether given key is set for 'exclude' type
79 * @param $criteriaKey Criteria key
80 * @return $isSet Whether key is set
82 public function isExcludeKeySet ($criteriaKey) {
84 return $this->isKeySet('exclude', $criteriaKey);
88 * Setter for wrapper class name
90 * @param $wrapperConfigEntry Configuration entry which hold the wrapper class' name
93 public final function setWrapperConfigEntry ($wrapperConfigEntry) {
94 $this->wrapperConfigEntry = (string) $wrapperConfigEntry;
98 * Getter for wrapper class name
100 * @return $wrapperConfigEntry Configuration entry which hold the wrapper class' name
102 public final function getWrapperConfigEntry () {
103 return $this->wrapperConfigEntry;
107 * Getter for criteria array
109 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
112 public final function getCriteriaArray ($criteriaType = 'default') {
113 return $this->getGenericArrayKey('criteria', $criteriaType, 'entries');
117 * Getter for criteria array 'choice' type
121 public final function getCriteriaChoiceArray () {
122 return $this->getCriteriaArray('choice');
126 * Getter for criteria array 'exclude' type
130 public final function getCriteriaExcludeArray () {
131 return $this->getCriteriaArray('exclude');
135 * Unsets a criteria key from all criteria types
137 * @param $criteriaKey Criteria key to unset
140 public final function unsetCriteria ($criteriaKey) {
141 // Make sure no 'my-' or 'my_' passes this point
142 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE));
144 // Convert dashes to underscore
145 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
147 // "Walk" through all criterias
148 foreach ($this->getGenericArray('criteria') as $criteriaType => $dummy) {
150 $this->unsetGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
155 * Add criteria, this method converts dashes to underscores because dashes
156 * are not valid for criteria keys.
158 * @param $criteriaKey Criteria key
159 * @param $criteriaValue Criteria value
160 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
163 public final function addCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
165 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
167 // Make sure no 'my-' or 'my_' passes this point
168 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
170 // Convert dashes to underscore
171 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
174 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey);
177 $this->appendStringToGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
181 * Set criteria, this method converts dashes to underscores because dashes
182 * are not valid for criteria keys.
184 * @param $criteriaKey Criteria key
185 * @param $criteriaValue Criteria value
186 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
189 public final function setCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
191 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
193 // Make sure no 'my-' or 'my_' passes this point
194 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
196 // Convert dashes to underscore
197 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
200 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey);
203 $this->setStringGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
207 * Add "choice" criteria, this method converts dashes to underscores because
208 * dashes are not valid for criteria keys.
210 * @param $criteriaKey Criteria key
211 * @param $criteriaValue Criteria value
214 public final function addChoiceCriteria ($criteriaKey, $criteriaValue) {
215 // Make sure no 'my-' or 'my_' passes this point
216 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
219 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
222 $this->pushValueToGenericArrayElement('criteria', 'choice', 'entries', self::convertDashesToUnderscores($criteriaKey), (string) $criteriaValue);
226 * Add "exclude" criteria, this method converts dashes to underscores because
227 * dashes are not valid for criteria keys.
229 * @param $criteriaKey Criteria key
230 * @param $criteriaValue Criteria value
233 public final function addExcludeCriteria ($criteriaKey, $criteriaValue) {
234 // Add it with generic method
235 $this->addCriteria($criteriaKey, $criteriaValue, 'exclude');
239 * Add configured criteria
241 * @param $criteriaKey Criteria key
242 * @param $configEntry Configuration entry
243 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
246 public final function addConfiguredCriteria ($criteriaKey, $configEntry, $criteriaType = 'default') {
247 // Add the configuration entry as a criteria
248 $value = $this->getConfigInstance()->getConfigEntry($configEntry);
249 $this->addCriteria($criteriaKey, $value, $criteriaType);
253 * Get criteria element or FALSE if not found
255 * @param $criteriaKey The requested criteria key
256 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
257 * @return $value Whether the value of the critera or FALSE
259 public function getCriteriaElemnent ($criteriaKey, $criteriaType = 'default') {
261 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaType=' . $criteriaType . ' - CALLED!');
263 // Make sure no 'my-' or 'my_' passes this point
264 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE));
266 // Convert dashes to underscore
267 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
270 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteria()=' . $this->countGenericArrayGroup('criteria', $criteriaType));
272 // Default is not found
275 // Is the criteria there?
276 if ($this->isKeySet($criteriaType, $criteriaKey)) {
278 $value = $this->getGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
282 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: value=' . $value . ' - EXIT!');
289 * Get criteria element or FALSE if not found for 'choice' type
291 * @param $criteriaKey The requested criteria key
292 * @return $value Whether the value of the critera or FALSE
294 public function getCriteriaChoiceElemnent ($criteriaKey) {
296 return $this->getCriteriaElemnent($criteriaKey, 'choice');
300 * Get criteria element or FALSE if not found for 'exclude' type
302 * @param $criteriaKey The requested criteria key
303 * @return $value Whether the value of the critera or FALSE
305 public function getCriteriaExcludeElemnent ($criteriaKey) {
307 return $this->getCriteriaElemnent($criteriaKey, 'exclude');
311 * Checks whether given array entry matches
313 * @param $entryArray Array with the entries to find
314 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
315 * @return $matches Whether the entry matches or not
317 public function ifEntryMatches (array $entryArray, $criteriaType = 'default') {
318 // First nothing matches and nothing is counted
322 // Walk through all entries
323 foreach ($entryArray as $key => $entry) {
324 // Make sure no 'my-' or 'my_' passes this point
325 assert((strpos($key, 'my-') === FALSE) && (strpos($key, 'my_') === FALSE));
327 // Convert dashes to underscore
328 $key = self::convertDashesToUnderscores($key);
330 // Then walk through all search criteria
331 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
332 // Make sure no 'my-' or 'my_' passes this point
333 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
335 // Convert dashes to underscore
336 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
338 // Is the element found and does it match?
339 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
340 // Then count this one up
346 // Now check if expected criteria counts match
347 $matches = ($counted == $this->countGenericArrayGroup('criteria', $criteriaType));
354 * Checks whether given array 'choice' entry matches
356 * @param $entryArray Array with the entries to find
357 * @return $matches Whether the entry matches or not
359 public function ifChoiceMatches (array $entryArray) {
361 return $this->ifEntryMatches($entryArray, 'choice');
365 * Checks whether given array 'exclude' entry matches
367 * @param $entryArray Array with the entries to find
368 * @return $matches Whether the entry matches or not
370 public function ifExcludeMatches (array $entryArray) {
372 return $this->ifEntryMatches($entryArray, 'exclude');
376 * "Getter" for a cache key
378 * @param $onlyKeys Only use these keys for a cache key
379 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
380 * @return $cacheKey The key suitable for the cache system
382 public function getCacheKey ($onlyKeys = array(), $criteriaType = 'default') {
384 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ': criteriaType=' . $criteriaType . ',count()=' . $this->countGenericArray('criteria')));
386 // Make sure the criteria is there
387 assert($this->isValidGenericArrayGroup('criteria', $criteriaType));
389 // Initialize the key
392 // Now walk through all criterias
393 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
394 // Make sure no 'my-' or 'my_' passes this point
395 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
397 // $criteriaValue cannot be an array
398 assert(!is_array($criteriaValue));
400 // Convert dashes to underscore
401 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
403 // Is the value in array or is $onlyKeys empty?
404 if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
405 // Add the value URL encoded to avoid any trouble with special characters
406 $cacheKey .= sprintf('%s=%s;',
408 urlencode($criteriaValue)
413 // Remove last semicolon
414 $cacheKey = substr($cacheKey, 0, -1);
416 // Is the instance SearchCriteria?
417 if ($this instanceof SearchCriteria) {
418 // Check if 'limit' and 'skip' are in
419 if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
420 // Add limit and skip values
421 $cacheKey .= sprintf(';%%limit%%=%s;%%skip%%=%s',
428 // Return the cache key
433 * "Getter" for a cache key ('choice' type)
435 * @param $onlyKeys Only use these keys for a cache key
436 * @return $cacheKey The key suitable for the cache system
438 public function getCacheKeyChoice ($onlyKeys = array()) {
440 return $this->getCacheKey($onlyKeys, 'choice');
444 * "Getter" for a cache key ('exclude' type)
446 * @param $onlyKeys Only use these keys for a cache key
447 * @return $cacheKey The key suitable for the cache system
449 public function getCacheKeyExclude ($onlyKeys = array()) {
451 return $this->getCacheKey($onlyKeys, 'exclude');
455 * Count the criteria, e.g. useful to find out if a database query has no
456 * limitation (search criteria).
458 * @param $criteriaType Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
459 * @return $count Count of all criteria entries
461 public final function count ($criteriaType = 'default') {
463 return $this->countGenericArrayGroup('criteria', $criteriaType);
467 * Count 'choice' criteria, e.g. useful to find out if a database query
468 * has no limitation (search criteria).
470 * @return $count Count of all criteria entries
472 public final function countChoice () {
473 return $this->count('choice');
477 * Count 'exclude' criteria, e.g. useful to find out if a database query
478 * has no limitation (search criteria).
480 * @return $count Count of all criteria entries
482 public final function countExclude () {
483 return $this->count('exclude');