diff options
-rw-r--r-- | application/LinkFilter.php | 45 | ||||
-rw-r--r-- | tests/LinkFilterTest.php | 17 |
2 files changed, 48 insertions, 14 deletions
diff --git a/application/LinkFilter.php b/application/LinkFilter.php index cf647371..b2e6530f 100644 --- a/application/LinkFilter.php +++ b/application/LinkFilter.php | |||
@@ -136,16 +136,21 @@ class LinkFilter | |||
136 | */ | 136 | */ |
137 | private function filterFulltext($searchterms, $privateonly = false) | 137 | private function filterFulltext($searchterms, $privateonly = false) |
138 | { | 138 | { |
139 | // FIXME: explode(' ',$searchterms) and perform a AND search. | 139 | $search = mb_convert_case(html_entity_decode($searchterms), MB_CASE_LOWER, 'UTF-8'); |
140 | // FIXME: accept double-quotes to search for a string "as is"? | ||
141 | $filtered = array(); | ||
142 | $search = mb_convert_case($searchterms, MB_CASE_LOWER, 'UTF-8'); | ||
143 | $explodedSearch = explode(' ', trim($search)); | 140 | $explodedSearch = explode(' ', trim($search)); |
144 | $keys = array('title', 'description', 'url', 'tags'); | 141 | $keys = array('title', 'description', 'url', 'tags'); |
142 | $found = true; | ||
143 | $searchExactPhrase = false; | ||
145 | 144 | ||
145 | // Check if we're using double-quotes to search for the exact string | ||
146 | if ($search[0] == '"' && $search[strlen($search) - 1] == '"') { | ||
147 | $searchExactPhrase = true; | ||
148 | |||
149 | // Remove the double-quotes as they are not what we search for | ||
150 | $search = substr($search, 1, -1); | ||
151 | } | ||
146 | // Iterate over every stored link. | 152 | // Iterate over every stored link. |
147 | foreach ($this->links as $link) { | 153 | foreach ($this->links as $link) { |
148 | $found = false; | ||
149 | 154 | ||
150 | // ignore non private links when 'privatonly' is on. | 155 | // ignore non private links when 'privatonly' is on. |
151 | if (! $link['private'] && $privateonly === true) { | 156 | if (! $link['private'] && $privateonly === true) { |
@@ -154,19 +159,33 @@ class LinkFilter | |||
154 | 159 | ||
155 | // Iterate over searchable link fields. | 160 | // Iterate over searchable link fields. |
156 | foreach ($keys as $key) { | 161 | foreach ($keys as $key) { |
157 | // Search full expression. | 162 | // Be optimistic |
158 | if (strpos( | 163 | $found = true; |
159 | mb_convert_case($link[$key], MB_CASE_LOWER, 'UTF-8'), | 164 | |
160 | $search | 165 | // FIXME: Find a better word for where you're searching in |
161 | ) !== false) { | 166 | $haystack = mb_convert_case($link[$key], MB_CASE_LOWER, 'UTF-8'); |
162 | $found = true; | ||
163 | } | ||
164 | 167 | ||
168 | // When searching for the phrase, check if it's in the haystack... | ||
169 | if ( $searchExactPhrase && strpos($haystack, $search) !== false) { | ||
170 | break; | ||
171 | } | ||
172 | else { | ||
173 | // Iterate over keywords, if keyword is not found, | ||
174 | // no need to check for the others. We want all or nothing. | ||
175 | foreach($explodedSearch as $keyword) { | ||
176 | if(strpos($haystack, $keyword) === false) { | ||
177 | $found = false; | ||
178 | break; | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | |||
183 | // One of the fields of the link matches, no need to check the other. | ||
165 | if ($found) { | 184 | if ($found) { |
166 | break; | 185 | break; |
167 | } | 186 | } |
168 | } | 187 | } |
169 | 188 | ||
170 | if ($found) { | 189 | if ($found) { |
171 | $filtered[$link['linkdate']] = $link; | 190 | $filtered[$link['linkdate']] = $link; |
172 | } | 191 | } |
diff --git a/tests/LinkFilterTest.php b/tests/LinkFilterTest.php index 5107ab72..5fb2423f 100644 --- a/tests/LinkFilterTest.php +++ b/tests/LinkFilterTest.php | |||
@@ -173,6 +173,11 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase | |||
173 | 2, | 173 | 2, |
174 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars.userfriendly.org')) | 174 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars.userfriendly.org')) |
175 | ); | 175 | ); |
176 | |||
177 | $this->assertEquals( | ||
178 | 2, | ||
179 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars org')) | ||
180 | ); | ||
176 | } | 181 | } |
177 | 182 | ||
178 | /** | 183 | /** |
@@ -208,8 +213,18 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase | |||
208 | { | 213 | { |
209 | $this->assertEquals( | 214 | $this->assertEquals( |
210 | 1, | 215 | 1, |
211 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'media publishing')) | 216 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'publishing media')) |
217 | ); | ||
218 | |||
219 | $this->assertEquals( | ||
220 | 1, | ||
221 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'mercurial w3c')) | ||
212 | ); | 222 | ); |
223 | |||
224 | $this->assertEquals( | ||
225 | 2, | ||
226 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '"free software"')) | ||
227 | ); | ||
213 | } | 228 | } |
214 | 229 | ||
215 | /** | 230 | /** |