170986c0caf9efc6899ac670cf1e23247189b3ea
[core.git] / inc / classes / main / criteria / search / class_SearchCriteria.php
1 <?php
2 /**
3  * Search criteria for e.g. searching in databases. Do not use this class if
4  * you are looking for a ship or company, or what ever. Instead use this class
5  * for looking in storages like the database.
6  *
7  * @author              Roland Haeder <webmaster@ship-simu.org>
8  * @version             0.0.0
9  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Core Developer Team
10  * @license             GNU GPL 3.0 or any newer version
11  * @link                http://www.ship-simu.org
12  *
13  * This program is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation, either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <http://www.gnu.org/licenses/>.
25  */
26 class SearchCriteria extends BaseCriteria implements LocalSearchCriteria {
27         /**
28          * Criteria to handle
29          */
30         private $criteria = array();
31
32         /**
33          * Limitation for the search
34          */
35         private $limit = 0;
36
37         /**
38          * Skip these entries before using them
39          */
40         private $skip = 0;
41
42         /**
43          * Protected constructor
44          *
45          * @return      void
46          */
47         protected function __construct () {
48                 // Call parent constructor
49                 parent::__construct(__CLASS__);
50         }
51
52         /**
53          * Create an instance of this class
54          *
55          * @return      $criteriaInstance       An instance of this criteria
56          */
57         public static final function createSearchCriteria () {
58                 // Get a new instance
59                 $criteriaInstance = new SearchCriteria();
60
61                 // Return this instance
62                 return $criteriaInstance;
63         }
64
65         /**
66          * Setter for limit
67          *
68          * @param       $limit  Search limit
69          * @return      void
70          * @todo        Find a nice casting here. (int) allows until and including 32766.
71          */
72         public final function setLimit ($limit) {
73                 $this->limit = $limit;
74         }
75
76         /**
77          * "Setter" for limit from a configuration entry
78          *
79          * @param       $configEntry    The configuration entry which hold a number as limit
80          * @return      void
81          */
82         public final function setConfiguredLimit ($configEntry) {
83                 // Get the limit from config entry and set it
84                 $limit = $this->getConfigInstance()->getConfigEntry($configEntry);
85                 $this->setLimit($limit);
86         }
87
88         /**
89          * Getter for limit
90          *
91          * @return      $limit  Search limit
92          */
93         public final function getLimit () {
94                 return $this->limit;
95         }
96
97         /**
98          * Setter for skip
99          *
100          * @param       $skip   Search skip
101          * @return      void
102          * @todo        Find a nice casting here. (int) allows until and including 32766.
103          */
104         public final function setSkip ($skip) {
105                 $this->skip = $skip;
106         }
107
108         /**
109          * Getter for skip
110          *
111          * @return      $skip   Search skip
112          */
113         public final function getSkip () {
114                 return $this->skip;
115         }
116
117         /**
118          * Checks whether the given key/value pair is matching with 'default' and one of 'choice' and
119          * never with in 'exclude'.
120          *
121          * @param       $key                    Key element to check
122          * @param       $value                  Value to check
123          * @param       $separator              Separator for "exploding" $value (default: ',')
124          * @return      $isMatching             Whether the key/value is matching or excluded
125          */
126         public function isCriteriaMatching ($key, $value, $separator = ',') {
127                 // $value cannot be array
128                 assert(!is_array($value));
129
130                 // "Explode" value
131                 $valueArray = explode($separator, $value);
132
133                 // Debug message
134                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: key=' . $key . ',value=' . $value . ' - ENTERED!');
135
136                 // Get 'default' search value
137                 $searchDefault = $this->getCriteriaElemnent($key);
138
139                 // Debug message
140                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: getCriteriaElement(' . $key . ')[' . gettype($searchDefault) . ']=' . $searchDefault);
141
142                 // 'default' check
143                 $isMatching = ((!is_null($searchDefault)) && ($searchDefault == $value));
144
145                 // Debug message
146                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: getCriteriaElement(' . $key . ')[' . gettype($searchDefault) . ']=' . $searchDefault . ',isMatching=' . intval($isMatching));
147
148                 // Get 'choice' search value (can be NULL or $separator-separated string)
149                 $searchChoice = $this->getCriteriaChoiceElemnent($key);
150
151                 // Debug message
152                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: getCriteriaChoiceElement(' . $key . ')[' . gettype($searchChoice) . ']=' . print_r($searchChoice, TRUE));
153
154                 // 'choice' check
155                 if ((is_array($searchChoice)) && (count($valueArray) == 1)) {
156                         // $value is a single-search value, so use in_array()
157                         $isMatching = ((($isMatching === TRUE) || (is_null($searchDefault))) && ((is_null($searchChoice)) || ((is_array($searchChoice)) && (in_array($value, $searchChoice)))));
158
159                         // Debug message
160                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: getCriteriaChoiceElement(' . $key . ')[]=' . gettype($searchChoice) . ',value=' . $value . ',isMatching=' . intval($isMatching) . ' - SINGLE-MATCH');
161                 } elseif ((is_array($searchChoice)) && (count($valueArray) > 1)) {
162                         // $value is choice-search value, so check all entries
163                         $isMatching = ((is_null($searchDefault)) || ($isMatching === TRUE));
164                         $idx = 0;
165                         foreach ($valueArray as $idx => $match) {
166                                 // Debug message
167                                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: match=' . $match . ',count(searchChoice)=' . count($searchChoice));
168
169                                 // Is it found? (one is okay)
170                                 $isMatching = (($isMatching === TRUE) && (in_array($match, $searchChoice)));
171
172                                 // Debug message
173                                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: match=' . $match . ',isMatching=' . intval($isMatching));
174                         } // END - foreach
175
176                         // Debug message
177                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: getCriteriaChoiceElement(' . $key . ')[]=' . gettype($searchChoice) . ',valueArray()=' . count($valueArray) . ',idx=' . $idx . ',isMatching=' . intval($isMatching) . ' - CHOICE-MATCH');
178                 } else {
179                         // Choice-match is NULL?
180                         $isMatching = (($isMatching === TRUE) || (is_null($searchDefault)));
181
182                         // Debug message
183                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: getCriteriaChoiceElement(' . $key . ')[]=' . gettype($searchChoice) . ',value=' . $value . ',isMatching=' . intval($isMatching) . ' - NULL-MATCH');
184                 }
185
186                 // Debug message
187                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: getCriteriaChoiceElement(' . $key . ')[]=' . gettype($searchChoice) . ',isMatching=' . intval($isMatching));
188
189                 // Get 'exclude' search value
190                 $searchExclude = $this->getCriteriaExcludeElemnent($key);
191
192                 // Debug message
193                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: getCriteriaExcludeElement(' . $key . ')[' . gettype($searchExclude) . ']=' . $searchExclude);
194
195                 // 'exclude' check
196                 $isMatching = (((is_null($searchChoice)) || ($isMatching === TRUE)) && ((is_null($searchExclude)) || ($searchExclude != $value)));
197
198                 // Return result
199                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SEARCH-CRITERIA[' . __LINE__ . ']: key=' . $key . ',value=' . $value . ',isMatching=' . intval($isMatching) . ' - EXIT!');
200                 return $isMatching;
201         }
202 }
203
204 // [EOF]
205 ?>