1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-16 11:44:42 +02:00

Updates in ProcessPageSearch and InputfieldPageAutocompete for support of new find operators, though additional code may still be necessary but this is a start

This commit is contained in:
Ryan Cramer
2020-07-10 12:52:12 -04:00
parent 6f1fddfedf
commit 01a607f7dc
3 changed files with 62 additions and 41 deletions

View File

@@ -373,7 +373,6 @@ _OUT;
public function ___getConfigInputfields() { public function ___getConfigInputfields() {
$inputfields = parent::___getConfigInputfields(); $inputfields = parent::___getConfigInputfields();
$recommended = $this->_('Recommended');
/** @var InputfieldRadios $field */ /** @var InputfieldRadios $field */
$field = $this->modules->get('InputfieldRadios'); $field = $this->modules->get('InputfieldRadios');
$field->setAttribute('name', 'operator'); $field->setAttribute('name', 'operator');
@@ -381,12 +380,17 @@ _OUT;
$field->description = $this->_("The search operator that is used in the API when performing autocomplete matches."); $field->description = $this->_("The search operator that is used in the API when performing autocomplete matches.");
$field->notes = $this->_("If you aren't sure what you want here, leave it set at the default: *="); $field->notes = $this->_("If you aren't sure what you want here, leave it set at the default: *=");
$field->required = false; $field->required = false;
$field->addOption('*=', '`*= ` ' . $this->_("Contains phrase or partial word (using fulltext index) - Recommended")); $operators = Selectors::getOperators(array(
$field->addOption('%=', '`%= ` ' . $this->_("Contains phrase or partial word (using LIKE)") . " - $recommended"); 'compareType' => Selector::compareTypeFind,
$field->addOption('~=', '`~= ` ' . $this->_("Contains all the [full] words, in any order")); 'getIndexType' => 'operator',
$field->addOption('^=', '`^= ` ' . $this->_("Starts with word/phrase")); 'getValueType' => 'verbose',
$field->addOption('$=', '`$= ` ' . $this->_("Ends with word/phrase")); ));
$field->addOption('=', '` = ` ' . $this->_("Equals [exact]")); foreach($operators as $operator => $info) {
if($operator === '#=') continue;
$opLabel = str_replace('*', '\*', $operator);
$field->addOption($operator, "`$opLabel` **$info[label]** — $info[description]");
}
$field->addOption('=', "`=` **" . SelectorEqual::getLabel() . "** — " . SelectorEqual::getDescription());
$field->attr('value', $this->operator); $field->attr('value', $this->operator);
$field->collapsed = Inputfield::collapsedNo; $field->collapsed = Inputfield::collapsedNo;
$inputfields->add($field); $inputfields->add($field);

View File

@@ -159,21 +159,12 @@ class ProcessPageSearch extends Process implements ConfigurableModule {
* *
*/ */
static public function getOperators() { static public function getOperators() {
$f = __FILE__; $operators = Selectors::getOperators(array(
$anyOrder = __('(in any order)', $f); 'getIndexType' => 'operator',
return array( 'getValueType' => 'label',
'=' => __('Equals', $f), ));
'!=' => __('Does not equal', $f), unset($operators['#=']); // maybe later
'>' => __('Greater than', $f), return $operators;
'>=' => __('Greater than or equal to', $f),
'<' => __('Less than', $f),
'<=' => __('Less than or equal to', $f),
'*=' => __('Contains phrase or partial word', $f) . '*',
'%=' => __('Contains phrase/word using LIKE', $f) . '*',
'~=' => __('Contains all the words', $f) . ' ' . $anyOrder,
'^=' => __('Starts with', $f) . '*',
'$=' => __('Ends with', $f) . '*',
);
} }
/** /**
@@ -245,7 +236,7 @@ class ProcessPageSearch extends Process implements ConfigurableModule {
$lister->initSelector = $initSelector; $lister->initSelector = $initSelector;
$lister->defaultSelector = $defaultSelector; $lister->defaultSelector = $defaultSelector;
$lister->defaultSort = 'relevance'; $lister->defaultSort = 'relevance';
$lister->limit = $this->resultLimit; $lister->set('limit', $this->resultLimit);
$lister->preview = false; $lister->preview = false;
$lister->columns = $this->getDisplayFields(); $lister->columns = $this->getDisplayFields();
return $lister->execute(); return $lister->execute();
@@ -860,7 +851,7 @@ class ProcessPageSearch extends Process implements ConfigurableModule {
// deetermine which operator (if any) is present in $q // deetermine which operator (if any) is present in $q
foreach($operators as $operator => $description) { foreach($operators as $operator => $description) {
if(strpos($q, $operator) === false) continue; if(strpos($q, $operator) === false) continue;
if(!preg_match('/^([^=%$*<>~^:]+)' . $operator . '([^=%$*<>~^:]+)$/', $q, $matches)) continue; if(!preg_match('/^([^=%$*+<>~^:]+)' . $operator . '([^=%$*+<>~^:]+)$/', $q, $matches)) continue;
if($operator === '=') $operator = '?'; // operator to be determined on factors search text if($operator === '=') $operator = '?'; // operator to be determined on factors search text
if($operator === '==') $operator = '='; if($operator === '==') $operator = '=';
$type = $sanitizer->name($matches[1]); $type = $sanitizer->name($matches[1]);
@@ -875,13 +866,13 @@ class ProcessPageSearch extends Process implements ConfigurableModule {
// operator was not present, only query text was, so use default operator // operator was not present, only query text was, so use default operator
$operator = $this->operator; $operator = $this->operator;
} }
$input->get->operator = $operator; $input->get->set('operator', $operator);
if(strpos($type, '.')) { if(strpos($type, '.')) {
// type with property/field // type with property/field
list($type, $field) = explode('.', $type, 2); list($type, $field) = explode('.', $type, 2);
$field = $this->wire('sanitizer')->fieldName(trim($field)); $field = $this->wire('sanitizer')->fieldName(trim($field));
$input->get->field = $field; $input->get->set('field', $field);
} else { } else {
$field = ''; $field = '';
} }
@@ -889,12 +880,12 @@ class ProcessPageSearch extends Process implements ConfigurableModule {
if($type == 'pages') { if($type == 'pages') {
// okay // okay
} else if($type == 'trash') { } else if($type == 'trash') {
$input->get->trash = 1; $input->get->set('trash', 1);
} else if($type) { } else if($type) {
$template = $type ? $this->wire('templates')->get($type) : ''; $template = $type ? $this->wire('templates')->get($type) : '';
if($template) { if($template) {
// defined template // defined template
$input->get->template = $template->name; $input->get->set('template', $template->name);
} else { } else {
// some other non-page type // some other non-page type
$redirectUrl = $this->wire('page')->url . 'live/' . $redirectUrl = $this->wire('page')->url . 'live/' .
@@ -1345,12 +1336,19 @@ class ProcessPageSearch extends Process implements ConfigurableModule {
public function getModuleConfigInputfields(array $data) { public function getModuleConfigInputfields(array $data) {
$adminLiveSearchLabel = $this->_('Admin live search');
$inputfields = $this->wire(new InputfieldWrapper()); $inputfields = $this->wire(new InputfieldWrapper());
$modules = $this->wire('modules'); $modules = $this->wire('modules');
$textFields = array(); $textFields = array();
$allSearchTypes = array('pages', 'trash', 'modules'); $allSearchTypes = array('pages', 'trash', 'modules');
$textOperators = array('%=', '~=', '*=', '^=', '='); // $textOperators = array('%=', '~=', '*=', '~*=', '~~=', '~%=', '~|=', '~|*=', '^=', '=');
$allOperators = self::getOperators(); $textOperators = Selectors::getOperators(array(
'compareType' => Selector::compareTypeFind,
'getIndexType' => 'operator',
'getValueType' => 'label',
));
$textOperators['='] = SelectorEqual::getLabel();
unset($textOperators['#=']);
if(!isset($data['searchTypesOrder'])) $data['searchTypesOrder'] = array(); if(!isset($data['searchTypesOrder'])) $data['searchTypesOrder'] = array();
if(!isset($data['noSearchTypes'])) $data['noSearchTypes'] = array(); if(!isset($data['noSearchTypes'])) $data['noSearchTypes'] = array();
@@ -1378,8 +1376,9 @@ class ProcessPageSearch extends Process implements ConfigurableModule {
if(!in_array($name, $searchTypesOrder)) $searchTypesOrder[] = $name; if(!in_array($name, $searchTypesOrder)) $searchTypesOrder[] = $name;
} }
/** @var InputfieldFieldset $fieldset */
$fieldset = $modules->get('InputfieldFieldset'); $fieldset = $modules->get('InputfieldFieldset');
$fieldset->label = $this->_('Admin live search'); $fieldset->label = $adminLiveSearchLabel;
$fieldset->icon = 'search'; $fieldset->icon = 'search';
$inputfields->add($fieldset); $inputfields->add($fieldset);
@@ -1413,6 +1412,13 @@ class ProcessPageSearch extends Process implements ConfigurableModule {
$f->attr('value', $noSearchTypes); $f->attr('value', $noSearchTypes);
$fieldset->add($f); $fieldset->add($f);
/** @var InputfieldFieldset $fieldset */
$fieldset = $modules->get('InputfieldFieldset');
$fieldset->label = $adminLiveSearchLabel . ' ' . $this->_('(settings for pages type)');
$fieldset->icon = 'search';
$fieldset->themeOffset = 'm';
$inputfields->add($fieldset);
$f = $modules->get('InputfieldAsmSelect'); $f = $modules->get('InputfieldAsmSelect');
$f->attr('name', 'searchFields2'); $f->attr('name', 'searchFields2');
$f->label = $this->_('Page fields to search'); $f->label = $this->_('Page fields to search');
@@ -1442,12 +1448,9 @@ class ProcessPageSearch extends Process implements ConfigurableModule {
$f->attr('value', isset($data['operator']) ? $data['operator'] : self::defaultOperator); $f->attr('value', isset($data['operator']) ? $data['operator'] : self::defaultOperator);
$f->label = $this->_('Default search operator for single and partial word searches'); $f->label = $this->_('Default search operator for single and partial word searches');
$f->columnWidth = 50; $f->columnWidth = 50;
foreach($textOperators as $operator) { foreach($textOperators as $operator => $label) {
$label = $allOperators[$operator];
$f->addOption($operator, "$operator $label"); $f->addOption($operator, "$operator $label");
} }
$partialLabel = '*' . $this->_('Indicates support of partial word matches');
$f->notes = $partialLabel;
$fieldset->append($f); $fieldset->append($f);
$f = $modules->get("InputfieldSelect"); $f = $modules->get("InputfieldSelect");
@@ -1455,11 +1458,9 @@ class ProcessPageSearch extends Process implements ConfigurableModule {
$f->attr('value', isset($data['operator2']) ? $data['operator2'] : '~='); $f->attr('value', isset($data['operator2']) ? $data['operator2'] : '~=');
$f->label = $this->_('Default search operator for multi-word (phrase) searches'); $f->label = $this->_('Default search operator for multi-word (phrase) searches');
$f->columnWidth = 50; $f->columnWidth = 50;
foreach($textOperators as $operator) { foreach($textOperators as $operator => $label) {
$label = $allOperators[$operator];
$f->addOption($operator, "$operator $label"); $f->addOption($operator, "$operator $label");
} }
$f->notes = $partialLabel;
$fieldset->append($f); $fieldset->append($f);
// displayField: no longer used, except if user lacks page-lister permission // displayField: no longer used, except if user lacks page-lister permission

View File

@@ -169,6 +169,14 @@ class ProcessPageSearchLive extends Wire {
$this->liveSearchDefaults = array_merge($this->liveSearchDefaults, $liveSearch); $this->liveSearchDefaults = array_merge($this->liveSearchDefaults, $liveSearch);
} }
$findOperators = Selectors::getOperators(array(
'compareType' => Selector::compareTypeFind,
'getIndexType' => 'none',
'getValueType' => 'operator',
));
$this->allowOperators = array_unique(array_merge($this->allowOperators, $findOperators));
$this->labels = array( $this->labels = array(
'missing-query' => $this->_('No search specified'), 'missing-query' => $this->_('No search specified'),
'pages' => $this->_('Pages'), 'pages' => $this->_('Pages'),
@@ -234,6 +242,8 @@ class ProcessPageSearchLive extends Wire {
$user = $this->wire('user'); $user = $this->wire('user');
/** @var Languages $languages */ /** @var Languages $languages */
$languages = $this->wire('languages'); $languages = $this->wire('languages');
/** @var AdminTheme|AdminThemeFramework $adminTheme */
$adminTheme = $this->wire()->adminTheme;
$type = isset($presets['type']) ? $presets['type'] : ''; $type = isset($presets['type']) ? $presets['type'] : '';
$language = isset($presets['language']) ? $presets['language'] : ''; $language = isset($presets['language']) ? $presets['language'] : '';
@@ -280,10 +290,13 @@ class ProcessPageSearchLive extends Wire {
} else if(strpos($q, '=') !== false) { } else if(strpos($q, '=') !== false) {
// regular equals or other w/equals // regular equals or other w/equals
$replaceOperator = '='; $replaceOperator = '=';
if(preg_match('/([%~*^$<>!]{1,2}=)/', $q, $matches)) { $opChars = Selectors::getOperatorChars();
if(preg_match('/([' . preg_quote(implode('', $opChars)) . ']{1,3}=)/', $q, $matches)) {
if(in_array($matches[1], $this->allowOperators)) { if(in_array($matches[1], $this->allowOperators)) {
$operator = $matches[1]; $operator = $matches[1];
$replaceOperator = $operator; $replaceOperator = $operator;
} else {
$q = str_replace($opChars, ' ', $q);
} }
} else { } else {
// regular equals, use default operator // regular equals, use default operator
@@ -362,6 +375,9 @@ class ProcessPageSearchLive extends Wire {
$selectors[] = implode('|', $this->defaultPageSearchFields) . $operator . $value; $selectors[] = implode('|', $this->defaultPageSearchFields) . $operator . $value;
} }
$help = strtolower($q) === 'help';
if(!$help && $adminTheme && $q === $adminTheme->getLabel('search-help')) $help = true;
$liveSearch = array_merge($this->liveSearchDefaults, $presets, array( $liveSearch = array_merge($this->liveSearchDefaults, $presets, array(
'type' => $type, 'type' => $type,
'property' => $property, 'property' => $property,
@@ -373,7 +389,7 @@ class ProcessPageSearchLive extends Wire {
'language' => $language, 'language' => $language,
'start' => $start, 'start' => $start,
'limit' => $limit, 'limit' => $limit,
'help' => strtolower($q) === 'help', 'help' => $help,
)); ));
if($this->isViewAll) { if($this->isViewAll) {