[textpattern] r3286 committed - enhanced search: adds search modes "any" and "all" to default mode "ex...

0 views
Skip to first unread message

textp...@googlecode.com

unread,
Oct 30, 2009, 3:19:18 PM10/30/09
to txp...@googlegroups.com
Revision: 3286
Author: artagesw
Date: Fri Oct 30 12:18:40 2009
Log: enhanced search: adds search modes "any" and "all" to default
mode "exact"; fixes some issues by properly escaping regex characters as
necessary

http://code.google.com/p/textpattern/source/detail?r=3286

Modified:
/development/4.x/textpattern/publish/taghandlers.php
/development/4.x/textpattern/publish.php

=======================================
--- /development/4.x/textpattern/publish/taghandlers.php Sun Jul 26
04:08:41 2009
+++ /development/4.x/textpattern/publish/taghandlers.php Fri Oct 30
12:18:40 2009
@@ -1160,6 +1160,7 @@
'label' => gTxt('search'),
'button' => '',
'section' => '',
+ 'match' => 'exact',
),$atts));

if ($form) {
@@ -1173,6 +1174,7 @@
$id = (!empty($html_id)) ? ' id="'.$html_id.'"' : '';
$out = fInput('text','q',$q,'','','',$size);
$out = (!empty($label)) ? $label.br.$out.$sub : $out.$sub;
+ $out = ($match === 'exact') ? $out : fInput('hidden','m',$match) . $out;
$out = ($wraptag) ? tag($out,$wraptag) : $out;

if (!$section) {
@@ -2485,20 +2487,38 @@
'limit' => 5,
), $atts));

+ $m = $pretext['m'];
$q = $pretext['q'];

+ $quoted = ($q[0] === '"') && ($q[strlen($q)-1] === '"');
+ $q = $quoted ? trim(trim($q, '"')) : $q;
+
$result = preg_replace('/\s+/', ' ', strip_tags(str_replace('><', '> <',
$thisarticle['body'])));
- preg_match_all('/(\G|\s).{0,50}'.preg_quote($q).'.{0,50}(\s|$)/iu',
$result, $concat);
-
- for ($i = 0, $r = array(); $i < min($limit, count($concat[0])); $i++)
- {
- $r[] = trim($concat[0][$i]);
+
+ if ($quoted || empty($m) || $m === 'exact')
+ {
+ $regex_search = '/(?:\G|\s).{0,50}'.preg_quote($q).'.{0,50}(?:\s|$)/iu';
+ $regex_hilite = '/('.preg_quote($q).')/i';
+ }
+ else
+ {
+ $regex_search = '/(?:\G|\s).{0,50}('.preg_replace('/\s+/', '|',
preg_quote($q)).').{0,50}(?:\s|$)/iu';
+ $regex_hilite = '/('.preg_replace('/\s+/', '|', preg_quote($q)).')/i';
+ }
+
+ preg_match_all($regex_search, $result, $concat);
+ $concat = $concat[0];
+
+ for ($i = 0, $r = array(); $i < min($limit, count($concat)); $i++)
+ {
+ $r[] = trim($concat[$i]);
}

$concat = join($break.n, $r);
$concat = preg_replace('/^[^>]+>/U', '', $concat);
#TODO
- $concat =
preg_replace('/('.preg_quote($q).')/i', "<$hilight>$1</$hilight>", $concat);
+
+ $concat = preg_replace($regex_hilite, "<$hilight>$1</$hilight>",
$concat);

return ($concat) ? trim($break.$concat.$break) : '';
}
=======================================
--- /development/4.x/textpattern/publish.php Sun Jul 26 17:10:40 2009
+++ /development/4.x/textpattern/publish.php Fri Oct 30 12:18:40 2009
@@ -217,7 +217,7 @@
callback_event('pretext');

// set messy variables
- $out = makeOut('id','s','c','q','pg','p','month','author');
+ $out = makeOut('id','s','c','q','m','pg','p','month','author');

if(gps('rss')) {
include txpath.'/publish/rss.php';
@@ -632,7 +632,9 @@
include_once txpath.'/publish/search.php';

$s_filter = ($searchall ? filterSearch() : '');
- $q = doSlash($q);
+ $q = trim($q);
+ $quoted = ($q[0] === '"') && ($q[strlen($q)-1] === '"');
+ $q = doSlash($quoted ? trim(trim($q, '"')) : $q);

// searchable article fields are limited to the columns of
// the textpattern table and a matching fulltext index must
exist.
@@ -640,11 +642,49 @@
if (empty($cols) or $cols[0] == '') $cols = array('Title', 'Body');

$match = ', match (`'.join('`, `', $cols)."`) against ('$q') as score";
- for ($i = 0; $i < count($cols); $i++)
- {
- $cols[$i] = "`$cols[$i]` rlike '$q'";
- }
- $cols = join(" or ", $cols);
+
+ if ($quoted || empty($m) || $m === 'exact')
+ {
+ $search_terms = preg_replace('/\s+/', ' ', str_replace(array('%','_'),
array('\\%','\\_'), $q));
+ for ($i = 0; $i < count($cols); $i++)
+ {
+ $cols[$i] = "`$cols[$i]` like '%$search_terms%'";
+ }
+ }
+ elseif ($m === 'any')
+ {
+ $search_terms =
+ preg_replace
+ (
+ '/\s+/',
+ ' | ',
+ str_replace
+ (
+
array('.','\\','+','*','?','[','^',']','$','(',')','{','}','=','!','<','>','|',':','-'),
+
array('\\\\.','\\\\\\','\\\\+','\\\\*','\\\\?','\\\\[','\\\\^','\\\\]','\\\\$','\\\\(','\\\\)','\\\\{','\\\\}','\\\\=','\\\\!','\\\\<','\\\\>','\\\\|','\\\\:','\\\\-'),
+ $q
+ )
+ );
+ for ($i = 0; $i < count($cols); $i++)
+ {
+ $cols[$i] = "`$cols[$i]` regexp '$search_terms'";
+ }
+ }
+ elseif ($m === 'all')
+ {
+ $search_terms = explode(' ', preg_replace('/\s+/', ' ',
str_replace(array('%','_'), array('\\%','\\_'), $q)));
+ for ($i = 0; $i < count($cols); $i++)
+ {
+ $like = array();
+ foreach ($search_terms as $search_term)
+ {
+ $like[] = "`$cols[$i]` like '%$search_term%'";
+ }
+ $cols[$i] = '(' . join(' && ', $like) . ')';
+ }
+ }
+
+ $cols = join(' or ', $cols);
$search = " and ($cols) $s_filter";

// searchall=0 can be used to show search results for the current
section only

Reply all
Reply to author
Forward
0 new messages