"); define ('HIT_AFTER',""); define ('QUERY_ORDER_BY','rss_order'); define ('QUERY_ORDER_BY_DATE','date'); define ('QUERY_ORDER_BY_CHANNEL','channel'); define ('QUERY_MATCH_OR','or'); define ('QUERY_MATCH_AND','and'); define ('QUERY_MATCH_EXACT','exact'); // This is needed for some constants rss_require('cls/wrappers/toolkit.php'); class SearchItemList extends ItemList { var $searchTerms = array(); var $matchMode; var $regMatch = ""; var $currentPage; var $resultsPerPage = 0; var $startItem; var $endItem; var $orderBy; var $query = ""; var $logicSep; function SearchItemList($query=null,$results=0) { parent::ItemList(); if ($query) { $this -> query=$query; } elseif(isset($_REQUEST[QUERY_PRM])) { $this->query = $_REQUEST[QUERY_PRM]; }else{ $this -> query = null; } // Sanitize the query parameters: // fixme: this probably breaks on queries with weird characters, depending // on the locale. // see: http://php.benscom.com/manual/en/reference.pcre.pattern.syntax.php if ($this -> query) { $this -> query = trim(preg_replace('#[^\w\s\x80-\xff]#','',$this -> query)); } $this->resultsPerPage = (int) $results; $this -> populate(); $this->humanReadableQuery = implode(" ".strtoupper($this->logicSep)." ", $this->searchTerms); } function filterItems() { $cntr = 0; foreach($this->feeds as $fkey => $feed) { foreach ($this -> feeds[$fkey]->items as $ikey => $item) { $descr_noTags = strip_tags($item -> description); $title_noTags = strip_tags($item -> title); $match = false; reset($this->searchTerms); $match = ($this->matchMode == QUERY_MATCH_AND || $this->matchMode == QUERY_MATCH_EXACT); foreach ($this->searchTerms as $term) { if ($this->matchMode == QUERY_MATCH_AND || $this->matchMode == QUERY_MATCH_EXACT) { $match = ((stristr($descr_noTags, $term) || stristr($title_noTags, $term)) && $match); } else { $match = ($match || (stristr($descr_noTags, $term) || stristr($title_noTags, $term))); } } if (!$match) { $this->removeItem($fkey,$ikey,true); } else { if ($cntr >= $this->startItem && $cntr <= $this->endItem) { $this->feeds[$fkey] -> items[$ikey] -> description = preg_replace("'(?!<.*?)(".$this->regMatch.")(?![^<>]*?>)'si", HIT_BEFORE."\\1".HIT_AFTER, $item -> description); } else { $this->removeItem($fkey,$ikey,false); } $cntr++; } } } } function populate() { if (!$this->query) { return; } $this->matchMode = sanitize( (!array_key_exists(QUERY_MATCH_MODE, $_REQUEST) ? QUERY_MATCH_AND : $_REQUEST[QUERY_MATCH_MODE]), RSS_SANITIZER_CHARACTERS_EXT); $this->channelId = sanitize( ((array_key_exists(QUERY_CHANNEL, $_REQUEST)) ? $_REQUEST[QUERY_CHANNEL] : ALL_CHANNELS_ID), RSS_SANITIZER_NUMERIC); if (!$this->resultsPerPage) { $this->resultsPerPage = sanitize( ((array_key_exists(QUERY_RESULTS, $_REQUEST)) ? $_REQUEST[QUERY_RESULTS] : INFINE_RESULTS), RSS_SANITIZER_NUMERIC); } $this->currentPage = sanitize( (array_key_exists(QUERY_CURRENT_PAGE, $_REQUEST) ? $_REQUEST[QUERY_CURRENT_PAGE] : 0), RSS_SANITIZER_NUMERIC); $this->startItem = $this->resultsPerPage * $this->currentPage; $this->endItem = $this->startItem + $this->resultsPerPage -1; if ($this->resultsPerPage == INFINE_RESULTS) { $this->endItem = 99999999; } $this->orderBy = sanitize( (array_key_exists(QUERY_ORDER_BY, $_REQUEST) ? $_REQUEST[QUERY_ORDER_BY] : QUERY_ORDER_BY_DATE), RSS_SANITIZER_CHARACTERS_EXT); $qWhere = ""; $this->regMatch = ""; $term = ""; if ($this->matchMode == QUERY_MATCH_OR || $this->matchMode == QUERY_MATCH_AND) { $this->logicSep = ($this->matchMode == QUERY_MATCH_OR ? "or" : "and"); $this->searchTerms = explode(" ", $this->query); foreach ($this->searchTerms as $term) { $term = trim($term); if ($term != "") { $qWhere .= "(i.description like '%$term%' or "." i.title like '%$term%') ".$this->logicSep; } // this will be used later for the highliting regexp if ($this->regMatch != "") { $this->regMatch .= "|"; } $this->regMatch .= $term; } $qWhere .= ($this->matchMode == QUERY_MATCH_OR ? " 1=0 " : " 1=1 "); } else { $this->logicSep = ""; $this->searchTerms[0] = $this->query; $term = $this->query; $qWhere .= "(i.description like '%$term%' or "." i.title like '%$term%') "; $this->regMatch = $this->query; } $qWhere= "(" . $qWhere. ") "; if ($this->channelId != ALL_CHANNELS_ID) { $qWhere .= " and c.id = " . $this->channelId . " "; } if (hidePrivate()) { $qWhere .= " and not(i.unread & ".RSS_MODE_PRIVATE_STATE.") "; } $qWhere .= " and not(i.unread & ".RSS_MODE_DELETED_STATE.") "; if ($this->orderBy == QUERY_ORDER_BY_DATE) { $qOrder = " ts desc"; } else { if (getConfig('rss.config.absoluteordering')) { $qOrder = " f.position asc, c.position asc"; } else { $qOrder = " f.name asc, c.title asc"; } } $qOrder .= ", i.added desc"; parent::populate($qWhere,$qOrder,0,getConfig("rss.search.maxitems"),ITEM_SORT_HINT_MIXED,true); $this -> filterItems(); $this -> nav(); } function nav() { $nav = ""; if ($this->resultsPerPage != INFINE_RESULTS && $this->itemCount > $this->resultsPerPage) { $nav .= "