diff --git a/core/includes/common.inc b/core/includes/common.inc index bee692e..68123cf 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -2,6 +2,7 @@ use Drupal\Component\Utility\Crypt; use Drupal\Component\Utility\String; +use Drupal\Component\Utility\Tags; use Drupal\Component\Utility\UrlValidator; use Drupal\Component\Utility\Xss; use Drupal\Core\Cache\Cache; @@ -13,6 +14,7 @@ use Drupal\Component\PhpStorage\PhpStorageFactory; use Drupal\Component\Utility\MapArray; use Drupal\Component\Utility\NestedArray; +use Drupal\Component\Utility\Unicode; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Database\Database; @@ -786,6 +788,8 @@ function valid_email_address($mail) { * TRUE if the URL is in a valid format. * * @see \Drupal\Component\Utility\UrlValidator::isValid() + * + * @deprecated as of Drupal 8.0. Use UrlValidator::isValid() instead. */ function valid_url($url, $absolute = FALSE) { return UrlValidator::isValid($url, $absolute); @@ -5584,44 +5588,24 @@ function watchdog_severity_levels() { * Explodes a string of tags into an array. * * @see drupal_implode_tags() + * @see \Drupal\Component\Utility\String::explodeTags(). + * + * @deprecated as of Drupal 8.0. Use Tags::explode() instead. */ function drupal_explode_tags($tags) { - // This regexp allows the following types of user input: - // this, "somecompany, llc", "and ""this"" w,o.rks", foo bar - $regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x'; - preg_match_all($regexp, $tags, $matches); - $typed_tags = array_unique($matches[1]); - - $tags = array(); - foreach ($typed_tags as $tag) { - // If a user has escaped a term (to demonstrate that it is a group, - // or includes a comma or quote character), we remove the escape - // formatting so to save the term into the database as the user intends. - $tag = trim(str_replace('""', '"', preg_replace('/^"(.*)"$/', '\1', $tag))); - if ($tag != "") { - $tags[] = $tag; - } - } - - return $tags; + return Tags::explode($tags); } /** * Implodes an array of tags into a string. * * @see drupal_explode_tags() + * @see \Drupal\Component\Utility\String::implodeTags(). + * + * @deprecated as of Drupal 8.0. Use Tags::implode() instead. */ function drupal_implode_tags($tags) { - $encoded_tags = array(); - foreach ($tags as $tag) { - // Commas and quotes in tag names are special cases, so encode them. - if (strpos($tag, ',') !== FALSE || strpos($tag, '"') !== FALSE) { - $tag = '"' . str_replace('"', '""', $tag) . '"'; - } - - $encoded_tags[] = $tag; - } - return implode(', ', $encoded_tags); + return Tags::implode($tags); } /** diff --git a/core/lib/Drupal/Component/Utility/Tags.php b/core/lib/Drupal/Component/Utility/Tags.php new file mode 100644 index 0000000..075eaec --- /dev/null +++ b/core/lib/Drupal/Component/Utility/Tags.php @@ -0,0 +1,67 @@ +[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x'; + preg_match_all($regexp, $tags, $matches); + $typed_tags = array_unique($matches[1]); + + $tags = array(); + foreach ($typed_tags as $tag) { + // If a user has escaped a term (to demonstrate that it is a group, + // or includes a comma or quote character), we remove the escape + // formatting so to save the term into the database as the user intends. + $tag = trim(str_replace('""', '"', preg_replace('/^"(.*)"$/', '\1', $tag))); + if ($tag != "") { + $tags[] = $tag; + } + } + + return $tags; + } + + /** + * Implodes an array of tags into a string. + * + * @param array $tags + * An array of tags. + * + * @return string + * The imploded string. + */ + public static function implode($tags) { + $encoded_tags = array(); + foreach ($tags as $tag) { + // Commas and quotes in tag names are special cases, so encode them. + if (strpos($tag, ',') !== FALSE || strpos($tag, '"') !== FALSE) { + $tag = '"' . str_replace('"', '""', $tag) . '"'; + } + + $encoded_tags[] = $tag; + } + return implode(', ', $encoded_tags); + } + +} diff --git a/core/lib/Drupal/Core/Template/AttributeArray.php b/core/lib/Drupal/Core/Template/AttributeArray.php index d3521e0..a32201e 100644 --- a/core/lib/Drupal/Core/Template/AttributeArray.php +++ b/core/lib/Drupal/Core/Template/AttributeArray.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Template; +use Drupal\Component\Utility\String; /** * A class that defines a type of Attribute that can be added to as an array. @@ -66,7 +67,7 @@ public function offsetExists($offset) { */ public function __toString() { $this->printed = TRUE; - return implode(' ', array_map('check_plain', $this->value)); + return implode(' ', array_map(array('Drupal\Component\Utility\String', 'checkPlain'), $this->value)); } /** diff --git a/core/lib/Drupal/Core/Template/AttributeString.php b/core/lib/Drupal/Core/Template/AttributeString.php index 9776467..2c3ca24 100644 --- a/core/lib/Drupal/Core/Template/AttributeString.php +++ b/core/lib/Drupal/Core/Template/AttributeString.php @@ -7,6 +7,8 @@ namespace Drupal\Core\Template; +use Drupal\Component\Utility\String; + /** * A class that represents most standard HTML attributes. * @@ -29,7 +31,7 @@ class AttributeString extends AttributeValueBase { */ public function __toString() { $this->printed = TRUE; - return check_plain($this->value); + return String::checkPlain($this->value); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/AttributesUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/AttributesUnitTest.php deleted file mode 100644 index 7b5305d..0000000 --- a/core/modules/system/lib/Drupal/system/Tests/Common/AttributesUnitTest.php +++ /dev/null @@ -1,56 +0,0 @@ - 'HTML Attributes', - 'description' => 'Tests the Drupal\Core\Template\Attribute functionality.', - 'group' => 'Common', - ); - } - - /** - * Tests that drupal_html_class() cleans the class name properly. - */ - function testDrupalAttributes() { - // Verify that special characters are HTML encoded. - $this->assertIdentical((string) new Attribute(array('title' => '&"\'<>')), ' title="&"'<>"', 'HTML encode attribute values.'); - - // Verify multi-value attributes are concatenated with spaces. - $attributes = array('class' => array('first', 'last')); - $this->assertIdentical((string) new Attribute(array('class' => array('first', 'last'))), ' class="first last"', 'Concatenate multi-value attributes.'); - - // Verify empty attribute values are rendered. - $this->assertIdentical((string) new Attribute(array('alt' => '')), ' alt=""', 'Empty attribute value #1.'); - $this->assertIdentical((string) new Attribute(array('alt' => NULL)), ' alt=""', 'Empty attribute value #2.'); - - // Verify multiple attributes are rendered. - $attributes = array( - 'id' => 'id-test', - 'class' => array('first', 'last'), - 'alt' => 'Alternate', - ); - $this->assertIdentical((string) new Attribute($attributes), ' id="id-test" class="first last" alt="Alternate"', 'Multiple attributes.'); - - // Verify empty attributes array is rendered. - $this->assertIdentical((string) new Attribute(array()), '', 'Empty attributes array.'); - - $attribute = new Attribute(array('key1' => 'value1')); - foreach($attribute as $value) { - $this->assertIdentical((string) $value, 'value1', 'Iterate over attribute.'); - } - } -} diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/ValidUrlUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/ValidUrlUnitTest.php deleted file mode 100644 index 6750d27..0000000 --- a/core/modules/system/lib/Drupal/system/Tests/Common/ValidUrlUnitTest.php +++ /dev/null @@ -1,118 +0,0 @@ - 'URL validation', - 'description' => 'Tests URL validation by valid_url()', - 'group' => 'Common', - ); - } - - /** - * Tests valid absolute URLs. - */ - function testValidAbsolute() { - $url_schemes = array('http', 'https', 'ftp'); - $valid_absolute_urls = array( - 'example.com', - 'www.example.com', - 'ex-ample.com', - '3xampl3.com', - 'example.com/paren(the)sis', - 'example.com/index.html#pagetop', - 'example.com:8080', - 'subdomain.example.com', - 'example.com/index.php/node', - 'example.com/index.php/node?param=false', - 'user@www.example.com', - 'user:pass@www.example.com:8080/login.php?do=login&style=%23#pagetop', - '127.0.0.1', - 'example.org?', - 'john%20doe:secret:foo@example.org/', - 'example.org/~,$\'*;', - 'caf%C3%A9.example.org', - '[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html', - ); - - foreach ($url_schemes as $scheme) { - foreach ($valid_absolute_urls as $url) { - $test_url = $scheme . '://' . $url; - $valid_url = valid_url($test_url, TRUE); - $this->assertTrue($valid_url, format_string('@url is a valid URL.', array('@url' => $test_url))); - } - } - } - - /** - * Tests invalid absolute URLs. - */ - function testInvalidAbsolute() { - $url_schemes = array('http', 'https', 'ftp'); - $invalid_ablosule_urls = array( - '', - 'ex!ample.com', - 'ex%ample.com', - ); - - foreach ($url_schemes as $scheme) { - foreach ($invalid_ablosule_urls as $url) { - $test_url = $scheme . '://' . $url; - $valid_url = valid_url($test_url, TRUE); - $this->assertFalse($valid_url, format_string('@url is NOT a valid URL.', array('@url' => $test_url))); - } - } - } - - /** - * Tests valid relative URLs. - */ - function testValidRelative() { - $valid_relative_urls = array( - 'paren(the)sis', - 'index.html#pagetop', - 'index.php/node', - 'index.php/node?param=false', - 'login.php?do=login&style=%23#pagetop', - ); - - foreach (array('', '/') as $front) { - foreach ($valid_relative_urls as $url) { - $test_url = $front . $url; - $valid_url = valid_url($test_url); - $this->assertTrue($valid_url, format_string('@url is a valid URL.', array('@url' => $test_url))); - } - } - } - - /** - * Tests invalid relative URLs. - */ - function testInvalidRelative() { - $invalid_relative_urls = array( - 'ex^mple', - 'example<>', - 'ex%ample', - ); - - foreach (array('', '/') as $front) { - foreach ($invalid_relative_urls as $url) { - $test_url = $front . $url; - $valid_url = valid_url($test_url); - $this->assertFALSE($valid_url, format_string('@url is NOT a valid URL.', array('@url' => $test_url))); - } - } - } -} diff --git a/core/tests/Drupal/Tests/Core/Common/AttributesTest.php b/core/tests/Drupal/Tests/Core/Common/AttributesTest.php new file mode 100644 index 0000000..bccd205 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Common/AttributesTest.php @@ -0,0 +1,76 @@ + 'HTML Attributes', + 'description' => 'Tests the Drupal\Core\Template\Attribute functionality.', + 'group' => 'Common', + ); + } + + /** + * Provides data for the Attribute test. + * + * @return array + */ + public function provideAttributeData() { + return array( + // Verify that special characters are HTML encoded. + array(array('title' => '&"\'<>'), ' title="&"'<>"', 'HTML encode attribute values.'), + // Verify multi-value attributes are concatenated with spaces. + array(array('class' => array('first', 'last')), ' class="first last"', 'Concatenate multi-value attributes.'), + // Verify empty attribute values are rendered. + array(array('alt' => ''), ' alt=""', 'Empty attribute value #1.'), + array(array('alt' => NULL), ' alt=""', 'Empty attribute value #2.'), + // Verify multiple attributes are rendered. + array( + array( + 'id' => 'id-test', + 'class' => array('first', 'last'), + 'alt' => 'Alternate', + ), + ' id="id-test" class="first last" alt="Alternate"', + 'Multiple attributes.' + ), + // Verify empty attributes array is rendered. + array(array(), '', 'Empty attributes array.'), + ); + } + + /** + * Tests casting an Attribute object to a string. + * + * @see \Drupal\Core\Template\Attribute::__toString() + * + * @dataProvider provideAttributeData + */ + function testDrupalAttributes($attributes, $expected, $message) { + $this->assertSame($expected, (string) new Attribute($attributes), $message); + } + + /** + * Test attribute iteration + */ + public function testAttributeIteration() { + $attribute = new Attribute(array('key1' => 'value1')); + foreach ($attribute as $value) { + $this->assertSame((string) $value, 'value1', 'Iterate over attribute.'); + } + } + +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/DiffArrayUnitTest.php b/core/tests/Drupal/Tests/Core/Common/DiffArrayTest.php similarity index 85% rename from core/modules/system/lib/Drupal/system/Tests/Common/DiffArrayUnitTest.php rename to core/tests/Drupal/Tests/Core/Common/DiffArrayTest.php index a5ae7d2..b4fc6c3 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/DiffArrayUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Common/DiffArrayTest.php @@ -2,18 +2,18 @@ /** * @file - * Contains \Drupal\system\Tests\Common\DiffArrayUnitTest. + * Contains \Drupal\Tests\Core\Common\DiffArrayTest. */ -namespace Drupal\system\Tests\Common; +namespace Drupal\Tests\Core\Common; use Drupal\Component\Utility\DiffArray; -use Drupal\simpletest\UnitTestBase; +use Drupal\Tests\UnitTestCase; /** * Tests the DiffArray helper class. */ -class DiffArrayUnitTest extends UnitTestBase { +class DiffArrayTest extends UnitTestCase { /** * Array to use for testing. @@ -77,7 +77,7 @@ public function testDiffAssocRecursive() { 'new' => 'new', ); - $this->assertIdentical(DiffArray::diffAssocRecursive($this->array1, $this->array2), $expected); + $this->assertSame(DiffArray::diffAssocRecursive($this->array1, $this->array2), $expected); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/AutocompleteTagsUnitTest.php b/core/tests/Drupal/Tests/Core/Common/TagsTest.php similarity index 60% rename from core/modules/system/lib/Drupal/system/Tests/Common/AutocompleteTagsUnitTest.php rename to core/tests/Drupal/Tests/Core/Common/TagsTest.php index 8240536..7106d73 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/AutocompleteTagsUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Common/TagsTest.php @@ -2,18 +2,20 @@ /** * @file - * Definition of Drupal\system\Tests\Common\AutocompleteTagsUnitTest. + * Contains \Drupal\Tests\Core\Common\TagsTest. */ -namespace Drupal\system\Tests\Common; +namespace Drupal\Tests\Core\Common; -use Drupal\simpletest\UnitTestBase; +use Drupal\Component\Utility\Tags; +use Drupal\Tests\UnitTestCase; /** - * Tests drupal_explode_tags() and drupal_implode_tags(). + * Tests Tags::explodeTags and Tags::implodeTags(). */ -class AutocompleteTagsUnitTest extends UnitTestBase { - var $validTags = array( +class TagsTest extends UnitTestCase { + + protected $validTags = array( 'Drupal' => 'Drupal', 'Drupal with some spaces' => 'Drupal with some spaces', '"Legendary Drupal mascot of doom: ""Druplicon"""' => 'Legendary Drupal mascot of doom: "Druplicon"', @@ -31,21 +33,21 @@ public static function getInfo() { /** * Explodes a series of tags. */ - function testDrupalExplodeTags() { + public function explodeTags() { $string = implode(', ', array_keys($this->validTags)); - $tags = drupal_explode_tags($string); + $tags = Tags::explode($string); $this->assertTags($tags); } /** * Implodes a series of tags. */ - function testDrupalImplodeTags() { + public function testImplodeTags() { $tags = array_values($this->validTags); // Let's explode and implode to our heart's content. for ($i = 0; $i < 10; $i++) { - $string = drupal_implode_tags($tags); - $tags = drupal_explode_tags($string); + $string = Tags::implode($tags); + $tags = Tags::explode($string); } $this->assertTags($tags); } @@ -53,15 +55,16 @@ function testDrupalImplodeTags() { /** * Helper function: asserts that the ending array of tags is what we wanted. */ - function assertTags($tags) { + protected function assertTags($tags) { $original = $this->validTags; foreach ($tags as $tag) { $key = array_search($tag, $original); - $this->assertTrue($key, format_string('Make sure tag %tag shows up in the final tags array (originally %original)', array('%tag' => $tag, '%original' => $key))); + $this->assertTrue((bool) $key, $tag, sprintf('Make sure tag %s shows up in the final tags array (originally %s)', $tag, $key)); unset($original[$key]); } foreach ($original as $leftover) { - $this->fail(format_string('Leftover tag %leftover was left over.', array('%leftover' => $leftover))); + $this->fail(sprintf('Leftover tag %s was left over.', $leftover)); } } + } diff --git a/core/tests/Drupal/Tests/Core/Common/UrlValidatorTest.php b/core/tests/Drupal/Tests/Core/Common/UrlValidatorTest.php new file mode 100644 index 0000000..a6329f7 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Common/UrlValidatorTest.php @@ -0,0 +1,174 @@ + 'URL validation', + 'description' => 'Tests URL validation by valid_url()', + 'group' => 'Common', + ); + } + + /** + * Data provider for absolute URLs. + */ + public function providerValidAbsolute() { + $urls = array( + 'example.com', + 'www.example.com', + 'ex-ample.com', + '3xampl3.com', + 'example.com/parenthesis', + 'example.com/index.html#pagetop', + 'example.com:8080', + 'subdomain.example.com', + 'example.com/index.php/node', + 'example.com/index.php/node?param=false', + 'user@www.example.com', + 'user:pass@www.example.com:8080/login.php?do=login&style=%23#pagetop', + '127.0.0.1', + 'example.org?', + 'john%20doe:secret:foo@example.org/', + 'example.org/~,$\'*;', + 'caf%C3%A9.example.org', + '[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html', + ); + + return $this->dataEnhanceWithScheme($urls); + } + + /** + * Tests valid absolute URLs. + * + * @param string $url + * The url to test. + * @param string $scheme + * The scheme to test. + * + * @dataProvider providerValidAbsolute + */ + public function testValidAbsolute($url, $scheme) { + $test_url = $scheme . '://' . $url; + $valid_url = UrlValidator::isValid($test_url, TRUE); + $this->assertTrue($valid_url, String::format('@url is a valid URL.', array('@url' => $test_url))); + } + + /** + * Provides invalid absolute URLs. + */ + public function providerInvalidAbsolute() { + $data = array( + '', + 'ex!ample.com', + 'ex%ample.com', + ); + return $this->dataEnhanceWithScheme($data); + } + + /** + * Tests invalid absolute URLs. + * + * @param string $url + * The url to test. + * @param string $scheme + * The scheme to test. + * + * @dataProvider providerInvalidAbsolute + */ + public function testInvalidAbsolute($url, $scheme) { + $test_url = $scheme . '://' . $url; + $valid_url = UrlValidator::isValid($test_url, TRUE); + $this->assertFalse($valid_url, String::format('@url is NOT a valid URL.', array('@url' => $test_url))); + } + + /** + * Provides valid relative URLs + */ + public function providerValidRelative() { + return array( + array('paren(the)sis'), + array('index.html#pagetop'), + array('index.php/node'), + array('index.php/node?param=false'), + array('login.php?do=login&style=%23#pagetop'), + ); + } + + /** + * Tests valid relative URLs. + * + * @param string $url + * The url to test. + * + * @dataProvider providerValidRelative + */ + public function testValidRelative($url) { + foreach (array('', '/') as $front) { + $test_url = $front . $url; + $valid_url = Urlvalidator::isValid($test_url); + $this->assertTrue($valid_url, String::format('@url is a valid URL.', array('@url' => $test_url))); + } + } + + /** + * Provides invalid relative URLs. + */ + public function providerInvalidRelative() { + return array( + array('ex^mple'), + array('example<>'), + array('ex%ample'), + ); + } + + /** + * Tests invalid relative URLs. + * + * @param string $url + * The url to test. + * + * @dataProvider providerInvalidRelative + */ + public function testInvalidRelative($url) { + foreach (array('', '/') as $front) { + $test_url = $front . $url; + $valid_url = UrlValidator::isValid($test_url); + $this->assertFALSE($valid_url, String::format('@url is NOT a valid URL.', array('@url' => $test_url))); + } + } + + /** + * Enhancers test urls with schemes + * + * @param array $urls + * The list of urls. + * + * @return array + * A list of provider data with schemes. + */ + public function dataEnhanceWithScheme($urls) { + $url_schemes = array('http', 'https', 'ftp'); + foreach ($url_schemes as $scheme) { + foreach ($urls as $url) { + $data[] = array($url, $scheme); + } + } + return $data; + } + +}