Gentics Portal.Node PHP API
 All Classes Namespaces Functions Variables Pages
SearchApi.php
1 <?php
2 /**
3  * Gentics Portal.Node PHP
4  * Author & Copyright (c) by Gentics Software GmbH
5  * sales@gentics.com
6  * http://www.gentics.com
7  * Licenses can be found in the LICENSE.txt file in the root-folder of this installation
8  * You must not use this software without a valid license agreement.
9  *
10  */
11 class SearchApi extends CComponent
12 {
13  /**
14  * Overrided search url
15  *
16  * @public string
17  **/
18  public $searchUrl;
19 
20  /**
21  * Overrided autosuggest url
22  *
23  * @public string
24  **/
26 
27  private $_repositoryApi;
28 
29  /**
30  * Internal getter for repository api.
31  * It used to allows overriding of RepositoryApi properties by SearchApi properties
32  *
33  * @public RepositoryApi
34  **/
35  public function getRepositoryApi()
36  {
37  if(!$this->_repositoryApi) {
38  if(!empty($this->searchUrl) || !empty($this->autosuggestUrl)) {
39  $repositoryApi = clone Yii::app()->repositoryApi;
40  if(!empty($this->searchUrl)){
41  $repositoryApi->search = $this->searchUrl;
42  }
43  if(!empty($this->autosuggestUrl)){
44  $repositoryApi->autosuggest = $this->autosuggestUrl;
45  }
46  $this->_repositoryApi = $repositoryApi;
47  } else {
48  $this->_repositoryApi = Yii::app()->repositoryApi;
49  }
50  }
51  return $this->_repositoryApi;
52  }
53 
54  /**
55  * Counstructor
56  *
57  * @return void
58  **/
59  public function __construct($searchUrl = null, $autosuggestUrl = null)
60  {
61  $this->searchUrl = $searchUrl;
62  $this->autosuggestUrl = $autosuggestUrl;
63  }
64 
65 
66  /**
67  * method for search
68  *
69  * @param string $phrase text to find
70  * @param bool $usePersonalisation defines if personalization
71  *
72  * @return array
73  */
74  public function search($phrase, $params = array(), $start = null, $count = null)
75  {
76  if (!$this->_checkPhrase($phrase)) {
77  return false;
78  }
79  $whereToSearch = isset($params['whereToSearch']) ? $params['whereToSearch'] : Yii::app()->getModule('search')->whereToSearch['default'];
80  $mimetype = isset($params['mimetype']) ? $params['mimetype'] : Yii::app()->getModule('search')->mimetype['default'];
81  $searchType = isset($params['searchType']) ? $params['searchType'] : Yii::app()->getModule('search')->searchType['default'];
82  $urlLimiter = isset($params['urlLimiter']) ? $params['urlLimiter'] : Yii::app()->getModule('search')->urlLimiter['default'];
83  $enableSearchOperators = isset($params['enableSearchOperators']) ? $params['enableSearchOperators'] : Yii::app()->getModule('search')->searchType['enableSearchOperators'];
84 
85 
86  $data = array(
87  'results' => array(),
88  'metaresolvable' => array()
89  );
90  $data = $this->_preformSearch($phrase, $whereToSearch, $mimetype, $searchType, $urlLimiter, $start, $count, $enableSearchOperators);
91  if($data['status'] != 'ok'){
92  return false;
93  }
94  unset($data['status']);
95  $meta = $data['10001']['attributes'];
96  unset($data['10001']);
97 
98  return array(
99  'meta' => $meta,
100  'results' => $data
101  );
102  }
103 
104 
105  /**
106  * Function checks cache if result for given parameters exists and if not - performs API request for it.
107  *
108  * @param string $phrase a phrase to search
109  * @param string $whereToSearch where to search
110  * @param string $mimetype mimetype of searched content
111  * @param string $searchType search type (AND / OR / NOT / EXACT)
112  * @param string $urlLimiter url of result must contain this
113  * @param boolean $enableSearchOperators precondition to understand OR, AND, NOT as operators
114  *
115  * @return array|bool
116  */
117  private function _preformSearch($phrase, $whereToSearch, $mimetype, $searchType, $urlLimiter, $start = null, $count = null, $enableSearchOperators = false)
118  {
119  if ($searchType == 'EXACT') {
120  $phrase = '"'.$phrase.'"';
121  } else {
122  $phrase = preg_replace('/([\ ]+)/', ' ', $phrase);
123 
124  /* gettings quoted phrases */
125  $wordGroups = $this->_extractWordGroups($phrase);
126 
127  /* replacing spaces in quoted phrases to avoid splitting */
128  if (!empty($wordGroups)) {
129  $phrase = str_replace(array_keys($wordGroups), $wordGroups, $phrase);
130  }
131 
132  /*
133  * Feature OR,AND,NOT to understand words OR, AND, NOT as operators
134  */
135  if(!$enableSearchOperators){
136 
137  $phrase = explode(' ', $phrase);
138  $phrase = implode(' '.$searchType.' ', $phrase);
139 
140  }else{
141 
142  $tmpPhrase = explode(' ', $phrase);
143  $phrase = array();
144  $keywordFlag = false;
145 
146  foreach ($tmpPhrase as $i => $word) {
147  if (in_array($word, array('AND', 'OR', 'NOT'))) {
148  $keywordFlag = true;
149  $phrase[] = $word;
150  continue;
151  }
152 
153  if ($keywordFlag || $i == 0) {
154  $keywordFlag = false;
155  $phrase[] = $word;
156  } else {
157  $phrase[] = $searchType.' '.$word;
158  }
159  }
160 
161  $phrase = implode(' ', $phrase);
162  }
163  /*
164  * End of feature
165  */
166  /* return spaces in their places */
167  if (!empty($wordGroups)) {
168  $phrase = str_replace($wordGroups, array_keys($wordGroups), $phrase);
169  }
170  }
171 
172  $staticString = Yii::app()->getModule('search')->staticString;
173  if (trim($staticString)!='') {
174  $phrase .= ' '.$staticString;
175  }
176 
177  $lang = substr(Yii::app()->language, 0, 2);
178  $params = array(
179  'type' => 'php',
180  'metaresolvable' => 'true',
181  'filter' => 'languagecode:'.$lang,
182  );
183 
184  if (!empty($this->getRepositoryApi()->additionalRequestParameters['search'])) {
185  $additional = $this->getRepositoryApi()->additionalRequestParameters['search'];
186  foreach ($additional as $item=>$val) {
187  $params[$item] = !empty($params[$item]) ? $params[$item].' AND '.$val : $params[$item];
188  }
189  }
190 
191  if ($whereToSearch != 'all') {
192  $params['filter'] .= ' AND '.$whereToSearch.':('.$phrase.')';
193  } else {
194  $whereToSearchAll = Yii::app()->getModule('search')->whereToSearch['options'];
195  if (isset($whereToSearchAll['all'])) {
196  unset($whereToSearchAll['all']);
197  }
198 
199  $aWhereToSearchAll = array();
200 
201  foreach ($whereToSearchAll as $key=>$val) {
202  $aWhereToSearchAll[] = $key.':('.$phrase.')';
203  }
204 
205  $params['filter'] .= ' AND ('.implode(' OR ', $aWhereToSearchAll).')';
206  }
207 
208  if ($mimetype!='all') {
209  $params['filter'] .= ' AND mimetype:'.$mimetype;
210  }
211 
212  if ($urlLimiter!='all') {
213  $params['filter'] .= ' AND url:'.$urlLimiter;
214  }
215 
216  if($start !== null){
217  $params['start'] = $start;
218  }
219 
220  if($count !== null){
221  $params['count'] = $count;
222  }
223 
224  $cacheId = md5(serialize($params));
225 
226  if (($data = Yii::app()->cache->get($cacheId)) === false) {
227  $data = $this->getRepositoryApi()->requestSearch($params);
228 
229  $data = unserialize($data);
230 
231  /* store all recieved data in cache */
232  Yii::app()->cache->set($cacheId, $data, Yii::app()->getModule('search')->cacheTime);
233  }
234  return $data;
235  }
236 
237  /**
238  * Checks given phrase for correct syntax
239  *
240  * @param string $phrase a phrase to search
241  *
242  * @return bool
243  */
244  private function _checkPhrase($phrase)
245  {
246  if (trim($phrase) == '') {
247  return false;
248  }
249  return true;
250  }
251 
252  private function _extractWordGroups($phrase, $quotes=array('"'))
253  {
254  if (empty($phrase)) {
255  return array();
256  }
257  $wordGroups = array();
258  foreach ($quotes as $quote) {
259  $reg = preg_quote($quote);
260  preg_match_all('/['.$quote.'](.*)['.$quote.']/sU', $phrase, $matches);
261 
262  if(!empty($matches[1])) {
263  foreach ($matches[1] as $match) {
264  $wordGroups[$match] = str_replace(' ', '_', $match);
265  }
266  }
267  }
268  return $wordGroups;
269  }
270 }
271 
272 ?>