3b97b8b5f432d1b4fad74e23e9151d54671bf66b
[core.git] / inc / classes / main / criteria / class_BaseCriteria.php
1 <?php
2 /**
3  * A general crtieria class
4  *
5  * @author              Roland Haeder <webmaster@ship-simu.org>
6  * @version             0.0.0
7  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Core Developer Team
8  * @license             GNU GPL 3.0 or any newer version
9  * @link                http://www.ship-simu.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          * Criteria to handle
32          */
33         private $criteria = array(
34                 // Default
35                 'default' => array(),
36                 // Choice
37                 'choice'  => array(),
38                 // .. and exclude
39                 'exclude' => array(),
40         );
41
42         /**
43          * Protected constructor
44          *
45          * @param       $className      Name of the class
46          * @return      void
47          */
48         protected function __construct ($className) {
49                 // Call parent constructor
50                 parent::__construct($className);
51         }
52
53         /**
54          * Setter for wrapper class name
55          *
56          * @param       $wrapperConfigEntry             Configuration entry which hold the wrapper class' name
57          * @return      void
58          */
59         public final function setWrapperConfigEntry ($wrapperConfigEntry) {
60                 $this->wrapperConfigEntry = (string) $wrapperConfigEntry;
61         }
62
63         /**
64          * Getter for wrapper class name
65          *
66          * @return      $wrapperConfigEntry             Configuration entry which hold the wrapper class' name
67          */
68         public final function getWrapperConfigEntry () {
69                 return $this->wrapperConfigEntry;
70         }
71
72         /**
73          * Getter for criteria array
74          *
75          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
76          * @return      $criteria
77          */
78         public final function getCriteriaArray ($criteriaType = 'default') {
79                 return $this->criteria[$criteriaType];
80         }
81
82         /**
83          * Getter for criteria array 'choice' type
84          *
85          * @return      $criteria
86          */
87         public final function getCriteriaChoiceArray () {
88                 return $this->getCriteriaArray('choice');
89         }
90
91         /**
92          * Getter for criteria array 'exclude' type
93          *
94          * @return      $criteria
95          */
96         public final function getCriteriaExcludeArray () {
97                 return $this->getCriteriaArray('exclude');
98         }
99
100         /**
101          * Add criteria, this method converts dashes to underscores because dashes
102          * are not valid for criteria keys.
103          *
104          * @param       $criteriaKey    Criteria key
105          * @param       $criteriaValue  Criteria value
106          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
107          * @return      void
108          */
109         public final function addCriteria ($criteriaKey, $criteriaValue, $criteriaType = 'default') {
110                 // Debug message
111                 if (strpos($criteriaKey, 'my-') !== false) $this->debugBackTrace('criteriaKey=' . $criteriaKey);
112                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($criteriaType) . '-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
113
114                 // Convert dashes to underscore
115                 $criteriaKey = $this->convertDashesToUnderscores($criteriaKey);
116
117                 // Is it already there?
118                 if (isset($this->criteria[$criteriaType][$criteriaKey])) {
119                         // Append it
120                         $this->criteria[$criteriaType][$criteriaKey] .= ',' . $criteriaValue;
121                 } else {
122                         // Add it
123                         $this->criteria[$criteriaType][$criteriaKey] = (string) $criteriaValue;
124                 }
125         }
126
127         /**
128          * Add "choice" criteria, this method converts dashes to underscores because
129          * dashes are not valid for criteria keys.
130          *
131          * @param       $criteriaKey    Criteria key
132          * @param       $criteriaValue  Criteria value
133          * @return      void
134          */
135         public final function addChoiceCriteria ($criteriaKey, $criteriaValue) {
136                 // Debug message
137                 if (strpos($criteriaKey, 'my-') !== false) $this->debugBackTrace('criteriaKey=' . $criteriaKey);
138                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CHOICE-CRITERIA: criteriaKey=' . $criteriaKey . ',criteriaValue=' . $criteriaValue);
139
140                 // Add it
141                 $this->criteria['choice'][$this->convertDashesToUnderscores($criteriaKey)][] = (string) $criteriaValue;
142         }
143
144         /**
145          * Add "exclude" criteria, this method converts dashes to underscores because
146          * dashes are not valid for criteria keys.
147          *
148          * @param       $criteriaKey    Criteria key
149          * @param       $criteriaValue  Criteria value
150          * @return      void
151          */
152         public final function addExcludeCriteria ($criteriaKey, $criteriaValue) {
153                 // Add it with generic method
154                 $this->addCriteria($criteriaKey, $criteriaValue, 'exclude');
155         }
156
157         /**
158          * Add configured criteria
159          *
160          * @param       $criteriaKey    Criteria key
161          * @param       $configEntry    Configuration entry
162          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
163          * @return      void
164          */
165         public final function addConfiguredCriteria ($criteriaKey, $configEntry, $criteriaType = 'default') {
166                 // Add the configuration entry as a criteria
167                 $value = $this->getConfigInstance()->getConfigEntry($configEntry);
168                 $this->addCriteria($criteriaKey, $value, $criteriaType);
169         }
170
171         /**
172          * Get criteria element or null if not found
173          *
174          * @param       $criteriaKey    The requested criteria key
175          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
176          * @return      $value                  Whether the value of the critera or null
177          */
178         public function getCriteriaElemnent ($criteriaKey, $criteriaType = 'default') {
179                 // Convert dashes to underscore
180                 $criteriaKey = $this->convertDashesToUnderscores($criteriaKey);
181
182                 // Debug message
183                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CRITERIA: criteriaKey=' . $criteriaKey . ',criteria()=' . count($this->criteria[$criteriaType]));
184
185                 // Default is not found
186                 $value = NULL;
187
188                 // Is the criteria there?
189                 if (isset($this->criteria[$criteriaType][$criteriaKey])) {
190                         // Then use it
191                         $value = $this->criteria[$criteriaType][$criteriaKey];
192                 } // END - if
193
194                 // Return the value
195                 return $value;
196         }
197
198         /**
199          * Get criteria element or null if not found for 'choice' type
200          *
201          * @param       $criteriaKey    The requested criteria key
202          * @return      $value                  Whether the value of the critera or null
203          */
204         public function getCriteriaChoiceElemnent ($criteriaKey) {
205                 // Call inner method
206                 return $this->getCriteriaElemnent($criteriaKey, 'choice');
207         }
208
209         /**
210          * Get criteria element or null if not found for 'exclude' type
211          *
212          * @param       $criteriaKey    The requested criteria key
213          * @return      $value                  Whether the value of the critera or null
214          */
215         public function getCriteriaExcludeElemnent ($criteriaKey) {
216                 // Call inner method
217                 return $this->getCriteriaElemnent($criteriaKey, 'exclude');
218         }
219
220         /**
221          * Checks whether given array entry matches
222          *
223          * @param       $entryArray             Array with the entries to find
224          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
225          * @return      $matches                Whether the entry matches or not
226          */
227         public function ifEntryMatches (array $entryArray, $criteriaType = 'default') {
228                 // First nothing matches and nothing is counted
229                 $matches = false;
230                 $counted = 0;
231
232                 // Walk through all entries
233                 foreach ($entryArray as $key => $entry) {
234                         // Convert dashes to underscore
235                         $key = $this->convertDashesToUnderscores($key);
236
237                         // Then walk through all search criteria
238                         foreach ($this->criteria[$criteriaType] as $criteriaKey => $criteriaValue) {
239                                 // Convert dashes to underscore
240                                 $criteriaKey = $this->convertDashesToUnderscores($criteriaKey);
241
242                                 // Is the element found and does it match?
243                                 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
244                                         // Then count this one up
245                                         $counted++;
246                                 } // END - if
247                         } // END - foreach
248                 } // END - foreach
249
250                 // Now check if expected criteria counts match
251                 $matches = ($counted == count($this->criteria[$criteriaType]));
252
253                 // Return the result
254                 return $matches;
255         }
256
257         /**
258          * Checks whether given array 'choice' entry matches
259          *
260          * @param       $entryArray             Array with the entries to find
261          * @return      $matches                Whether the entry matches or not
262          */
263         public function ifChoiceMatches (array $entryArray) {
264                 // Call inner method
265                 return $this->ifEntryMatches($entryArray, 'choice');
266         }
267
268         /**
269          * Checks whether given array 'exclude' entry matches
270          *
271          * @param       $entryArray             Array with the entries to find
272          * @return      $matches                Whether the entry matches or not
273          */
274         public function ifExcludeMatches (array $entryArray) {
275                 // Call inner method
276                 return $this->ifEntryMatches($entryArray, 'exclude');
277         }
278
279         /**
280          * "Getter" for a cache key
281          *
282          * @param       $onlyKeys       Only use these keys for a cache key
283          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
284          * @return      $cacheKey       The key suitable for the cache system
285          */
286         public function getCacheKey ($onlyKeys = array(), $criteriaType = 'default') {
287                 // Debug message
288                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ': criteriaType=' . $criteriaType . ',count()=' . count($this->criteria));
289
290                 // Make sure the criteria is there
291                 assert((isset($this->criteria[$criteriaType])) && (is_array($this->criteria[$criteriaType])));
292
293                 // Initialize the key
294                 $cacheKey = '';
295
296                 // Now walk through all criterias
297                 foreach ($this->criteria[$criteriaType] as $criteriaKey => $criteriaValue) {
298                         // Convert dashes to underscore
299                         $criteriaKey = $this->convertDashesToUnderscores($criteriaKey);
300
301                         // Is the value in array or is $onlyKeys empty?
302                         if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
303                                 // Add the value URL encoded to avoid any trouble with special characters
304                                 $cacheKey .= sprintf("%s=%s;",
305                                         $criteriaKey,
306                                         urlencode($criteriaValue)
307                                 );
308                         } // END - if
309                 } // END - foreach
310
311                 // Remove last semicolon
312                 $cacheKey = substr($cacheKey, 0, -1);
313
314                 // Is the instance SearchCriteria?
315                 if ($this instanceof SearchCriteria) {
316                         // Check if 'limit' and 'skip' are in
317                         if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
318                                 // Add limit and skip values
319                                 $cacheKey .= sprintf(";%%limit%%=%s;%%skip%%=%s",
320                                         $this->getLimit(),
321                                         $this->getSkip()
322                                 );
323                         } // END - if
324                 } // END - if
325
326                 // Return the cache key
327                 return $cacheKey;
328         }
329
330         /**
331          * "Getter" for a cache key ('choice' type)
332          *
333          * @param       $onlyKeys       Only use these keys for a cache key
334          * @return      $cacheKey       The key suitable for the cache system
335          */
336         public function getCacheKeyChoice ($onlyKeys = array()) {
337                 // Call inner method
338                 return $this->getCacheKey($onlyKeys, 'choice');
339         }
340
341         /**
342          * "Getter" for a cache key ('exclude' type)
343          *
344          * @param       $onlyKeys       Only use these keys for a cache key
345          * @return      $cacheKey       The key suitable for the cache system
346          */
347         public function getCacheKeyExclude ($onlyKeys = array()) {
348                 // Call inner method
349                 return $this->getCacheKey($onlyKeys, 'exclude');
350         }
351
352         /**
353          * Count the criteria, e.g. useful to find out if a database query has no
354          * limitation (search criteria).
355          *
356          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
357          * @return      $count  Count of all criteria entries
358          */
359         public final function count ($criteriaType = 'default') {
360                 // Return it
361                 return count($this->criteria[$criteriaType]);
362         }
363
364         /**
365          * Count 'choice' criteria, e.g. useful to find out if a database query
366          * has no limitation (search criteria).
367          *
368          * @return      $count  Count of all criteria entries
369          */
370         public final function countChoice () {
371                 return $this->count('choice');
372         }
373
374         /**
375          * Count 'exclude' criteria, e.g. useful to find out if a database query
376          * has no limitation (search criteria).
377          *
378          * @return      $count  Count of all criteria entries
379          */
380         public final function countExclude () {
381                 return $this->count('exclude');
382         }
383 }
384
385 // [EOF]
386 ?>