diff --git a/core/modules/search/lib/Drupal/search/SearchExpression.php b/core/modules/search/lib/Drupal/search/SearchExpression.php new file mode 100644 index 0000000..cd5e5dc --- /dev/null +++ b/core/modules/search/lib/Drupal/search/SearchExpression.php @@ -0,0 +1,93 @@ +expression = $expression; + } + + /** + * Gets the expression. + * + * @return string + */ + public function getExpression() { + return $this->expression; + } + + /** + * Extracts a module-specific search option from a search expression. + * + * Search options are added using SearchExpression::insert() and retrieved + * using SearchExpression::extract(). They take the form option:value, and + * are added to the ordinary keywords in the search expression. + * + * @param string $option + * The name of the option to retrieve from the search expression. + * + * @return string + * The value previously stored in the search expression for option $option, + * if any. Trailing spaces in values will not be included. + */ + public function extract($option) { + if (preg_match('/(^| )' . $option . ':([^ ]*)( |$)/i', $this->expression, $matches)) { + return $matches[2]; + } + } + + /** + * Adds a module-specific search option to a search expression. + * + * Search options are added using SearchExpression::insert() and retrieved + * using SearchExpression::extract(). They take the form option:value, and + * are added to the ordinary keywords in the search expression. + * + * @param string $option + * The name of the option to add to the search expression. + * @param string $value + * The value to add for the option. If present, it will replace any previous + * value added for the option. Cannot contain any spaces or | characters, as + * these are used as delimiters. If you want to add a blank value $option: to + * the search expression, pass in an empty string or a string that is + * composed of only spaces. To clear a previously-stored option without + * adding a replacement, pass in NULL for $value or omit. + * + * @return static|\Drupal\search\SearchExpression + * The search expression, with any previous value for this option removed, and + * a new $option:$value pair added if $value was provided. + */ + public function insert($option, $value = NULL) { + // Remove any previous values stored with $option. + $this->expression = trim(preg_replace('/(^| )' . $option . ':[^ ]*/i', '', $this->expression)); + + // Set new value, if provided. + if (isset($value)) { + $this->expression .= ' ' . $option . ':' . trim($value); + } + return $this; + } + +} diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchExpressionInsertExtractTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchExpressionInsertExtractTest.php deleted file mode 100644 index b7ea84a..0000000 --- a/core/modules/search/lib/Drupal/search/Tests/SearchExpressionInsertExtractTest.php +++ /dev/null @@ -1,71 +0,0 @@ - 'Search expression insert/extract', - 'description' => 'Tests the functions search_expression_insert() and search_expression_extract()', - 'group' => 'Search', - ); - } - - function setUp() { - drupal_load('module', 'search'); - parent::setUp(); - } - - /** - * Tests search_expression_insert() and search_expression_extract(). - */ - function testInsertExtract() { - $base_expression = "mykeyword"; - // Build an array of option, value, what should be in the expression, what - // should be retrieved from expression. - $cases = array( - array('foo', 'bar', 'foo:bar', 'bar'), // Normal case. - array('foo', NULL, '', NULL), // Empty value: shouldn't insert. - array('foo', ' ', 'foo:', ''), // Space as value: should insert but retrieve empty string. - array('foo', '', 'foo:', ''), // Empty string as value: should insert but retrieve empty string. - array('foo', '0', 'foo:0', '0'), // String zero as value: should insert. - array('foo', 0, 'foo:0', '0'), // Numeric zero as value: should insert. - ); - - foreach ($cases as $index => $case) { - $after_insert = search_expression_insert($base_expression, $case[0], $case[1]); - if (empty($case[2])) { - $this->assertEqual($after_insert, $base_expression, "Empty insert does not change expression in case $index"); - } - else { - $this->assertEqual($after_insert, $base_expression . ' ' . $case[2], "Insert added correct expression for case $index"); - } - - $retrieved = search_expression_extract($after_insert, $case[0]); - if (!isset($case[3])) { - $this->assertFalse(isset($retrieved), "Empty retrieval results in unset value in case $index"); - } - else { - $this->assertEqual($retrieved, $case[3], "Value is retrieved for case $index"); - } - - $after_clear = search_expression_insert($after_insert, $case[0]); - $this->assertEqual(trim($after_clear), $base_expression, "After clearing, base expression is restored for case $index"); - - $cleared = search_expression_extract($after_clear, $case[0]); - $this->assertFalse(isset($cleared), "After clearing, value could not be retrieved for case $index"); - } - } -} diff --git a/core/modules/search/search.module b/core/modules/search/search.module index 9de229b..48b75f4 100644 --- a/core/modules/search/search.module +++ b/core/modules/search/search.module @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Component\Utility\Unicode; +use Drupal\search\SearchExpression; /** * Matches all 'N' Unicode character classes (numbers) @@ -867,9 +868,8 @@ function search_comment_unpublish($comment) { * if any. Trailing spaces in values will not be included. */ function search_expression_extract($expression, $option) { - if (preg_match('/(^| )' . $option . ':([^ ]*)( |$)/i', $expression, $matches)) { - return $matches[2]; - } + $expression = new SearchExpression($expression); + return $expression->extract($option); } /** @@ -896,14 +896,8 @@ function search_expression_extract($expression, $option) { * a new $option:$value pair added if $value was provided. */ function search_expression_insert($expression, $option, $value = NULL) { - // Remove any previous values stored with $option. - $expression = trim(preg_replace('/(^| )' . $option . ':[^ ]*/i', '', $expression)); - - // Set new value, if provided. - if (isset($value)) { - $expression .= ' ' . $option . ':' . trim($value); - } - return $expression; + $expression = new SearchExpression($expression); + return $expression->insert($option, $value)->getExpression(); } /** diff --git a/core/modules/search/tests/Drupal/search/Tests/SearchExpressionTest.php b/core/modules/search/tests/Drupal/search/Tests/SearchExpressionTest.php new file mode 100644 index 0000000..27f59ed --- /dev/null +++ b/core/modules/search/tests/Drupal/search/Tests/SearchExpressionTest.php @@ -0,0 +1,89 @@ + 'Search expression insert/extract', + 'description' => 'Tests the search expression class.', + 'group' => 'Search', + ); + } + + + /** + * Provides data for the search expression tests. + * + * @return array + * An array of values passed to the test methods. + */ + public function dataProvider() { + $cases = array( + // Normal case. + array('foo', 'bar', 'foo:bar', 'bar'), + // Empty value: shouldn't insert. + array('foo', NULL, '', NULL), + // Space as value: should insert but retrieve empty string. + array('foo', ' ', 'foo:', ''), + // Empty string as value: should insert but retrieve empty string. + array('foo', '', 'foo:', ''), + // String zero as value: should insert. + array('foo', '0', 'foo:0', '0'), + // Numeric zero as value: should insert. + array('foo', 0, 'foo:0', '0'), + ); + return $cases; + } + + /** + * Tests the search expression methods. + * + * @dataProvider dataProvider + */ + public function testInsertExtract($case_0, $case_1, $case_2, $case_3) { + $base_expression = 'mykeyword'; + // Build an array of option, value, what should be in the expression, what + // should be retrieved from expression. + + $after_insert = new SearchExpression($base_expression); + $after_insert->insert($case_0, $case_1); + + if (empty($case_2)) { + $this->assertEquals($base_expression, $after_insert->getExpression(), 'Empty insert does change expression.'); + } + else { + $this->assertEquals($base_expression . ' ' . $case_2, $after_insert->getExpression(), 'Insert added incorrect expression.'); + } + + $retrieved = $after_insert->extract($case_0); + + if (!isset($case_3)) { + $this->assertFalse(isset($retrieved), 'Empty retrieval results in unset value.'); + } + else { + $this->assertEquals($case_3, $retrieved, 'Value is retrieved.'); + } + + $after_clear = $after_insert->insert($case_0); + $this->assertEquals($base_expression, $after_clear->getExpression(), 'After clearing, base expression is not restored.'); + + $cleared = $after_clear->extract($case_0); + $this->assertFalse(isset($cleared), 'After clearing, value could be retrieved.'); + } + +}