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