Skip to content

Commit

Permalink
Merge pull request #9374 from jitendrapurohit/CRM-19048
Browse files Browse the repository at this point in the history
CRM-19048 - Additional fix
  • Loading branch information
Yashodha Chaku authored Dec 7, 2016
2 parents d9d5262 + 9325219 commit 2fa4cf8
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 7 deletions.
36 changes: 31 additions & 5 deletions CRM/Utils/QueryFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,17 @@ protected function _formatFts($text, $mode) {
*/
protected function _formatFtsBool($text, $mode) {
$result = NULL;
$operators = array('+', '-', '~', '(', ')');

//Return if searched string ends with an unsupported operator.
foreach ($operators as $val) {
if ($text == '@' || CRM_Utils_String::endsWith($text, $val)) {
$csid = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', 'CRM_Contact_Form_Search_Custom_FullText', 'value', 'name');
$url = CRM_Utils_System::url("civicrm/contact/search/custom", "csid={$csid}&reset=1");
$operators = implode("', '", $operators);
CRM_Core_Error::statusBounce("Full-Text Search does not support the use of a search string ending with any of these operators ('{$operators}' or a single '@'). Please adjust your search term and try again.", $url);
}
}

// normalize user-inputted wildcards
$text = str_replace('%', '*', $text);
Expand All @@ -309,7 +320,7 @@ protected function _formatFtsBool($text, $mode) {
else {
switch ($mode) {
case self::MODE_NONE:
$result = $this->mapWords($text, '+word');
$result = $this->mapWords($text, '+word', TRUE);
break;

case self::MODE_PHRASE:
Expand Down Expand Up @@ -380,21 +391,24 @@ protected function _formatLike($text, $mode) {
* User-supplied query string.
* @param string $template
* A prototypical description of each word, eg "word%" or "word*" or "*word*".
* @param bool $quotes
* True if each searched keyword need to be surrounded with quotes.
* @return string
*/
protected function mapWords($text, $template) {
protected function mapWords($text, $template, $quotes = FALSE) {
$result = array();
foreach ($this->parseWords($text) as $word) {
foreach ($this->parseWords($text, $quotes) as $word) {
$result[] = str_replace('word', $word, $template);
}
return implode(' ', $result);
}

/**
* @param $text
* @bool $quotes
* @return array
*/
protected function parseWords($text) {
protected function parseWords($text, $quotes) {
//NYSS 9692 special handling for emails
if (preg_match('/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/', $text)) {
$parts = explode('@', $text);
Expand All @@ -403,7 +417,19 @@ protected function parseWords($text) {
}

//NYSS also replace other occurrences of @
return explode(' ', preg_replace('/[ \r\n\t\@]+/', ' ', trim($text)));
$replacedText = preg_replace('/[ \r\n\t\@]+/', ' ', trim($text));
//filter empty values if any
$keywords = array_filter(explode(' ', $replacedText));

//Ensure each searched keywords are wrapped in double quotes.
if ($quotes) {
foreach ($keywords as &$val) {
if (!is_numeric($val)) {
$val = "\"{$val}\"";
}
}
}
return $keywords;
}

/**
Expand Down
7 changes: 5 additions & 2 deletions tests/phpunit/CRM/Utils/QueryFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function dataProvider() {
$cases[] = array('someone@example.com', 'fts', 'wildwords', '*someone* *example*', $allEmailRows);
$cases[] = array('someone@example.com', 'fts', 'wildwords-suffix', 'someone* example*', $allEmailRows);

$cases[] = array('someone@example.com', 'ftsbool', 'simple', '+someone +example', $allEmailRows);
$cases[] = array('someone@example.com', 'ftsbool', 'simple', '+"someone" +"example"', $allEmailRows);
$cases[] = array('someone@example.com', 'ftsbool', 'phrase', '+"someone@example.com"', $allEmailRows);
$cases[] = array('someone@example.com', 'ftsbool', 'wildphrase', '+"*someone@example.com*"', $allEmailRows);
$cases[] = array('someone@example.com', 'ftsbool', 'wildwords', '+*someone* +*example*', $allEmailRows);
Expand All @@ -92,7 +92,7 @@ public function dataProvider() {
$cases[] = array('first second', 'fts', 'wildwords', '*first* *second*', array(3, 4, 5, 7));
$cases[] = array('first second', 'fts', 'wildwords-suffix', 'first* second*', array(3, 4, 5, 7));

$cases[] = array('first second', 'ftsbool', 'simple', '+first +second', array(3, 4, 5));
$cases[] = array('first second', 'ftsbool', 'simple', '+"first" +"second"', array(3, 4, 5));
$cases[] = array('first second', 'ftsbool', 'phrase', '+"first second"', array(3, 4, 5));
$cases[] = array('first second', 'ftsbool', 'wildphrase', '+"*first second*"', array(3, 4, 5));
$cases[] = array('first second', 'ftsbool', 'wildwords', '+*first* +*second*', array(3, 4, 5, 7));
Expand All @@ -104,6 +104,9 @@ public function dataProvider() {
$cases[] = array('first second', 'solr', 'wildwords', '*first* *second*', NULL);
$cases[] = array('first second', 'solr', 'wildwords-suffix', 'first* second*', NULL);

$cases[] = array('someone@', 'ftsbool', 'simple', '+"someone"', $allEmailRows);
$cases[] = array('@example.com', 'ftsbool', 'simple', '+"example.com"', $allEmailRows);

// If user supplies wildcards, then ignore mode.
foreach (array(
'simple',
Expand Down

0 comments on commit 2fa4cf8

Please sign in to comment.