From 4bb8548eccf22b40c25352fe27c66f1f8039ebcd Mon Sep 17 00:00:00 2001 From: Alexis Degrugillier Date: Sun, 8 Feb 2015 20:51:41 -0500 Subject: Add a way to parse search string to extract keywords This feature is not in use at the moment, but it will be handy to reorganize the query building process. It allows to have more than one keyword in the search box. Full tests are available as well. It probably needs a refactoring later, but I think this is the first step to make the application full object oriented and testable. --- app/Models/Context.php | 149 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) (limited to 'app/Models/Context.php') diff --git a/app/Models/Context.php b/app/Models/Context.php index 1c770c756..645639907 100644 --- a/app/Models/Context.php +++ b/app/Models/Context.php @@ -301,4 +301,153 @@ class FreshRSS_Context { } return false; } + + /** + * Parse search string to extract the different keywords. + * + * @return array + */ + public function parseSearch() { + $search = self::$search; + $intitle = $this->parseIntitleSearch($search); + $author = $this->parseAuthorSearch($intitle['string']); + $inurl = $this->parseInurlSearch($author['string']); + $pubdate = $this->parsePubdateSearch($inurl['string']); + $date = $this->parseDateSearch($pubdate['string']); + + $remaining = array(); + $remaining_search = trim($date['string']); + if (strcmp($remaining_search, '') != 0) { + $remaining['search'] = $remaining_search; + } + + return array_merge($intitle['search'], $author['search'], $inurl['search'], $date['search'], $pubdate['search'], $remaining); + } + + /** + * Parse the search string to find intitle keyword and the search related + * to it. + * The search is the first word following the keyword. + * It returns an array containing the matched string and the search. + * + * @param string $search + * @return array + */ + private function parseIntitleSearch($search) { + if (preg_match('/intitle:(?P[\'"])(?P.*)(?P=delim)/U', $search, $matches)) { + return array( + 'string' => str_replace($matches[0], '', $search), + 'search' => array('intitle' => $matches['search']), + ); + } + if (preg_match('/intitle:(?P\w*)/', $search, $matches)) { + return array( + 'string' => str_replace($matches[0], '', $search), + 'search' => array('intitle' => $matches['search']), + ); + } + return array( + 'string' => $search, + 'search' => array(), + ); + } + + /** + * Parse the search string to find author keyword and the search related + * to it. + * The search is the first word following the keyword except when using + * a delimiter. Supported delimiters are single quote (') and double + * quotes ("). + * It returns an array containing the matched string and the search. + * + * @param string $search + * @return array + */ + private function parseAuthorSearch($search) { + if (preg_match('/author:(?P[\'"])(?P.*)(?P=delim)/U', $search, $matches)) { + return array( + 'string' => str_replace($matches[0], '', $search), + 'search' => array('author' => $matches['search']), + ); + } + if (preg_match('/author:(?P\w*)/', $search, $matches)) { + return array( + 'string' => str_replace($matches[0], '', $search), + 'search' => array('author' => $matches['search']), + ); + } + return array( + 'string' => $search, + 'search' => array(), + ); + } + + /** + * Parse the search string to find inurl keyword and the search related + * to it. + * The search is the first word following the keyword except. + * It returns an array containing the matched string and the search. + * + * @param string $search + * @return array + */ + private function parseInurlSearch($search) { + if (preg_match('/inurl:(?P[^\s]*)/', $search, $matches)) { + return array( + 'string' => str_replace($matches[0], '', $search), + 'search' => array('inurl' => $matches['search']), + ); + } + return array( + 'string' => $search, + 'search' => array(), + ); + } + + /** + * Parse the search string to find date keyword and the search related + * to it. + * The search is the first word following the keyword. + * It returns an array containing the matched string and the search. + * + * @param string $search + * @return array + */ + private function parseDateSearch($search) { + if (preg_match('/date:(?P[^\s]*)/', $search, $matches)) { + list($min_date, $max_date) = parseDateInterval($matches['search']); + return array( + 'string' => str_replace($matches[0], '', $search), + 'search' => array('min_date' => $min_date, 'max_date' => $max_date), + ); + } + return array( + 'string' => $search, + 'search' => array(), + ); + } + + /** + * Parse the search string to find pubdate keyword and the search related + * to it. + * The search is the first word following the keyword. + * It returns an array containing the matched string and the search. + * + * @param string $search + * @return array + */ + private function parsePubdateSearch($search) { + if (preg_match('/pubdate:(?P[^\s]*)/', $search, $matches)) { + list($min_date, $max_date) = parseDateInterval($matches['search']); + return array( + 'string' => str_replace($matches[0], '', $search), + 'search' => array('min_pubdate' => $min_date, 'max_pubdate' => $max_date), + ); + } + return array( + 'string' => $search, + 'search' => array(), + ); + } + } -- cgit v1.2.3