Some updates:
[core.git] / framework / main / classes / criteria / class_BaseCriteria.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Criteria;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Criteria\Search\SearchCriteria;
7 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
8
9 /**
10  * A general crtieria class
11  *
12  * @author              Roland Haeder <webmaster@shipsimu.org>
13  * @version             0.0.0
14 <<<<<<< HEAD:framework/main/classes/criteria/class_BaseCriteria.php
15  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
16 =======
17  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2016 Core Developer Team
18 >>>>>>> Some updates::inc/main/classes/criteria/class_BaseCriteria.php
19  * @license             GNU GPL 3.0 or any newer version
20  * @link                http://www.shipsimu.org
21  *
22  * This program is free software: you can redistribute it and/or modify
23  * it under the terms of the GNU General Public License as published by
24  * the Free Software Foundation, either version 3 of the License, or
25  * (at your option) any later version.
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30  * GNU General Public License for more details.
31  *
32  * You should have received a copy of the GNU General Public License
33  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
34  */
35 abstract class BaseCriteria extends BaseFrameworkSystem implements Criteria {
36         /**
37          * Wrapper class name stored in config entry
38          */
39         private $wrapperConfigEntry = '';
40
41         /**
42          * Protected constructor
43          *
44          * @param       $className      Name of the class
45          * @return      void
46          */
47         protected function __construct ($className) {
48                 // Call parent constructor
49                 parent::__construct($className);
50
51                 // Initialize all criteria arrays
52                 foreach (array('default', 'choice', 'exclude') as $criteriaType) {
53                         // Init it
54                         $this->initGenericArrayKey('criteria', $criteriaType, 'entries');
55                 } // END - foreach
56         }
57
58         /**
59          * Checks whether given key is set
60          *
61          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
62          * @param       $criteriaKey    Criteria key
63          * @return      $isSet                  Whether key is set
64          */
65         public function isKeySet ($criteriaType, $criteriaKey) {
66                 // Make sure no 'my-' or 'my_' passes this point
67                 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
68
69                 // Determine it
70                 $isSet = $this->isGenericArrayElementSet('criteria', $criteriaType, 'entries', $criteriaKey);
71
72                 // Return it
73                 return $isSet;
74         }
75
76         /**
77          * Checks whether given key is set for 'choice' type
78          *
79          * @param       $criteriaKey    Criteria key
80          * @return      $isSet                  Whether key is set
81          */
82         public function isChoiceKeySet ($criteriaKey) {
83                 // Call inner method
84                 return $this->isKeySet('choice', $criteriaKey);
85         }
86
87         /**
88          * Checks whether given key is set for 'exclude' type
89          *
90          * @param       $criteriaKey    Criteria key
91          * @return      $isSet                  Whether key is set
92          */
93         public function isExcludeKeySet ($criteriaKey) {
94                 // Call inner method
95                 return $this->isKeySet('exclude', $criteriaKey);
96         }
97
98         /**
99          * Setter for wrapper class name
100          *
101          * @param       $wrapperConfigEntry             Configuration entry which hold the wrapper class' name
102          * @return      void
103          */
104         public final function setWrapperConfigEntry ($wrapperConfigEntry) {
105                 $this->wrapperConfigEntry = (string) $wrapperConfigEntry;
106         }
107
108         /**
109          * Getter for wrapper class name
110          *
111          * @return      $wrapperConfigEntry             Configuration entry which hold the wrapper class' name
112          */
113         public final function getWrapperConfigEntry () {
114                 return $this->wrapperConfigEntry;
115         }
116
117         /**
118          * Getter for criteria array
119          *
120          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
121          * @return      $criteria
122          */
123         public final function getCriteriaArray ($criteriaType = 'default') {
124                 return $this->getGenericArrayKey('criteria', $criteriaType, 'entries');
125         }
126
127         /**
128          * Getter for criteria array 'choice' type
129          *
130          * @return      $criteria
131          */
132         public final function getCriteriaChoiceArray () {
133                 return $this->getCriteriaArray('choice');
134         }
135
136         /**
137          * Getter for criteria array 'exclude' type
138          *
139          * @return      $criteria
140          */
141         public final function getCriteriaExcludeArray () {
142                 return $this->getCriteriaArray('exclude');
143         }
144
145         /**
146          * Unsets a criteria key from all criteria types
147          *
148          * @param       $criteriaKey    Criteria key to unset
149          * @return      void
150          */
151         public final function unsetCriteria ($criteriaKey) {
152                 // Make sure no 'my-' or 'my_' passes this point
153                 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
154
155                 // Convert dashes to underscore
156                 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
157
158                 // "Walk" through all criterias
159                 foreach ($this->getGenericArray('criteria') as $criteriaType => $dummy) {
160                         // Remove it
161                         $this->unsetGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
162                 } // END - foreach
163         }
164
165         /**
166          * Add criteria, this method converts dashes to underscores because dashes
167          * are not valid for criteria keys.
168          *
169          * @param       $criteriaKey    Criteria key
170          * @param       $criteriaValue  Criteria value
171          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
172          * @return      void
173          */
174         public final function addCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
175                 // Debug message
176                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
177
178                 // Make sure no 'my-' or 'my_' passes this point
179                 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
180
181                 // Convert dashes to underscore
182                 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
183
184                 // Debug message
185                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey);
186
187                 // Append it
188                 $this->appendStringToGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
189         }
190
191         /**
192          * Set criteria, this method converts dashes to underscores because dashes
193          * are not valid for criteria keys.
194          *
195          * @param       $criteriaKey    Criteria key
196          * @param       $criteriaValue  Criteria value
197          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
198          * @return      void
199          */
200         public final function setCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
201                 // Debug message
202                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue . ',criteriaType=' . $criteriaType . ' - CALLED!');
203
204                 // Make sure no 'my-' or 'my_' passes this point
205                 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
206
207                 // Convert dashes to underscore
208                 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
209
210                 // Debug message
211                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey);
212
213                 // Set it
214                 $this->setStringGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey, $criteriaValue);
215         }
216
217         /**
218          * Add "choice" criteria, this method converts dashes to underscores because
219          * dashes are not valid for criteria keys.
220          *
221          * @param       $criteriaKey    Criteria key
222          * @param       $criteriaValue  Criteria value
223          * @return      void
224          */
225         public final function addChoiceCriteria ($criteriaKey, $criteriaValue) {
226                 // Make sure no 'my-' or 'my_' passes this point
227                 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
228
229                 // Debug message
230                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '(' . $this->__toString() . ')-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
231
232                 // Add it
233                 $this->pushValueToGenericArrayElement('criteria', 'choice', 'entries', self::convertDashesToUnderscores($criteriaKey), (string) $criteriaValue);
234         }
235
236         /**
237          * Add "exclude" criteria, this method converts dashes to underscores because
238          * dashes are not valid for criteria keys.
239          *
240          * @param       $criteriaKey    Criteria key
241          * @param       $criteriaValue  Criteria value
242          * @return      void
243          */
244         public final function addExcludeCriteria ($criteriaKey, $criteriaValue) {
245                 // Add it with generic method
246                 $this->addCriteria($criteriaKey, $criteriaValue, 'exclude');
247         }
248
249         /**
250          * Add configured criteria
251          *
252          * @param       $criteriaKey    Criteria key
253          * @param       $configEntry    Configuration entry
254          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
255          * @return      void
256          */
257         public final function addConfiguredCriteria ($criteriaKey, $configEntry, $criteriaType = 'default') {
258                 // Add the configuration entry as a criteria
259                 $value = $this->getConfigInstance()->getConfigEntry($configEntry);
260                 $this->addCriteria($criteriaKey, $value, $criteriaType);
261         }
262
263         /**
264          * Get criteria element or false if not found
265          *
266          * @param       $criteriaKey    The requested criteria key
267          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
268          * @return      $value                  Whether the value of the critera or false
269          */
270         public function getCriteriaElemnent ($criteriaKey, $criteriaType = 'default') {
271                 // Debug message
272                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteriaType=' . $criteriaType . ' - CALLED!');
273
274                 // Make sure no 'my-' or 'my_' passes this point
275                 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false));
276
277                 // Convert dashes to underscore
278                 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
279
280                 // Debug message
281                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: criteriaKey=' . $criteriaKey . ',criteria()=' . $this->countGenericArrayGroup('criteria', $criteriaType));
282
283                 // Default is not found
284                 $value = false;
285
286                 // Is the criteria there?
287                 if ($this->isKeySet($criteriaType, $criteriaKey)) {
288                         // Then use it
289                         $value = $this->getGenericArrayElement('criteria', $criteriaType, 'entries', $criteriaKey);
290                 } // END - if
291
292                 // Debug message
293                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA[' . __METHOD__ . ':' . __LINE__ . ']: value=' . $value . ' - EXIT!');
294
295                 // Return the value
296                 return $value;
297         }
298
299         /**
300          * Get criteria element or false if not found for 'choice' type
301          *
302          * @param       $criteriaKey    The requested criteria key
303          * @return      $value                  Whether the value of the critera or false
304          */
305         public function getCriteriaChoiceElemnent ($criteriaKey) {
306                 // Call inner method
307                 return $this->getCriteriaElemnent($criteriaKey, 'choice');
308         }
309
310         /**
311          * Get criteria element or false if not found for 'exclude' type
312          *
313          * @param       $criteriaKey    The requested criteria key
314          * @return      $value                  Whether the value of the critera or false
315          */
316         public function getCriteriaExcludeElemnent ($criteriaKey) {
317                 // Call inner method
318                 return $this->getCriteriaElemnent($criteriaKey, 'exclude');
319         }
320
321         /**
322          * Checks whether given array entry matches
323          *
324          * @param       $entryArray             Array with the entries to find
325          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
326          * @return      $matches                Whether the entry matches or not
327          */
328         public function ifEntryMatches (array $entryArray, $criteriaType = 'default') {
329                 // First nothing matches and nothing is counted
330                 $matches = false;
331                 $counted = 0;
332
333                 // Walk through all entries
334                 foreach ($entryArray as $key => $entry) {
335                         // Make sure no 'my-' or 'my_' passes this point
336                         assert((strpos($key, 'my-') === false) && (strpos($key, 'my_') === false));
337
338                         // Convert dashes to underscore
339                         $key = self::convertDashesToUnderscores($key);
340
341                         // Then walk through all search criteria
342                         foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
343                                 // Make sure no 'my-' or 'my_' passes this point
344                                 assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
345
346                                 // Convert dashes to underscore
347                                 $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
348
349                                 // Is the element found and does it match?
350                                 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
351                                         // Then count this one up
352                                         $counted++;
353                                 } // END - if
354                         } // END - foreach
355                 } // END - foreach
356
357                 // Now check if expected criteria counts match
358                 $matches = ($counted == $this->countGenericArrayGroup('criteria', $criteriaType));
359
360                 // Return the result
361                 return $matches;
362         }
363
364         /**
365          * Checks whether given array 'choice' 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 ifChoiceMatches (array $entryArray) {
371                 // Call inner method
372                 return $this->ifEntryMatches($entryArray, 'choice');
373         }
374
375         /**
376          * Checks whether given array 'exclude' entry matches
377          *
378          * @param       $entryArray             Array with the entries to find
379          * @return      $matches                Whether the entry matches or not
380          */
381         public function ifExcludeMatches (array $entryArray) {
382                 // Call inner method
383                 return $this->ifEntryMatches($entryArray, 'exclude');
384         }
385
386         /**
387          * "Getter" for a cache key
388          *
389          * @param       $onlyKeys       Only use these keys for a cache key
390          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
391          * @return      $cacheKey       The key suitable for the cache system
392          */
393         public function getCacheKey ($onlyKeys = array(), $criteriaType = 'default') {
394                 // Debug message
395                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . ': criteriaType=' . $criteriaType . ',count()=' . $this->countGenericArray('criteria')));
396
397                 // Make sure the criteria is there
398                 assert($this->isValidGenericArrayGroup('criteria', $criteriaType));
399
400                 // Initialize the key
401                 $cacheKey = '';
402
403                 // Now walk through all criterias
404                 foreach ($this->getGenericArrayKey('criteria', $criteriaType, 'entries') as $criteriaKey => $criteriaValue) {
405                         // Make sure no 'my-' or 'my_' passes this point
406                         assert((strpos($criteriaKey, 'my-') === false) && (strpos($criteriaKey, 'my_') === false) && (!is_bool($criteriaValue)));
407
408                         // $criteriaValue cannot be an array
409                         assert(!is_array($criteriaValue));
410
411                         // Convert dashes to underscore
412                         $criteriaKey = self::convertDashesToUnderscores($criteriaKey);
413
414                         // Is the value in array or is $onlyKeys empty?
415                         if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
416                                 // Add the value URL encoded to avoid any trouble with special characters
417                                 $cacheKey .= sprintf('%s=%s;',
418                                         $criteriaKey,
419                                         urlencode($criteriaValue)
420                                 );
421                         } // END - if
422                 } // END - foreach
423
424                 // Remove last semicolon
425                 $cacheKey = substr($cacheKey, 0, -1);
426
427                 // Is the instance SearchCriteria?
428                 if ($this instanceof SearchCriteria) {
429                         // Check if 'limit' and 'skip' are in
430                         if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
431                                 // Add limit and skip values
432                                 $cacheKey .= sprintf(';%%limit%%=%s;%%skip%%=%s',
433                                         $this->getLimit(),
434                                         $this->getSkip()
435                                 );
436                         } // END - if
437                 } // END - if
438
439                 // Return the cache key
440                 return $cacheKey;
441         }
442
443         /**
444          * "Getter" for a cache key ('choice' 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 getCacheKeyChoice ($onlyKeys = array()) {
450                 // Call inner method
451                 return $this->getCacheKey($onlyKeys, 'choice');
452         }
453
454         /**
455          * "Getter" for a cache key ('exclude' type)
456          *
457          * @param       $onlyKeys       Only use these keys for a cache key
458          * @return      $cacheKey       The key suitable for the cache system
459          */
460         public function getCacheKeyExclude ($onlyKeys = array()) {
461                 // Call inner method
462                 return $this->getCacheKey($onlyKeys, 'exclude');
463         }
464
465         /**
466          * Count the criteria, e.g. useful to find out if a database query has no
467          * limitation (search criteria).
468          *
469          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
470          * @return      $count  Count of all criteria entries
471          */
472         public final function count ($criteriaType = 'default') {
473                 // Return it
474                 return $this->countGenericArrayGroup('criteria', $criteriaType);
475         }
476
477         /**
478          * Count 'choice' criteria, e.g. useful to find out if a database query
479          * has no limitation (search criteria).
480          *
481          * @return      $count  Count of all criteria entries
482          */
483         public final function countChoice () {
484                 return $this->count('choice');
485         }
486
487         /**
488          * Count 'exclude' criteria, e.g. useful to find out if a database query
489          * has no limitation (search criteria).
490          *
491          * @return      $count  Count of all criteria entries
492          */
493         public final function countExclude () {
494                 return $this->count('exclude');
495         }
496
497 }