diff --git a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php index 85c7b1165fea4dfff6538ef04b6af982b5c2b8e7..0d46e1693853edf9629c579df790daa7a1446b4e 100644 --- a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php +++ b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php @@ -73,21 +73,13 @@ public function query($group_by = FALSE) { $this->ensureMyTable(); if (!empty($this->options['break_phrase'])) { - $tids = new \stdClass(); - $tids->value = $this->argument; - $tids = $this->breakPhrase($this->argument, $tids); - if ($tids->value == array(-1)) { + $break = static::breakString($this->argument); + if ($break->value === array(-1)) { return FALSE; } - if (count($tids->value) > 1) { - $operator = 'IN'; - } - else { - $operator = '='; - } - - $tids = $tids->value; + $operator = (count($break->value) > 1) ? 'IN' : '='; + $tids = $break->value; } else { $operator = "="; diff --git a/core/modules/user/src/Tests/Views/HandlerArgumentUserUidTest.php b/core/modules/user/src/Tests/Views/HandlerArgumentUserUidTest.php index f2e8cd3c13a5bfdd8f9bc93c0c4b1d822fed1667..2327c58ae6200730b7ffa7f41191a1662d4ddcb2 100644 --- a/core/modules/user/src/Tests/Views/HandlerArgumentUserUidTest.php +++ b/core/modules/user/src/Tests/Views/HandlerArgumentUserUidTest.php @@ -50,6 +50,11 @@ public function testArgumentTitle() { $this->executeView($view, array($account->id() . ',0')); $this->assertEqual($view->getTitle(), $account->label() . ', ' . $anonymous); $view->destroy(); + + $view->getDisplay()->getHandler('argument', 'uid')->options['break_phrase'] = TRUE; + $this->executeView($view, array('0,' . $account->id())); + $this->assertEqual($view->getTitle(), $anonymous . ', ' . $account->label()); + $view->destroy(); } } diff --git a/core/modules/views/src/Plugin/views/HandlerBase.php b/core/modules/views/src/Plugin/views/HandlerBase.php index 33c8d81a9fd946e27631414f148d925bc0d90c50..ce31f43212e3ae880df5167ed61180b164ef2c7e 100644 --- a/core/modules/views/src/Plugin/views/HandlerBase.php +++ b/core/modules/views/src/Plugin/views/HandlerBase.php @@ -772,117 +772,42 @@ public function getEntityType() { } /** - * Breaks x,y,z and x+y+z into an array. Numeric only. + * Breaks x,y,z and x+y+z into an array. * * @param string $str - * The string to parse. - * @param \Drupal\views\Plugin\views\HandlerBase|null $handler - * The handler object to use as a base. If not specified one will - * be created. + * The string to split. + * @param bool $force_int + * Enforce a numeric check. * - * @return \Drupal\views\Plugin\views\HandlerBase|stdClass $handler - * The new handler object. + * @return \stdClass + * A stdClass object containing value and operator properties. */ - public static function breakPhrase($str, &$handler = NULL) { - if (!$handler) { - $handler = new \stdClass(); - } - - // Set up defaults: - - if (!isset($handler->value)) { - $handler->value = array(); - } - - if (!isset($handler->operator)) { - $handler->operator = 'or'; - } - - if (empty($str)) { - return $handler; - } + public static function breakString($str, $force_int = FALSE) { + $operator = NULL; + $value = array(); - if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str)) { + // Determine if the string has 'or' operators (plus signs) or 'and' + // operators (commas) and split the string accordingly. + if (preg_match('/^([\w0-9-_]+[+ ]+)+[\w0-9-_]+$/u', $str)) { // The '+' character in a query string may be parsed as ' '. - $handler->operator = 'or'; - $handler->value = preg_split('/[+ ]/', $str); - } - elseif (preg_match('/^([0-9]+,)*[0-9]+$/', $str)) { - $handler->operator = 'and'; - $handler->value = explode(',', $str); - } - - // Keep an 'error' value if invalid strings were given. - if (!empty($str) && (empty($handler->value) || !is_array($handler->value))) { - $handler->value = array(-1); - return $handler; - } - - // Doubly ensure that all values are numeric only. - foreach ($handler->value as $id => $value) { - $handler->value[$id] = intval($value); - } - - return $handler; - } - - /** - * Breaks x,y,z and x+y+z into an array. Works for strings. - * - * @param string $str - * The string to parse. - * @param \Drupal\views\Plugin\views\HandlerBase|null $handler - * The object to use as a base. If not specified one will - * be created. - * - * @return \Drupal\views\Plugin\views\HandlerBase|stdClass $handler - * The new handler object. - */ - public static function breakPhraseString($str, &$handler = NULL) { - if (!$handler) { - $handler = new \stdClass(); - } - - // Set up defaults: - if (!isset($handler->value)) { - $handler->value = array(); + $operator = 'or'; + $value = preg_split('/[+ ]/', $str); } - - if (!isset($handler->operator)) { - $handler->operator = 'or'; - } - - if ($str == '') { - return $handler; - } - - // Determine if the string has 'or' operators (plus signs) or 'and' operators - // (commas) and split the string accordingly. If we have an 'and' operator, - // spaces are treated as part of the word being split, but otherwise they are - // treated the same as a plus sign. - $or_wildcard = '[^\s+,]'; - $and_wildcard = '[^+,]'; - if (preg_match("/^({$or_wildcard}+[+ ])+{$or_wildcard}+$/", $str)) { - $handler->operator = 'or'; - $handler->value = preg_split('/[+ ]/', $str); - } - elseif (preg_match("/^({$and_wildcard}+,)*{$and_wildcard}+$/", $str)) { - $handler->operator = 'and'; - $handler->value = explode(',', $str); + elseif (preg_match('/^([\w0-9-_]+[, ]+)*[\w0-9-_]+$/u', $str)) { + $operator = 'and'; + $value = explode(',', $str); } - // Keep an 'error' value if invalid strings were given. - if (!empty($str) && (empty($handler->value) || !is_array($handler->value))) { - $handler->value = array(-1); - return $handler; - } + // Filter any empty matches (Like from '++' in a string) and reset the + // array keys. 'strlen' is used as the filter callback so we do not lose + // 0 values (would otherwise evaluate == FALSE). + $value = array_values(array_filter($value, 'strlen')); - // Doubly ensure that all values are strings only. - foreach ($handler->value as $id => $value) { - $handler->value[$id] = (string) $value; + if ($force_int) { + $value = array_map('intval', $value); } - return $handler; + return (object) array('value' => $value, 'operator' => $operator); } /** @@ -966,5 +891,4 @@ public function submitTemporaryForm($form, FormStateInterface $form_state) { // Write to cache $form_state['view']->cacheSet(); } - } diff --git a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php index 81a3182c7b7b237bb1f55e3d2a1052d6cd09d1a6..cc9012baaa8ad962a7c1d7818e7d12d8b44161a3 100644 --- a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php +++ b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php @@ -1151,6 +1151,18 @@ public static function encodeValidatorId($id) { public static function decodeValidatorId($id) { return str_replace('---', ':', $id); } + + /** + * Splits an argument into value and operator properties on this instance. + * + * @param bool $force_int + * Enforce that values should be numeric. + */ + protected function unpackArgumentValue($force_int = FALSE) { + $break = static::breakString($this->argument, $force_int); + $this->value = $break->value; + $this->operator = $break->operator; + } } /** diff --git a/core/modules/views/src/Plugin/views/argument/ManyToOne.php b/core/modules/views/src/Plugin/views/argument/ManyToOne.php index 4e3042689230f06e61edaf72bc4e2b7f41630a7d..669c944026bcda24474553327956f31624c0bf71 100644 --- a/core/modules/views/src/Plugin/views/argument/ManyToOne.php +++ b/core/modules/views/src/Plugin/views/argument/ManyToOne.php @@ -120,12 +120,8 @@ public function query($group_by = FALSE) { } if (!empty($this->options['break_phrase'])) { - if (!empty($this->definition['numeric'])) { - $this->breakPhrase($this->argument, $this); - } - else { - $this->breakPhraseString($this->argument, $this); - } + $force_int = !empty($this->definition['numeric']); + $this->unpackArgumentValue($force_int); } else { $this->value = array($this->argument); @@ -141,7 +137,8 @@ function title() { } if (!empty($this->options['break_phrase'])) { - $this->breakPhrase($this->argument, $this); + $force_int = !empty($this->definition['numeric']); + $this->unpackArgumentValue($force_int); } else { $this->value = array($this->argument); diff --git a/core/modules/views/src/Plugin/views/argument/Numeric.php b/core/modules/views/src/Plugin/views/argument/Numeric.php index 951ce654220c556bee45dcd36858b96234cd59fc..3051790e28e2d6e9055220bc944c9dcb02994444 100644 --- a/core/modules/views/src/Plugin/views/argument/Numeric.php +++ b/core/modules/views/src/Plugin/views/argument/Numeric.php @@ -67,7 +67,9 @@ function title() { } if (!empty($this->options['break_phrase'])) { - $this->breakPhrase($this->argument, $this); + $break = static::breakString($this->argument, TRUE); + $this->value = $break->value; + $this->operator = $break->operator; } else { $this->value = array($this->argument); @@ -98,7 +100,9 @@ public function query($group_by = FALSE) { $this->ensureMyTable(); if (!empty($this->options['break_phrase'])) { - $this->breakPhrase($this->argument, $this); + $break = static::breakString($this->argument, TRUE); + $this->value = $break->value; + $this->operator = $break->operator; } else { $this->value = array($this->argument); diff --git a/core/modules/views/src/Plugin/views/argument/String.php b/core/modules/views/src/Plugin/views/argument/String.php index 3f92185b8092c9e8db74b03f87946dab24ce2fcb..a900d0de8b15184a1dd2a0f2045593be5c19ae30 100644 --- a/core/modules/views/src/Plugin/views/argument/String.php +++ b/core/modules/views/src/Plugin/views/argument/String.php @@ -189,7 +189,7 @@ public function query($group_by = FALSE) { } if (!empty($this->options['break_phrase'])) { - $this->breakPhraseString($argument, $this); + $this->unpackArgumentValue(); } else { $this->value = array($argument); @@ -263,7 +263,7 @@ function title() { } if (!empty($this->options['break_phrase'])) { - $this->breakPhraseString($this->argument, $this); + $this->unpackArgumentValue(); } else { $this->value = array($this->argument); diff --git a/core/modules/views/src/Tests/Handler/HandlerTest.php b/core/modules/views/src/Tests/Handler/HandlerTest.php index 81e05aefca396112762ccf6ae613337c946e3e5b..9c9e038856e9af7381daeb7d905e32328b02ecb8 100644 --- a/core/modules/views/src/Tests/Handler/HandlerTest.php +++ b/core/modules/views/src/Tests/Handler/HandlerTest.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\views\Tests\Handler\HandlerTest. + * Contains \Drupal\views\Tests\Handler\HandlerTest. */ namespace Drupal\views\Tests\Handler; @@ -85,102 +85,99 @@ function testFilterInOperatorUi() { } /** - * Tests the breakPhraseString() method. + * Tests the breakString method. */ - function testBreakPhraseString() { - $empty_stdclass = new \stdClass(); - $empty_stdclass->operator = 'or'; - $empty_stdclass->value = array(); - - // check defaults - $null = NULL; - $this->assertEqual($empty_stdclass, HandlerBase::breakPhraseString('', $null)); - - $item = array( - 'table' => 'node', - 'field' => 'title', - ); - $handler = $this->container->get('plugin.manager.views.argument')->getHandler($item); - $this->assertEqual($handler, HandlerBase::breakPhraseString('', $handler), 'The breakPhraseString() method works correctly.'); + public function testBreakString() { + // Check defaults. + $this->assertEqual((object) array('value' => array(), 'operator' => NULL), HandlerBase::breakString('')); - // test ors - $handler = HandlerBase::breakPhraseString('word1 word2+word'); + // Test ors + $handler = HandlerBase::breakString('word1 word2+word'); $this->assertEqualValue(array('word1', 'word2', 'word'), $handler); $this->assertEqual('or', $handler->operator); - $handler = HandlerBase::breakPhraseString('word1+word2+word'); + $handler = HandlerBase::breakString('word1+word2+word'); $this->assertEqualValue(array('word1', 'word2', 'word'), $handler); $this->assertEqual('or', $handler->operator); - $handler = HandlerBase::breakPhraseString('word1 word2 word'); + $handler = HandlerBase::breakString('word1 word2 word'); $this->assertEqualValue(array('word1', 'word2', 'word'), $handler); $this->assertEqual('or', $handler->operator); - $handler = HandlerBase::breakPhraseString('word-1+word-2+word'); + $handler = HandlerBase::breakString('word-1+word-2+word'); $this->assertEqualValue(array('word-1', 'word-2', 'word'), $handler); $this->assertEqual('or', $handler->operator); - $handler = HandlerBase::breakPhraseString('wõrd1+wõrd2+wõrd'); + $handler = HandlerBase::breakString('wõrd1+wõrd2+wõrd'); $this->assertEqualValue(array('wõrd1', 'wõrd2', 'wõrd'), $handler); $this->assertEqual('or', $handler->operator); - // test ands. - $handler = HandlerBase::breakPhraseString('word1,word2,word'); + // Test ands. + $handler = HandlerBase::breakString('word1,word2,word'); $this->assertEqualValue(array('word1', 'word2', 'word'), $handler); $this->assertEqual('and', $handler->operator); - $handler = HandlerBase::breakPhraseString('word1 word2,word'); + $handler = HandlerBase::breakString('word1 word2,word'); $this->assertEqualValue(array('word1 word2', 'word'), $handler); $this->assertEqual('and', $handler->operator); - $handler = HandlerBase::breakPhraseString('word1,word2 word'); + $handler = HandlerBase::breakString('word1,word2 word'); $this->assertEqualValue(array('word1', 'word2 word'), $handler); $this->assertEqual('and', $handler->operator); - $handler = HandlerBase::breakPhraseString('word-1,word-2,word'); + $handler = HandlerBase::breakString('word-1,word-2,word'); $this->assertEqualValue(array('word-1', 'word-2', 'word'), $handler); $this->assertEqual('and', $handler->operator); - $handler = HandlerBase::breakPhraseString('wõrd1,wõrd2,wõrd'); + $handler = HandlerBase::breakString('wõrd1,wõrd2,wõrd'); $this->assertEqualValue(array('wõrd1', 'wõrd2', 'wõrd'), $handler); $this->assertEqual('and', $handler->operator); - // test a single word - $handler = HandlerBase::breakPhraseString('word'); + // Test a single word + $handler = HandlerBase::breakString('word'); $this->assertEqualValue(array('word'), $handler); $this->assertEqual('and', $handler->operator); - } - - /** - * Tests Drupal\views\Plugin\views\HandlerBase::breakPhrase() function. - */ - function testBreakPhrase() { - $empty_stdclass = new \stdClass(); - $empty_stdclass->operator = 'or'; - $empty_stdclass->value = array(); - - $null = NULL; - // check defaults - $this->assertEqual($empty_stdclass, HandlerBase::breakPhrase('', $null)); - - $item = array( - 'table' => 'node', - 'field' => 'title', - ); - $handler = $this->container->get('plugin.manager.views.argument')->getHandler($item); - $this->assertEqual($handler, HandlerBase::breakPhrase('', $handler), 'The breakPhrase() method works correctly.'); + $s1 = $this->randomMachineName(); // Generate three random numbers which can be used below; $n1 = rand(0, 100); $n2 = rand(0, 100); $n3 = rand(0, 100); - // test ors - $this->assertEqualValue(array($n1, $n2, $n3), HandlerBase::breakPhrase("$n1 $n2+$n3", $handler)); - $this->assertEqual('or', $handler->operator); - $this->assertEqualValue(array($n1, $n2, $n3), HandlerBase::breakPhrase("$n1+$n2+$n3", $handler)); - $this->assertEqual('or', $handler->operator); - $this->assertEqualValue(array($n1, $n2, $n3), HandlerBase::breakPhrase("$n1 $n2 $n3", $handler)); - $this->assertEqual('or', $handler->operator); - $this->assertEqualValue(array($n1, $n2, $n3), HandlerBase::breakPhrase("$n1 $n2++$n3", $handler)); - $this->assertEqual('or', $handler->operator); - // test ands. - $this->assertEqualValue(array($n1, $n2, $n3), HandlerBase::breakPhrase("$n1,$n2,$n3", $handler)); - $this->assertEqual('and', $handler->operator); - $this->assertEqualValue(array($n1, $n2, $n3), HandlerBase::breakPhrase("$n1,,$n2,$n3", $handler)); - $this->assertEqual('and', $handler->operator); + // Test "or"s. + $handlerBase = HandlerBase::breakString("$s1 $n2+$n3"); + $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1+$n2+$n3"); + $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1 $n2 $n3"); + $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1 $n2++$n3"); + $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + // Test "and"s. + $handlerBase = HandlerBase::breakString("$s1,$n2,$n3"); + $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); + $this->assertEqual('and', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1,,$n2,$n3"); + $this->assertEqualValue(array($s1, $n2, $n3), $handlerBase); + $this->assertEqual('and', $handlerBase->operator); + + // Enforce int values. + $handlerBase = HandlerBase::breakString("$n1,$n2,$n3", TRUE); + $this->assertEqualValue(array($n1, $n2, $n3), $handlerBase); + $this->assertEqual('and', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$n1+$n2+$n3", TRUE); + $this->assertEqualValue(array($n1, $n2, $n3), $handlerBase); + $this->assertEqual('or', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1,$n2,$n3", TRUE); + $this->assertEqualValue(array((int) $s1, $n2, $n3), $handlerBase); + $this->assertEqual('and', $handlerBase->operator); + + $handlerBase = HandlerBase::breakString("$s1+$n2+$n3", TRUE); + $this->assertEqualValue(array((int) $s1, $n2, $n3), $handlerBase); + $this->assertEqual('or', $handlerBase->operator); } /** @@ -214,8 +211,8 @@ public function testHandlerWeights() { /** * Check to see if a value is the same as the value on a certain handler. * - * @param $first - * The first value to check. + * @param $expected + * The expected value to check. * @param \Drupal\views\Plugin\views\HandlerBase $handler * The handler that has the $handler->value property to compare with first. * @param string $message @@ -226,8 +223,12 @@ public function testHandlerWeights() { * @return bool * TRUE if the assertion succeeded, FALSE otherwise. */ - protected function assertEqualValue($first, $handler, $message = '', $group = 'Other') { - return $this->assert($first == $handler->value, $message ? $message : t('First value is equal to second value'), $group); + protected function assertEqualValue($expected, $handler, $message = '', $group = 'Other') { + if (empty($message)) { + $message = t('Comparing @first and @second', array('@first' => implode(',', $expected), '@second' => implode(',', $handler->value))); + } + + return $this->assert($expected == $handler->value, $message, $group); } /**