1: <?php
2:
3:
4: if(!isset($config)) {
5: require_once '../util/AlphaConfig.inc';
6: $config = AlphaConfig::getInstance();
7:
8: require_once $config->get('app.root').'alpha/util/AlphaAutoLoader.inc';
9: }
10:
11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55:
56: class Search extends AlphaController implements AlphaControllerInterface {
57: 58: 59: 60: 61: 62:
63: private static $logger = null;
64:
65: 66: 67: 68: 69: 70:
71: protected $startPoint;
72:
73: 74: 75: 76: 77: 78:
79: private $resultCount = 0;
80:
81: 82: 83: 84: 85: 86:
87: private $query;
88:
89: 90: 91: 92: 93: 94:
95: public function __construct($visibility='Public') {
96: self::$logger = new Logger('Search');
97: self::$logger->debug('>>__construct(visibility=['.$visibility.'])');
98:
99: global $config;
100:
101:
102: parent::__construct($visibility);
103:
104: self::$logger->debug('<<__construct');
105: }
106:
107: 108: 109: 110: 111: 112: 113:
114: public function doGET($params) {
115: self::$logger->debug('>>doGET($params=['.var_export($params, true).'])');
116:
117: if (isset($params['start']) ? $this->startPoint = $params['start']: $this->startPoint = 0);
118:
119: global $config;
120:
121: $KPI = new AlphaKPI('search');
122:
123: if(isset($params['q'])) {
124:
125: $this->query = $params['q'];
126:
127:
128: $params['q'] = str_replace('%20', ' ', $params['q']);
129:
130: $this->setTitle('Search results - '.$params['q']);
131: echo AlphaView::displayPageHead($this);
132:
133:
134: $log = new LogFile($config->get('app.file.store.dir').'logs/search.log');
135: $log->writeLine(array($params['q'], date('Y-m-d H:i:s'), $_SERVER['HTTP_USER_AGENT'], $_SERVER['REMOTE_ADDR']));
136:
137: $KPI->logStep('log search query');
138:
139:
140: if(isset($params['bo']))
141: $BOs = array($params['bo']);
142: else
143: $BOs = AlphaDAO::getBOClassNames();
144:
145: try {
146: foreach($BOs as $BO) {
147: AlphaDAO::loadClassDef($BO);
148: $temp = new $BO;
149:
150: if($temp->isTagged()) {
151: $BOIDs = $this->doTagSearch($params['q'], $BO);
152:
153: $this->resultCount += count($BOIDs);
154:
155: $KPI->logStep('built array of matching OIDs');
156:
157:
158: arsort($BOIDs);
159:
160:
161: $this->renderResultList($BOIDs, $BO, $params['q']);
162:
163: AlphaDAO::disconnect();
164: }
165: }
166: }catch(Exception $e) {
167: self::$logger->error($e->getMessage());
168: throw new IllegalArguementException('Error occured while searching for: ['.$params['q'].']');
169: }
170: }else{
171: $this->setTitle('Search results');
172: echo AlphaView::displayPageHead($this);
173: self::$logger->debug('No search query provided!');
174: }
175:
176: echo AlphaView::displayPageFoot($this);
177:
178: $KPI->log();
179:
180: self::$logger->debug('<<doGET');
181: }
182:
183: 184: 185: 186: 187: 188: 189: 190: 191:
192: protected function doTagSearch($query, $BOName, $BOIDs=array()) {
193:
194: $queryTags = TagObject::tokenize($query, '', '', false);
195: $matchingTags = array();
196:
197:
198: foreach($queryTags as $queryTag) {
199: $tags = $queryTag->loadAllByAttribute('content', $queryTag->get('content'));
200: $matchingTags = array_merge($matchingTags, $tags);
201: }
202:
203: self::$logger->debug('There are ['.count($matchingTags).'] TagObjects matching the query ['.$query.']');
204:
205: 206: 207: 208: 209:
210: foreach($matchingTags as $tag) {
211: if($tag->get('taggedClass') == $BOName) {
212:
213: if(isset($BOIDs[$tag->get('taggedOID')])) {
214:
215: $weight = intval($BOIDs[$tag->get('taggedOID')]) + 1;
216: $BOIDs[$tag->get('taggedOID')] = $weight;
217: }else{
218: $BOIDs[$tag->get('taggedOID')] = 1;
219: }
220:
221: self::$logger->debug('Found BO ['.$tag->get('taggedOID').'] has weight ['.$BOIDs[$tag->get('taggedOID')].']');
222: }
223: }
224:
225: return $BOIDs;
226: }
227:
228: 229: 230: 231: 232: 233: 234: 235: 236: 237:
238: protected function renderResultList($BOIDs, $BO, $query='', $showTags=true, $showScore=false) {
239: global $config;
240:
241:
242: $end = ($this->startPoint+$config->get('app.list.page.amount'));
243:
244: $displayedCount = 0;
245:
246: if(!empty($query))
247: echo '<h2>Displaying results for "'.$query.'"</h2>';
248:
249: foreach(array_keys($BOIDs) as $oid) {
250: try {
251:
252: if($displayedCount == $end)
253: break;
254:
255:
256: if($displayedCount >= $this->startPoint) {
257: $temp = new $BO;
258: $temp->load($oid);
259:
260: if($temp instanceof ArticleObject && $temp->get('published') == false){
261: $this->resultCount--;
262: }else{
263: $view = AlphaView::getInstance($temp);
264: echo $view->listView();
265:
266: if($showTags) {
267: $tags = $temp->getPropObject('tags')->getRelatedObjects();
268:
269: if(count($tags) > 0) {
270: echo '<p>Tags: ';
271:
272: $queryTerms = explode(' ', strtolower($query));
273:
274: foreach($tags as $tag) {
275: echo (in_array($tag->get('content'), $queryTerms) ? '<strong>'.$tag->get('content').' </strong>' : $tag->get('content').' ');
276: }
277:
278: echo '</p>';
279: }
280: }
281:
282: if($showScore) {
283: $score = $BOIDs[$oid];
284:
285: echo '<p>Score: <strong>'.$score.'</strong></p>';
286: }
287: }
288: }
289:
290: $displayedCount++;
291: }catch(BONotFoundException $e) {
292: self::$logger->warn('Orpaned TagObject detected pointing to a non-existant BO of OID ['.$oid.'] and type ['.$BO.'].');
293: }
294: }
295: }
296:
297: 298: 299: 300: 301: 302:
303: public function doPOST($params) {
304: self::$logger->debug('>>doPOST($params=['.var_export($params, true).'])');
305:
306: self::$logger->debug('<<doPOST');
307: }
308:
309: 310: 311: 312: 313: 314:
315: public function after_displayPageHead_callback() {
316: global $config;
317:
318: $html = '<div align="center"><form method="GET" id="search_form" onsubmit="document.location = \''.$config->get('app.url').'search/q/\'+document.getElementById(\'q\').value; return false;">';
319: $html .= 'Search for: <input type="text" size="80" name="q" id="q"/> ';
320: $button = new Button('document.location = \''.$config->get('app.url').'search/q/\'+document.getElementById(\'q\').value', 'Search', 'searchButton');
321: $html .= $button->render();
322: $html .= '</form></div>';
323:
324: return $html;
325: }
326:
327: 328: 329: 330: 331: 332:
333: public function () {
334: $html = $this->renderPageLinks();
335:
336: $html .= '<br>';
337:
338: return $html;
339: }
340:
341: 342: 343: 344: 345: 346:
347: protected function renderPageLinks() {
348: global $config;
349:
350: $html = '';
351:
352: $end = ($this->startPoint+$config->get('app.list.page.amount'));
353:
354: if($end > $this->resultCount)
355: $end = $this->resultCount;
356:
357: if($this->resultCount > 0) {
358: $html .= '<p align="center">Displaying '.($this->startPoint+1).' to '.$end.' of <strong>'.$this->resultCount.'</strong>. ';
359: }else{
360: if(!empty($this->query))
361: $html .= AlphaView::displayUpdateMessage('There were no search results for your query.');
362: }
363:
364: if ($this->startPoint > 0) {
365:
366: if(isset($_GET['tk']))
367: $html .= '<a href="'.FrontController::generateSecureURL('act=Search&q='.$this->query.'&start='.($this->startPoint-$config->get('app.list.page.amount'))).'"><<-Previous</a> ';
368: else
369: $html .= '<a href="'.$config->get('app.url').'search/q/'.$this->query.'/start/'.($this->startPoint-$config->get('app.list.page.amount')).'"><<-Previous</a> ';
370: }elseif($this->resultCount > $config->get('app.list.page.amount')){
371: $html .= '<<-Previous ';
372: }
373: $page = 1;
374: for ($i = 0; $i < $this->resultCount; $i+=$config->get('app.list.page.amount')) {
375: if($i != $this->startPoint) {
376:
377: if(isset($_GET['tk']))
378: $html .= ' <a href="'.FrontController::generateSecureURL('act=Search&q='.$this->query.'&start='.$i).'">'.$page.'</a> ';
379: else
380: $html .= ' <a href="'.$config->get('app.url').'search/q/'.$this->query.'/start/'.$i.'">'.$page.'</a> ';
381: }elseif($this->resultCount > $config->get('app.list.page.amount')){
382: $html .= ' '.$page.' ';
383: }
384: $page++;
385: }
386: if ($this->resultCount > $end) {
387:
388: if(isset($_GET['tk']))
389: $html .= ' <a href="'.FrontController::generateSecureURL('act=Search&q='.$this->query.'&start='.($this->startPoint+$config->get('app.list.page.amount'))).'">Next->></a>';
390: else
391: $html .= ' <a href="'.$config->get('app.url').'search/q/'.$this->query.'/start/'.($this->startPoint+$config->get('app.list.page.amount')).'">Next->></a>';
392: }elseif($this->resultCount > $config->get('app.list.page.amount')){
393: $html .= ' Next->>';
394: }
395: $html .= '</p>';
396:
397: return $html;
398: }
399: }
400:
401:
402: if(basename($_SERVER['PHP_SELF']) == 'Search.php') {
403: $controller = new Search();
404:
405: if(!empty($_POST)) {
406: $controller->doPOST($_REQUEST);
407: }else{
408: $controller->doGET($_GET);
409: }
410: }
411:
412: ?>