Opps, forgot this.
[core.git] / inc / classes / main / criteria / class_BaseCriteria.php
1 <?php
2 /**
3  * A general crtieria class
4  *
5  * @author              Roland Haeder <webmaster@shipsimu.org>
6  * @version             0.0.0
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
10  *
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.
15  *
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.
20  *
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/>.
23  */
24 class BaseCriteria extends BaseFrameworkSystem implements Criteria {
25         /**
26          * Wrapper class name stored in config entry
27          */
28         private $wrapperConfigEntry = '';
29
30         /**
31          * Protected constructor
32          *
33          * @param       $className      Name of the class
34          * @return      void
35          */
36         protected function __construct ($className) {
37                 // Call parent constructor
38                 parent::__construct($className);
39
40                 // Initialize all criteria arrays
41                 foreach (array('default', 'choice', 'exclude') as $criteriaType) {
42                         // Init it
43                         $this->initGenericArrayKey('criteria', $criteriaType, 'entries');
44                 } // END - foreach
45         }
46
47         /**
48          * Checks whether given key is set
49          *
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
53          */
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));
57
58                 // Determine it
59                 $isSet = $this->isGenericArrayElementSet('criteria', $criteriaType, 'entries', $criteriaKey);
60
61                 // Return it
62                 return $isSet;
63         }
64
65         /**
66          * Checks whether given key is set for 'choice' type
67          *
68          * @param       $criteriaKey    Criteria key
69          * @return      $isSet                  Whether key is set
70          */
71         public function isChoiceKeySet ($criteriaKey) {
72                 // Call inner method
73                 return $this->isKeySet('choice', $criteriaKey);
74         }
75
76         /**
77          * Checks whether given key is set for 'exclude' type
78          *
79          * @param       $criteriaKey    Criteria key
80          * @return      $isSet                  Whether key is set
81          */
82         public function isExcludeKeySet ($criteriaKey) {
83                 // Call inner method
84                 return $this->isKeySet('exclude', $criteriaKey);
85         }
86
87         /**
88          * Setter for wrapper class name
89          *
90          * @param       $wrapperConfigEntry             Configuration entry which hold the wrapper class' name
91          * @return      void
92          */
93         public final function setWrapperConfigEntry ($wrapperConfigEntry) {
94                 $this->wrapperConfigEntry = (string) $wrapperConfigEntry;
95         }
96
97         /**
98          * Getter for wrapper class name
99          *
100          * @return      $wrapperConfigEntry             Configuration entry which hold the wrapper class' name
101          */
102         public final function getWrapperConfigEntry () {
103                 return $this->wrapperConfigEntry;
104         }
105
106         /**
107          * Getter for criteria array
108          *
109          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
110          * @return      $criteria
111          */
112         public final function getCriteriaArray ($criteriaType = 'default') {
113                 return $this->getGenericArrayKey('criteria', $criteriaType, 'entries');
114         }
115
116         /**
117          * Getter for criteria array 'choice' type
118          *
119          * @return      $criteria
120          */
121         public final function getCriteriaChoiceArray () {
122                 return $this->getCriteriaArray('choice');
123         }
124
125         /**
126          * Getter for criteria array 'exclude' type
127          *
128          * @return      $criteria
129          */
130         public final function getCriteriaExcludeArray () {
131                 return $this->getCriteriaArray('exclude');
132         }
133
134         /**
135          * Unsets a criteria key from all criteria types
136          *
137          * @param       $criteriaKey    Criteria key to unset
138          * @return      void
139          */
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));
143
144                 // Convert dashes to underscore
145                 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
146
147                 // "Walk" through all criterias
148                 foreach ($this->getGenericArray('criteria') as $criteriaType => $dummy) {
149                         // Remove it
150                         $this->unsetGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
151                 } // END - foreach
152         }
153
154         /**
155          * Add criteria, this method converts dashes to underscores because dashes
156          * are not valid for criteria keys.
157          *
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'
161          * @return      void
162          */
163         public final function addCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
164                 // Debug message
165                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
166
167                 // Make sure no 'my-' or 'my_' passes this point
168                 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
169
170                 // Convert dashes to underscore
171                 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
172
173                 // Debug message
174                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey);
175
176                 // Append it
177                 $this->appendStringToGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
178         }
179
180         /**
181          * Set criteria, this method converts dashes to underscores because dashes
182          * are not valid for criteria keys.
183          *
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'
187          * @return      void
188          */
189         public final function setCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
190                 // Debug message
191                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
192
193                 // Make sure no 'my-' or 'my_' passes this point
194                 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
195
196                 // Convert dashes to underscore
197                 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
198
199                 // Debug message
200                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey);
201
202                 // Set it
203                 $this->setStringGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
204         }
205
206         /**
207          * Add "choice" criteria, this method converts dashes to underscores because
208          * dashes are not valid for criteria keys.
209          *
210          * @param       $criteriaKey    Criteria key
211          * @param       $criteriaValue  Criteria value
212          * @return      void
213          */
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)));
217
218                 // Debug message
219                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
220
221                 // Add it
222                 $this->pushValueToGenericArrayElement('criteria', 'choice', 'entries', self::convertDashesToUnderscores($criteriaKey), (string) $criteriaValue);
223         }
224
225         /**
226          * Add "exclude" criteria, this method converts dashes to underscores because
227          * dashes are not valid for criteria keys.
228          *
229          * @param       $criteriaKey    Criteria key
230          * @param       $criteriaValue  Criteria value
231          * @return      void
232          */
233         public final function addExcludeCriteria ($criteriaKey, $criteriaValue) {
234                 // Add it with generic method
235                 $this->addCriteria($criteriaKey, $criteriaValue, 'exclude');
236         }
237
238         /**
239          * Add configured criteria
240          *
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'
244          * @return      void
245          */
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);
250         }
251
252         /**
253          * Get criteria element or FALSE if not found
254          *
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
258          */
259         public function getCriteriaElemnent ($criteriaKey, $criteriaType = 'default') {
260                 // Debug message
261                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaType=' . $criteriaType . ' - CALLED!');
262
263                 // Make sure no 'my-' or 'my_' passes this point
264                 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE));
265
266                 // Convert dashes to underscore
267                 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
268
269                 // Debug message
270                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteria()=' . $this->countGenericArrayGroup('criteria', $criteriaType));
271
272                 // Default is not found
273                 $value = FALSE;
274
275                 // Is the criteria there?
276                 if ($this->isKeySet($criteriaType, $criteriaKey)) {
277                         // Then use it
278                         $value = $this->getGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
279                 } // END - if
280
281                 // Debug message
282                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: value=' . $value . ' - EXIT!');
283
284                 // Return the value
285                 return $value;
286         }
287
288         /**
289          * Get criteria element or FALSE if not found for 'choice' type
290          *
291          * @param       $criteriaKey    The requested criteria key
292          * @return      $value                  Whether the value of the critera or FALSE
293          */
294         public function getCriteriaChoiceElemnent ($criteriaKey) {
295                 // Call inner method
296                 return $this->getCriteriaElemnent($criteriaKey, 'choice');
297         }
298
299         /**
300          * Get criteria element or FALSE if not found for 'exclude' type
301          *
302          * @param       $criteriaKey    The requested criteria key
303          * @return      $value                  Whether the value of the critera or FALSE
304          */
305         public function getCriteriaExcludeElemnent ($criteriaKey) {
306                 // Call inner method
307                 return $this->getCriteriaElemnent($criteriaKey, 'exclude');
308         }
309
310         /**
311          * Checks whether given array entry matches
312          *
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
316          */
317         public function ifEntryMatches (array $entryArray, $criteriaType = 'default') {
318                 // First nothing matches and nothing is counted
319                 $matches = FALSE;
320                 $counted = 0;
321
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));
326
327                         // Convert dashes to underscore
328                         $key = self::convertDashesToUnderscores($key);
329
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)));
334
335                                 // Convert dashes to underscore
336                                 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
337
338                                 // Is the element found and does it match?
339                                 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
340                                         // Then count this one up
341                                         $counted++;
342                                 } // END - if
343                         } // END - foreach
344                 } // END - foreach
345
346                 // Now check if expected criteria counts match
347                 $matches = ($counted == $this->countGenericArrayGroup('criteria', $criteriaType));
348
349                 // Return the result
350                 return $matches;
351         }
352
353         /**
354          * Checks whether given array 'choice' entry matches
355          *
356          * @param       $entryArray             Array with the entries to find
357          * @return      $matches                Whether the entry matches or not
358          */
359         public function ifChoiceMatches (array $entryArray) {
360                 // Call inner method
361                 return $this->ifEntryMatches($entryArray, 'choice');
362         }
363
364         /**
365          * Checks whether given array 'exclude' entry matches
366          *
367          * @param       $entryArray             Array with the entries to find
368          * @return      $matches                Whether the entry matches or not
369          */
370         public function ifExcludeMatches (array $entryArray) {
371                 // Call inner method
372                 return $this->ifEntryMatches($entryArray, 'exclude');
373         }
374
375         /**
376          * "Getter" for a cache key
377          *
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
381          */
382         public function getCacheKey ($onlyKeys = array(), $criteriaType = 'default') {
383                 // Debug message
384                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ': criteriaType=' . $criteriaType . ',count()=' . $this->countGenericArray('criteria')));
385
386                 // Make sure the criteria is there
387                 assert($this->isValidGenericArrayGroup('criteria', $criteriaType));
388
389                 // Initialize the key
390                 $cacheKey = '';
391
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)));
396
397                         // $criteriaValue cannot be an array
398                         assert(!is_array($criteriaValue));
399
400                         // Convert dashes to underscore
401                         $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
402
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;',
407                                         $criteriaKey,
408                                         urlencode($criteriaValue)
409                                 );
410                         } // END - if
411                 } // END - foreach
412
413                 // Remove last semicolon
414                 $cacheKey = substr($cacheKey, 0, -1);
415
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',
422                                         $this->getLimit(),
423                                         $this->getSkip()
424                                 );
425                         } // END - if
426                 } // END - if
427
428                 // Return the cache key
429                 return $cacheKey;
430         }
431
432         /**
433          * "Getter" for a cache key ('choice' type)
434          *
435          * @param       $onlyKeys       Only use these keys for a cache key
436          * @return      $cacheKey       The key suitable for the cache system
437          */
438         public function getCacheKeyChoice ($onlyKeys = array()) {
439                 // Call inner method
440                 return $this->getCacheKey($onlyKeys, 'choice');
441         }
442
443         /**
444          * "Getter" for a cache key ('exclude' type)
445          *
446          * @param       $onlyKeys       Only use these keys for a cache key
447          * @return      $cacheKey       The key suitable for the cache system
448          */
449         public function getCacheKeyExclude ($onlyKeys = array()) {
450                 // Call inner method
451                 return $this->getCacheKey($onlyKeys, 'exclude');
452         }
453
454         /**
455          * Count the criteria, e.g. useful to find out if a database query has no
456          * limitation (search criteria).
457          *
458          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
459          * @return      $count  Count of all criteria entries
460          */
461         public final function count ($criteriaType = 'default') {
462                 // Return it
463                 return $this->countGenericArrayGroup('criteria', $criteriaType);
464         }
465
466         /**
467          * Count 'choice' criteria, e.g. useful to find out if a database query
468          * has no limitation (search criteria).
469          *
470          * @return      $count  Count of all criteria entries
471          */
472         public final function countChoice () {
473                 return $this->count('choice');
474         }
475
476         /**
477          * Count 'exclude' criteria, e.g. useful to find out if a database query
478          * has no limitation (search criteria).
479          *
480          * @return      $count  Count of all criteria entries
481          */
482         public final function countExclude () {
483                 return $this->count('exclude');
484         }
485 }
486
487 // [EOF]
488 ?>