Added assert, all arrays are empty initialized now
[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          * Checks whether given array entry matches
200          *
201          * @param       $entryArray             Array with the entries to find
202          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
203          * @return      $matches                Whether the entry matches or not
204          */
205         public function ifEntryMatches (array $entryArray, $criteriaType = 'default') {
206                 // First nothing matches and nothing is counted
207                 $matches = false;
208                 $counted = 0;
209
210                 // Walk through all entries
211                 foreach ($entryArray as $key => $entry) {
212                         // Convert dashes to underscore
213                         $key = $this->convertDashesToUnderscores($key);
214
215                         // Then walk through all search criteria
216                         foreach ($this->criteria[$criteriaType] as $criteriaKey => $criteriaValue) {
217                                 // Convert dashes to underscore
218                                 $criteriaKey = $this->convertDashesToUnderscores($criteriaKey);
219
220                                 // Is the element found and does it match?
221                                 if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
222                                         // Then count this one up
223                                         $counted++;
224                                 } // END - if
225                         } // END - foreach
226                 } // END - foreach
227
228                 // Now check if expected criteria counts match
229                 $matches = ($counted == count($this->criteria[$criteriaType]));
230
231                 // Return the result
232                 return $matches;
233         }
234
235         /**
236          * Checks whether given array 'choice' entry matches
237          *
238          * @param       $entryArray             Array with the entries to find
239          * @return      $matches                Whether the entry matches or not
240          */
241         public function ifChoiceMatches (array $entryArray) {
242                 // Call inner method
243                 return $this->ifEntryMatches($entryArray, 'choice');
244         }
245
246         /**
247          * Checks whether given array 'exclude' entry matches
248          *
249          * @param       $entryArray             Array with the entries to find
250          * @return      $matches                Whether the entry matches or not
251          */
252         public function ifExcludeMatches (array $entryArray) {
253                 // Call inner method
254                 return $this->ifEntryMatches($entryArray, 'exclude');
255         }
256
257         /**
258          * "Getter" for a cache key
259          *
260          * @param       $onlyKeys       Only use these keys for a cache key
261          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
262          * @return      $cacheKey       The key suitable for the cache system
263          */
264         public function getCacheKey ($onlyKeys = array(), $criteriaType = 'default') {
265                 // Debug message
266                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ': criteriaType=' . $criteriaType . ',count()=' . count($this->criteria));
267
268                 // Make sure the criteria is there
269                 assert((isset($this->criteria[$criteriaType])) && (is_array($this->criteria[$criteriaType])));
270
271                 // Initialize the key
272                 $cacheKey = '';
273
274                 // Now walk through all criterias
275                 foreach ($this->criteria[$criteriaType] as $criteriaKey => $criteriaValue) {
276                         // Convert dashes to underscore
277                         $criteriaKey = $this->convertDashesToUnderscores($criteriaKey);
278
279                         // Is the value in array or is $onlyKeys empty?
280                         if ((isset($onlyKeys[$criteriaKey])) || (count($onlyKeys) == 0)) {
281                                 // Add the value URL encoded to avoid any trouble with special characters
282                                 $cacheKey .= sprintf("%s=%s;",
283                                         $criteriaKey,
284                                         urlencode($criteriaValue)
285                                 );
286                         } // END - if
287                 } // END - foreach
288
289                 // Remove last semicolon
290                 $cacheKey = substr($cacheKey, 0, -1);
291
292                 // Is the instance SearchCriteria?
293                 if ($this instanceof SearchCriteria) {
294                         // Check if 'limit' and 'skip' are in
295                         if (((isset($onlyKeys['limit'])) && (isset($onlyKeys['skip']))) || (count($onlyKeys) == 0)) {
296                                 // Add limit and skip values
297                                 $cacheKey .= sprintf(";%%limit%%=%s;%%skip%%=%s",
298                                         $this->getLimit(),
299                                         $this->getSkip()
300                                 );
301                         } // END - if
302                 } // END - if
303
304                 // Return the cache key
305                 return $cacheKey;
306         }
307
308         /**
309          * "Getter" for a cache key ('choice' type)
310          *
311          * @param       $onlyKeys       Only use these keys for a cache key
312          * @return      $cacheKey       The key suitable for the cache system
313          */
314         public function getCacheKeyChoice ($onlyKeys = array()) {
315                 // Call inner method
316                 return $this->getCacheKey($onlyKeys, 'choice');
317         }
318
319         /**
320          * "Getter" for a cache key ('exclude' type)
321          *
322          * @param       $onlyKeys       Only use these keys for a cache key
323          * @return      $cacheKey       The key suitable for the cache system
324          */
325         public function getCacheKeyExclude ($onlyKeys = array()) {
326                 // Call inner method
327                 return $this->getCacheKey($onlyKeys, 'exclude');
328         }
329
330         /**
331          * Count the criteria, e.g. useful to find out if a database query has no
332          * limitation (search criteria).
333          *
334          * @param       $criteriaType   Type of this criteria, can be one of 'default' (default), 'choice' or 'exclude'
335          * @return      $count  Count of all criteria entries
336          */
337         public final function count ($criteriaType = 'default') {
338                 // Return it
339                 return count($this->criteria[$criteriaType]);
340         }
341
342         /**
343          * Count 'choice' criteria, e.g. useful to find out if a database query
344          * has no limitation (search criteria).
345          *
346          * @return      $count  Count of all criteria entries
347          */
348         public final function countChoice () {
349                 return $this->count('choice');
350         }
351
352         /**
353          * Count 'exclude' criteria, e.g. useful to find out if a database query
354          * has no limitation (search criteria).
355          *
356          * @return      $count  Count of all criteria entries
357          */
358         public final function countExclude () {
359                 return $this->count('exclude');
360         }
361 }
362
363 // [EOF]
364 ?>