Project

General

Profile

Actions

Feature #61981

closed

Search all fields in Suggest Wizard (patch)

Added by Einar Gislason over 9 years ago. Updated over 5 years ago.

Status:
Closed
Priority:
Should have
Category:
Backend User Interface
Target version:
-
Start date:
2014-09-30
Due date:
% Done:

100%

Estimated time:
PHP Version:
Tags:
Complexity:
Sprint Focus:

Description

Problem: It is not possible to search across all available fields in the suggest wizard. This patch solves this problem
http://docs.typo3.org/typo3cms/TCAReference/AdditionalFeatures/WizardsConfiguration/Index.html#wizards-configuration-suggest

Case: We store our authors in a table with separate fields for first, middle and last name. The table is quite large and there are many people that share a first or last name. Finding a certain person is almost impossible unless you search for both first and last name. The current code only allowes you to search in one field.
Example:
Database: first_name = John, last_name = Doe
Query: "John Doe" will currently return empty as it matches neither first or last name

The patch explodes the searchString on "+" (plus) and then loops through each word. I've used "+" but this could be any character that makes sense.

So in stead of the select clause being like this (using search query "John Doe"):
(first_name LIKE '%john doe%' OR last_name LIKE '%john doe%')
...it will be (using search query "John + Doe"):
((first_name LIKE '%john%' OR last_name LIKE '%john%') AND (first_name LIKE '%doe%' OR last_name LIKE '%doe%'))

This will allow you to type two or more words and be more specific in you query. This should not break anything as you can search like normal if you don't use the "+" sign.

File: typo3/sysext/backend/Classes/Form/Element/SuggestDefaultReceiver.php

     protected function prepareSelectStatement() {
        $searchWholePhrase = $this->config['searchWholePhrase'];
        $searchString = $this->params['value'];
        $searchUid = (int)$searchString;

        if (strlen($searchString)) {
            $searchStrings = explode('+', $searchString); // Perhaps use another char than "+"?
            $selectParts = array();
            foreach($searchStrings as $searchWord){
                $searchWord = $GLOBALS['TYPO3_DB']->quoteStr($searchWord, $this->table);
                $searchWord = trim($searchWord);
                $likeCondition = ' LIKE \'' . ($searchWholePhrase ? '%' : '') . $GLOBALS['TYPO3_DB']->escapeStrForLike($searchWord, $this->table) . '%\'';
                // Search in all fields given by label or label_alt
                $selectFieldsList = $GLOBALS['TCA'][$this->table]['ctrl']['label'] . ',' . $GLOBALS['TCA'][$this->table]['ctrl']['label_alt'] . ',' . $this->config['additionalSearchFields'];
                $selectFields = GeneralUtility::trimExplode(',', $selectFieldsList, TRUE);
                $selectFields = array_unique($selectFields);
                $fieldSelectParts = array();
                foreach ($selectFields as $field) {
                    $fieldSelectParts[] = $field . $likeCondition;
                }
                $selectParts[] = '(' . implode(' OR ', $fieldSelectParts) . ')';
            }

            $this->selectClause = '(' . implode(' AND ', $selectParts) . ')';

            if ($searchUid > 0 && $searchUid == $searchString) {
                $this->selectClause = '(' . $this->selectClause . ' OR uid = ' . $searchUid . ')';
            }
        }
        if (isset($GLOBALS['TCA'][$this->table]['ctrl']['delete'])) {
            $this->selectClause .= ' AND ' . $GLOBALS['TCA'][$this->table]['ctrl']['delete'] . ' = 0';
        }
        if (count($this->allowedPages)) {
            $pidList = $GLOBALS['TYPO3_DB']->cleanIntArray($this->allowedPages);
            if (count($pidList)) {
                $this->selectClause .= ' AND pid IN (' . implode(', ', $pidList) . ') ';
            }
        }
        // add an additional search condition comment
        if (isset($this->config['searchCondition']) && strlen($this->config['searchCondition']) > 0) {
            $this->selectClause .= ' AND ' . $this->config['searchCondition'];
        }
        // add the global clauses to the where-statement
        $this->selectClause .= $this->addWhere;
    }


Files

SuggestDefaultReceiver.php (13.5 KB) SuggestDefaultReceiver.php Einar Gislason, 2014-09-30 15:44
Actions

Also available in: Atom PDF