Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'feature/uri-normalize-filter' of https://github.com/she…

…vron/zf2 into feature/filter-uri-normalization
  • Loading branch information...
commit 6d08f08800dfe67638ac4ee13fca374f311720e4 2 parents d1291e0 + 09b5907
Matthew Weier O'Phinney weierophinney authored
1  library/Zend/Filter/FilterPluginManager.php
View
@@ -68,6 +68,7 @@ class FilterPluginManager extends AbstractPluginManager
'stringtrim' => 'Zend\Filter\StringTrim',
'stripnewlines' => 'Zend\Filter\StripNewlines',
'striptags' => 'Zend\Filter\StripTags',
+ 'urinormalize' => 'Zend\Filter\UriNormalize',
'wordcamelcasetodash' => 'Zend\Filter\Word\CamelCaseToDash',
'wordcamelcasetoseparator' => 'Zend\Filter\Word\CamelCaseToSeparator',
'wordcamelcasetounderscore' => 'Zend\Filter\Word\CamelCaseToUnderscore',
150 library/Zend/Filter/UriNormalize.php
View
@@ -0,0 +1,150 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Filter
+ */
+
+namespace Zend\Filter;
+
+use Zend\Filter\AbstractFilter;
+use Zend\Filter\Exception\InvalidArgumentException;
+use Zend\Uri\UriFactory;
+use Zend\Uri\Uri;
+use Zend\Uri\Exception\ExceptionInterface as UriException;
+
+/**
+ * @category Zend
+ * @package Zend_Filter
+ */
+class UriNormalize extends AbstractFilter
+{
+ /**
+ * The default scheme to use when parsing scheme-less URIs
+ *
+ * @var string
+ */
+ protected $defaultScheme = null;
+
+ /**
+ * Enforced scheme for scheme-less URIs. See setEnforcedScheme docs for info
+ *
+ * @var string
+ */
+ protected $enforcedScheme = null;
+
+ /**
+ * Sets filter options
+ *
+ * @param string|array|\Zend\Config\Config $options
+ * @return void
+ */
+ public function __construct($options = null)
+ {
+ if ($options) {
+ $this->setOptions($options);
+ }
+ }
+
+ /**
+ * Set the default scheme to use when parsing scheme-less URIs
+ *
+ * The scheme used when parsing URIs may affect the specific object used to
+ * normalize the URI and thus may affect the resulting normalize URI.
+ *
+ * @param string $defaultScheme
+ * @return \Zend\Filter\UriNormalize
+ */
+ public function setDefaultScheme($defaultScheme)
+ {
+ $this->defaultScheme = $defaultScheme;
+ return $this;
+ }
+
+ /**
+ * Set a URI scheme to enforce on schemeless URIs
+ *
+ * This allows forcing input values such as 'www.example.com/foo' into
+ * 'http://www.example.com/foo'.
+ *
+ * This should be used with caution, as a standard-compliant URI parser
+ * would regard 'www.example.com' in the above input URI to be the path and
+ * not host part of the URI. While this option can assist in solving
+ * real-world user mishaps, it may yield unexpected results at times.
+ *
+ * @param string $enforcedScheme
+ * @return \Zend\Filter\UriNormalize
+ */
+ public function setEnforcedScheme($enforcedScheme)
+ {
+ $this->enforcedScheme = $enforcedScheme;
+ return $this;
+ }
+
+ /**
+ * Filter the URL by normalizing it and applying a default scheme if set
+ *
+ * @param string $value
+ * @return string
+ */
+ public function filter($value)
+ {
+ $defaultScheme = $this->defaultScheme ?: $this->enforcedScheme;
+
+ // Reset default scheme if it is not a known scheme
+ if (!UriFactory::getRegisteredSchemeClass($defaultScheme)) {
+ $defaultScheme = null;
+ }
+
+ try {
+ $uri = UriFactory::factory($value, $defaultScheme);
+ if ($this->enforcedScheme && (!$uri->getScheme())) {
+ $this->enforceScheme($uri);
+ }
+
+ } catch (UriException $ex) {
+ // We are unable to parse / enfore scheme with the given config and input
+ return $value;
+ }
+
+ $uri->normalize();
+
+ if (!$uri->isValid()) {
+ return $value;
+ }
+
+ return $uri->toString();
+ }
+
+ /**
+ * Enforce the defined scheme on the URI
+ *
+ * This will also adjust the host and path parts of the URI as expected in
+ * the case of scheme-less network URIs
+ *
+ * @param Uri $uri
+ */
+ protected function enforceScheme(Uri $uri)
+ {
+ $path = $uri->getPath();
+ if (strpos($path, '/') !== false) {
+ list($host, $path) = explode('/', $path, 2);
+ $path = '/' . $path;
+ } else {
+ $host = $path;
+ $path = '';
+ }
+
+ // We have nothing to do if we have no host
+ if (!$host) {
+ return;
+ }
+
+ $uri->setScheme($this->enforcedScheme)
+ ->setHost($host)
+ ->setPath($path);
+ }
+}
17 library/Zend/Uri/UriFactory.php
View
@@ -67,6 +67,23 @@ public static function unregisterScheme($scheme)
}
/**
+ * Get the class name for a registered scheme
+ *
+ * If provided scheme is not registered, will return NULL
+ *
+ * @param string $scheme
+ * @return string|null
+ */
+ public static function getRegisteredSchemeClass($scheme)
+ {
+ if (isset(static::$schemeClasses[$scheme])) {
+ return static::$schemeClasses[$scheme];
+ } else {
+ return null;
+ }
+ }
+
+ /**
* Create a URI from a string
*
* @param string $uriString
70 tests/ZendTest/Filter/UriNormalizeTest.php
View
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend_Filter
+ */
+
+namespace ZendTest\Filter;
+
+use Zend\Filter\UriNormalize;
+
+/**
+ * @category Zend
+ * @package Zend_Filter
+ * @subpackage UnitTests
+ * @group Zend_Filter
+ */
+class UriNormalizeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider abnormalUriProvider
+ */
+ public function testUrisAreNormalized($url, $expected)
+ {
+ $filter = new UriNormalize();
+ $result = $filter->filter($url);
+ $this->assertEquals($expected, $result);
+ }
+
+ public function testDefaultSchemeAffectsNormalization()
+ {
+ $this->markTestIncomplete();
+ }
+
+ /**
+ * @dataProvider enforcedSchemeTestcaseProvider
+ */
+ public function testEnforcedScheme($scheme, $input, $expected)
+ {
+ $filter = new UriNormalize(array('enforcedScheme' => $scheme));
+ $result = $filter->filter($input);
+ $this->assertEquals($expected, $result);
+ }
+
+ public static function abnormalUriProvider()
+ {
+ return array(
+ array('http://www.example.com', 'http://www.example.com/'),
+ array('hTTp://www.example.com/ space', 'http://www.example.com/%20space'),
+ array('file:///www.example.com/foo/bar', 'file:///www.example.com/foo/bar'), // this should not be affected
+ array('file:///home/shahar/secret/../../otherguy/secret', 'file:///home/otherguy/secret'),
+ array('https://www.example.com:443/hasport', 'https://www.example.com/hasport'),
+ array('/foo/bar?q=%711', '/foo/bar?q=q1'), // no scheme enforced
+ );
+ }
+
+ public static function enforcedSchemeTestcaseProvider()
+ {
+ return array(
+ array('ftp', 'http://www.example.com', 'http://www.example.com/'), // no effect - this one has a scheme
+ array('mailto', 'mailto:shahar@example.com', 'mailto:shahar@example.com'),
+ array('http', 'www.example.com/foo/bar?q=q', 'http://www.example.com/foo/bar?q=q'),
+ array('ftp', 'www.example.com/path/to/file.ext', 'ftp://www.example.com/path/to/file.ext'),
+ array('http', '/just/a/path', '/just/a/path') // cannot be enforced, no host
+ );
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.