Skip to content

Commit d229216

Browse files
committed
Split the search into values
Before, the search was a single value. Now it is splited in chuncks when separated by spaces. Except if they are enclosed by single quotes or double quotes. For some reasons, the unit tests are working for both single and double quotes but the search box isn't. It is working only with single quotes. We need to investigate the reason of this behavior. See #823
1 parent 2a0d04d commit d229216

File tree

3 files changed

+77
-31
lines changed

3 files changed

+77
-31
lines changed

app/Models/EntryDAO.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,13 @@ private function sqlListWhere($type = 'a', $id = '', $state = FreshRSS_Entry::ST
478478
}
479479
}
480480
if ($filter->getSearch()) {
481-
$search .= 'AND ' . $this->sqlconcat('e1.title', $this->isCompressed() ? 'UNCOMPRESS(content_bin)' : 'content') . ' LIKE ? ';
482-
$values[] = "%{$filter->getSearch()}%";
481+
$search_values = $filter->getSearch();
482+
foreach ($search_values as $search_value) {
483+
$search .= 'AND ' . $this->sqlconcat('e1.title', $this->isCompressed() ? 'UNCOMPRESS(content_bin)' : 'content') . ' LIKE ? ';
484+
$values[] = "%{$search_value}%";
485+
}
483486
}
484487
}
485-
486488
return array($values,
487489
'SELECT e1.id FROM `' . $this->prefix . 'entry` e1 '
488490
. ($joinFeed ? 'INNER JOIN `' . $this->prefix . 'feed` f ON e1.id_feed=f.id ' : '')

app/Models/Search.php

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ public function __construct($input) {
3434
$input = $this->parsePubdateSearch($input);
3535
$input = $this->parseDateSearch($input);
3636
$input = $this->parseTagsSeach($input);
37-
$this->search = $this->cleanSearch($input);
37+
$this->parseSearch($input);
3838
}
39-
39+
4040
public function __toString() {
4141
return $this->getRawInput();
4242
}
@@ -187,6 +187,34 @@ private function parseTagsSeach($input) {
187187
return $input;
188188
}
189189

190+
/**
191+
* Parse the search string to find search values.
192+
* Every word is a distinct search value, except when using a delimiter.
193+
* Supported delimiters are single quote (') and double quotes (").
194+
*
195+
* @param string $input
196+
* @return string
197+
*/
198+
private function parseSearch($input) {
199+
$input = $this->cleanSearch($input);
200+
if (strcmp($input, '') == 0) {
201+
return;
202+
}
203+
if (preg_match_all('/(?P<delim>[\'"])(?P<search>.*)(?P=delim)/U', $input, $matches)) {
204+
$this->search = $matches['search'];
205+
$input = str_replace($matches[0], '', $input);
206+
}
207+
$input = $this->cleanSearch($input);
208+
if (strcmp($input, '') == 0) {
209+
return;
210+
}
211+
if (is_array($this->search)) {
212+
$this->search = array_merge($this->search, explode(' ', $input));
213+
} else {
214+
$this->search = explode(' ', $input);
215+
}
216+
}
217+
190218
/**
191219
* Remove all unnecessary spaces in the search
192220
*

tests/app/Models/SearchTest.php

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,21 @@ public function test__construct_whenInputContainsIntitle_setsIntitlePropery($inp
5151
public function provideIntitleSearch() {
5252
return array(
5353
array('intitle:word1', 'word1', null),
54-
array('intitle:word1 word2', 'word1', 'word2'),
54+
array('intitle:word1 word2', 'word1', array('word2')),
5555
array('intitle:"word1 word2"', 'word1 word2', null),
5656
array("intitle:'word1 word2'", 'word1 word2', null),
57-
array('word1 intitle:word2', 'word2', 'word1'),
58-
array('word1 intitle:word2 word3', 'word2', 'word1 word3'),
59-
array('word1 intitle:"word2 word3"', 'word2 word3', 'word1'),
60-
array("word1 intitle:'word2 word3'", 'word2 word3', 'word1'),
61-
array('intitle:word1 intitle:word2', 'word1', 'intitle:word2'),
62-
array('intitle: word1 word2', null, 'word1 word2'),
57+
array('word1 intitle:word2', 'word2', array('word1')),
58+
array('word1 intitle:word2 word3', 'word2', array('word1', 'word3')),
59+
array('word1 intitle:"word2 word3"', 'word2 word3', array('word1')),
60+
array("word1 intitle:'word2 word3'", 'word2 word3', array('word1')),
61+
array('intitle:word1 intitle:word2', 'word1', array('intitle:word2')),
62+
array('intitle: word1 word2', null, array('word1', 'word2')),
6363
array('intitle:123', '123', null),
64-
array('intitle:"word1 word2" word3"', 'word1 word2', 'word3"'),
65-
array("intitle:'word1 word2' word3'", 'word1 word2', "word3'"),
64+
array('intitle:"word1 word2" word3"', 'word1 word2', array('word3"')),
65+
array("intitle:'word1 word2' word3'", 'word1 word2', array("word3'")),
6666
array('intitle:"word1 word2\' word3"', "word1 word2' word3", null),
6767
array("intitle:'word1 word2\" word3'", 'word1 word2" word3', null),
68+
array("intitle:word1 'word2 word3' word4", 'word1', array('word2 word3', 'word4')),
6869
);
6970
}
7071

@@ -86,20 +87,21 @@ public function test__construct_whenInputContainsAuthor_setsAuthorValue($input,
8687
public function provideAuthorSearch() {
8788
return array(
8889
array('author:word1', 'word1', null),
89-
array('author:word1 word2', 'word1', 'word2'),
90+
array('author:word1 word2', 'word1', array('word2')),
9091
array('author:"word1 word2"', 'word1 word2', null),
9192
array("author:'word1 word2'", 'word1 word2', null),
92-
array('word1 author:word2', 'word2', 'word1'),
93-
array('word1 author:word2 word3', 'word2', 'word1 word3'),
94-
array('word1 author:"word2 word3"', 'word2 word3', 'word1'),
95-
array("word1 author:'word2 word3'", 'word2 word3', 'word1'),
96-
array('author:word1 author:word2', 'word1', 'author:word2'),
97-
array('author: word1 word2', null, 'word1 word2'),
93+
array('word1 author:word2', 'word2', array('word1')),
94+
array('word1 author:word2 word3', 'word2', array('word1', 'word3')),
95+
array('word1 author:"word2 word3"', 'word2 word3', array('word1')),
96+
array("word1 author:'word2 word3'", 'word2 word3', array('word1')),
97+
array('author:word1 author:word2', 'word1', array('author:word2')),
98+
array('author: word1 word2', null, array('word1', 'word2')),
9899
array('author:123', '123', null),
99-
array('author:"word1 word2" word3"', 'word1 word2', 'word3"'),
100-
array("author:'word1 word2' word3'", 'word1 word2', "word3'"),
100+
array('author:"word1 word2" word3"', 'word1 word2', array('word3"')),
101+
array("author:'word1 word2' word3'", 'word1 word2', array("word3'")),
101102
array('author:"word1 word2\' word3"', "word1 word2' word3", null),
102103
array("author:'word1 word2\" word3'", 'word1 word2" word3', null),
104+
array("author:word1 'word2 word3' word4", 'word1', array('word2 word3', 'word4')),
103105
);
104106
}
105107

@@ -121,10 +123,11 @@ public function test__construct_whenInputContainsInurl_setsInurlValue($input, $i
121123
public function provideInurlSearch() {
122124
return array(
123125
array('inurl:word1', 'word1', null),
124-
array('inurl: word1', null, 'word1'),
126+
array('inurl: word1', null, array('word1')),
125127
array('inurl:123', '123', null),
126-
array('inurl:word1 word2', 'word1', 'word2'),
127-
array('inurl:"word1 word2"', '"word1', 'word2"'),
128+
array('inurl:word1 word2', 'word1', array('word2')),
129+
array('inurl:"word1 word2"', '"word1', array('word2"')),
130+
array("inurl:word1 'word2 word3' word4", 'word1', array('word2 word3', 'word4')),
128131
);
129132
}
130133

@@ -198,11 +201,12 @@ public function test__construct_whenInputContainsTags_setsTagsValue($input, $tag
198201
public function provideTagsSearch() {
199202
return array(
200203
array('#word1', array('word1'), null),
201-
array('# word1', null, '# word1'),
204+
array('# word1', null, array('#', 'word1')),
202205
array('#123', array('123'), null),
203-
array('#word1 word2', array('word1'), 'word2'),
204-
array('#"word1 word2"', array('"word1'), 'word2"'),
206+
array('#word1 word2', array('word1'), array('word2')),
207+
array('#"word1 word2"', array('"word1'), array('word2"')),
205208
array('#word1 #word2', array('word1', 'word2'), null),
209+
array("#word1 'word2 word3' word4", array('word1'), array('word2 word3', 'word4')),
206210
);
207211
}
208212

@@ -257,7 +261,7 @@ public function provideMultipleSearch() {
257261
'1172725200',
258262
'1210564799',
259263
array('word4', 'word5'),
260-
'word6',
264+
array('word6'),
261265
),
262266
array(
263267
'word6 intitle:word2 inurl:word3 pubdate:2007-03-01/2008-05-11 #word4 author:word1 #word5 word7 date:2007-03-01/2008-05-11',
@@ -269,7 +273,19 @@ public function provideMultipleSearch() {
269273
'1172725200',
270274
'1210564799',
271275
array('word4', 'word5'),
272-
'word6 word7',
276+
array('word6', 'word7'),
277+
),
278+
array(
279+
'word6 intitle:word2 inurl:word3 pubdate:2007-03-01/2008-05-11 #word4 author:word1 #word5 "word7 word8" date:2007-03-01/2008-05-11',
280+
'word1',
281+
'1172725200',
282+
'1210564799',
283+
'word2',
284+
'word3',
285+
'1172725200',
286+
'1210564799',
287+
array('word4', 'word5'),
288+
array('word7 word8', 'word6'),
273289
),
274290
);
275291
}

0 commit comments

Comments
 (0)