Let's see if this works better.
[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 = $this->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                 // Make sure no 'my-' or 'my_' passes this point
165                 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
166
167                 // Convert dashes to underscore
168                 $criteriaKey = $this->convertDashesToUnderscores($criteriaKey);
169
170                 // Debug message
171                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
172
173                 // Append it
174                 $this->appendStringToGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
175         }
176
177         /**
178          * Add "choice" criteria, this method converts dashes to underscores because
179          * dashes are not valid for criteria keys.
180          *
181          * @param       $criteriaKey    Criteria key
182          * @param       $criteriaValue  Criteria value
183          * @return      void
184          */
185         public final function addChoiceCriteria ($criteriaKey, $criteriaValue) {
186                 // Make sure no 'my-' or 'my_' passes this point
187                 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
188
189                 // Debug message
190                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
191
192                 // Add it
193                 $this->pushValueToGenericArrayElement('criteria', 'choice', 'entries', $this->convertDashesToUnderscores($criteriaKey), (string) $criteriaValue);
194         }
195
196         /**
197          * Add "exclude" criteria, this method converts dashes to underscores because
198          * dashes are not valid for criteria keys.
199          *
200          * @param       $criteriaKey    Criteria key
201          * @param       $criteriaValue  Criteria value
202          * @return      void
203          */
204         public final function addExcludeCriteria ($criteriaKey, $criteriaValue) {
205                 // Add it with generic method
206                 $this->addCriteria($criteriaKey, $criteriaValue, 'exclude');
207         }
208
209         /**
210          * Add configured criteria
211          *
212          * @param       $criteriaKey    Criteria key
213          * @param       $configEntry    Configuration entry
214          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
215          * @return      void
216          */
217         public final function addConfiguredCriteria ($criteriaKey, $configEntry, $criteriaType = 'default') {
218                 // Add the configuration entry as a criteria
219                 $value = $this->getConfigInstance()->getConfigEntry($configEntry);
220                 $this->addCriteria($criteriaKey, $value, $criteriaType);
221         }
222
223         /**
224          * Get criteria element or FALSE if not found
225          *
226          * @param       $criteriaKey    The requested criteria key
227          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
228          * @return      $value                  Whether the value of the critera or FALSE
229          */
230         public function getCriteriaElemnent ($criteriaKey, $criteriaType = 'default') {
231                 // Make sure no 'my-' or 'my_' passes this point
232                 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE));
233
234                 // Convert dashes to underscore
235                 $criteriaKey = $this->convertDashesToUnderscores($criteriaKey);
236
237                 // Debug message
238                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteria()=' . $this->countGenericArrayGroup('criteria', $criteriaType)));
239
240                 // Default is not found
241                 $value = FALSE;
242
243                 // Is the criteria there?
244                 if ($this->isKeySet($criteriaType, $criteriaKey)) {
245                         // Then use it
246                         $value = $this->getGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
247                 } // END - if
248
249                 // Return the value
250                 return $value;
251         }
252
253         /**
254          * Get criteria element or FALSE if not found for 'choice' type
255          *
256          * @param       $criteriaKey    The requested criteria key
257          * @return      $value                  Whether the value of the critera or FALSE
258          */
259         public function getCriteriaChoiceElemnent ($criteriaKey) {
260                 // Call inner method
261                 return $this->getCriteriaElemnent($criteriaKey, 'choice');
262         }
263
264         /**
265          * Get criteria element or FALSE if not found for 'exclude' type
266          *
267          * @param       $criteriaKey    The requested criteria key
268          * @return      $value                  Whether the value of the critera or FALSE
269          */
270         public function getCriteriaExcludeElemnent ($criteriaKey) {
271                 // Call inner method
272                 return $this->getCriteriaElemnent($criteriaKey, 'exclude');
273         }
274
275         /**
276          * Checks whether given array entry matches
277          *
278          * @param       $entryArray             Array with the entries to find
279          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
280          * @return      $matches                Whether the entry matches or not
281          */
282         public function ifEntryMatches (array $entryArray, $criteriaType = 'default') {
283                 // First nothing matches and nothing is counted
284                 $matches = FALSE;
285                 $counted = 0;
286
287                 // Walk through all entries
288                 foreach ($entryArray as $key => $entry) {
289                         // Make sure no 'my-' or 'my_' passes this point
290                         assert((strpos($key, 'my-') === FALSE) && (strpos($key, 'my_') === FALSE));
291
292                         // Convert dashes to underscore
293                         $key = $this->convertDashesToUnderscores($key);
294
295                         // Then walk through all search criteria
296                         foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
297                                 // Make sure no 'my-' or 'my_' passes this point
298                                 assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
299
300                                 // Convert dashes to underscore
301                                 $criteriaKey = $this->convertDashesToUnderscores($criteriaKey);
302
303                                 // Is the element found and does it match?
304                                 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
305                                         // Then count this one up
306                                         $counted++;
307                                 } // END - if
308                         } // END - foreach
309                 } // END - foreach
310
311                 // Now check if expected criteria counts match
312                 $matches = ($counted == $this->countGenericArrayGroup('criteria', $criteriaType));
313
314                 // Return the result
315                 return $matches;
316         }
317
318         /**
319          * Checks whether given array 'choice' entry matches
320          *
321          * @param       $entryArray             Array with the entries to find
322          * @return      $matches                Whether the entry matches or not
323          */
324         public function ifChoiceMatches (array $entryArray) {
325                 // Call inner method
326                 return $this->ifEntryMatches($entryArray, 'choice');
327         }
328
329         /**
330          * Checks whether given array 'exclude' entry matches
331          *
332          * @param       $entryArray             Array with the entries to find
333          * @return      $matches                Whether the entry matches or not
334          */
335         public function ifExcludeMatches (array $entryArray) {
336                 // Call inner method
337                 return $this->ifEntryMatches($entryArray, 'exclude');
338         }
339
340         /**
341          * "Getter" for a cache key
342          *
343          * @param       $onlyKeys       Only use these keys for a cache key
344          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
345          * @return      $cacheKey       The key suitable for the cache system
346          */
347         public function getCacheKey ($onlyKeys = array(), $criteriaType = 'default') {
348                 // Debug message
349                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ': criteriaType=' . $criteriaType . ',count()=' . $this->countGenericArray('criteria')));
350
351                 // Make sure the criteria is there
352                 assert($this->isValidGenericArrayGroup('criteria', $criteriaType));
353
354                 // Initialize the key
355                 $cacheKey = '';
356
357                 // Now walk through all criterias
358                 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
359                         // Make sure no 'my-' or 'my_' passes this point
360                         assert((strpos($criteriaKey, 'my-') === FALSE) && (strpos($criteriaKey, 'my_') === FALSE) && (!is_bool($criteriaValue)));
361
362                         // $criteriaValue cannot be an array
363                         assert(!is_array($criteriaValue));
364
365                         // Convert dashes to underscore
366                         $criteriaKey = $this->convertDashesToUnderscores($criteriaKey);
367
368                         // Is the value in array or is $onlyKeys empty?
369                         if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
370                                 // Add the value URL encoded to avoid any trouble with special characters
371                                 $cacheKey .= sprintf('%s=%s;',
372                                         $criteriaKey,
373                                         urlencode($criteriaValue)
374                                 );
375                         } // END - if
376                 } // END - foreach
377
378                 // Remove last semicolon
379                 $cacheKey = substr($cacheKey, 0, -1);
380
381                 // Is the instance SearchCriteria?
382                 if ($this instanceof SearchCriteria) {
383                         // Check if 'limit' and 'skip' are in
384                         if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
385                                 // Add limit and skip values
386                                 $cacheKey .= sprintf(';%%limit%%=%s;%%skip%%=%s',
387                                         $this->getLimit(),
388                                         $this->getSkip()
389                                 );
390                         } // END - if
391                 } // END - if
392
393                 // Return the cache key
394                 return $cacheKey;
395         }
396
397         /**
398          * "Getter" for a cache key ('choice' type)
399          *
400          * @param       $onlyKeys       Only use these keys for a cache key
401          * @return      $cacheKey       The key suitable for the cache system
402          */
403         public function getCacheKeyChoice ($onlyKeys = array()) {
404                 // Call inner method
405                 return $this->getCacheKey($onlyKeys, 'choice');
406         }
407
408         /**
409          * "Getter" for a cache key ('exclude' type)
410          *
411          * @param       $onlyKeys       Only use these keys for a cache key
412          * @return      $cacheKey       The key suitable for the cache system
413          */
414         public function getCacheKeyExclude ($onlyKeys = array()) {
415                 // Call inner method
416                 return $this->getCacheKey($onlyKeys, 'exclude');
417         }
418
419         /**
420          * Count the criteria, e.g. useful to find out if a database query has no
421          * limitation (search criteria).
422          *
423          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
424          * @return      $count  Count of all criteria entries
425          */
426         public final function count ($criteriaType = 'default') {
427                 // Return it
428                 return $this->countGenericArrayGroup('criteria', $criteriaType);
429         }
430
431         /**
432          * Count 'choice' criteria, e.g. useful to find out if a database query
433          * has no limitation (search criteria).
434          *
435          * @return      $count  Count of all criteria entries
436          */
437         public final function countChoice () {
438                 return $this->count('choice');
439         }
440
441         /**
442          * Count 'exclude' criteria, e.g. useful to find out if a database query
443          * has no limitation (search criteria).
444          *
445          * @return      $count  Count of all criteria entries
446          */
447         public final function countExclude () {
448                 return $this->count('exclude');
449         }
450 }
451
452 // [EOF]
453 ?>