Browse Source

Updated asUrl method to not introduce BC break (#18742)

tags/2.0.43
Bizley 3 years ago committed by GitHub
parent
commit
9d56179e9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      framework/CHANGELOG.md
  2. 6
      framework/helpers/BaseUrl.php
  3. 29
      framework/i18n/Formatter.php
  4. 84
      tests/framework/i18n/FormatterTest.php

2
framework/CHANGELOG.md

@ -12,8 +12,8 @@ Yii Framework 2 Change Log
- Enh #18676: Added method `yii\helpers\BaseFileHelper::changeOwnership()` and properties `newFileMode`/`newFileOwnership` in `yii\console\controllers\BaseMigrateController` (rhertogh)
- Bug #18678: Fix `yii\caching\DbCache` to use configured cache table name instead of the default one in case of MSSQL varbinary column type detection (aidanbek)
- Enh #18695: Added `yii\web\Cookie::SAME_SITE_NONE` constant (rhertogh)
- Enh #18712: Added `scheme` option for `$options` argument for `yii\i18n\Formatter::asUrl()` (bizley)
- Enh #18707: Changed the base error handler to not expose `$_SERVER` details unless `YII_DEBUG` is enabled (coolgoose)
- Enh #18712: Added `$scheme` option to `yii\i18n\Formatter::asUrl()` (bizley)
- Bug #18648: Fix `yii\web\Request` to properly handle HTTP Basic Auth headers (olegbaturin)
- Enh #18726: Added `yii\helpers\Json::$prettyPrint` (rhertogh)

6
framework/helpers/BaseUrl.php

@ -232,12 +232,12 @@ class BaseUrl
}
/**
* Normalize URL by ensuring that it use specified scheme.
* Normalize the URL by ensuring it uses specified scheme.
*
* If URL is relative or scheme is not string, normalization is skipped.
* If the URL is relative or the scheme is not a string, normalization is skipped.
*
* @param string $url the URL to process
* @param string $scheme the URI scheme used in URL (e.g. `http` or `https`). Use empty string to
* @param string $scheme the URI scheme used in the URL (e.g. `http` or `https`). Use an empty string to
* create protocol-relative URL (e.g. `//example.com/path`)
* @return string the processed URL
* @since 2.0.11

29
framework/i18n/Formatter.php

@ -18,9 +18,11 @@ use Yii;
use yii\base\Component;
use yii\base\InvalidArgumentException;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use yii\helpers\FormatConverter;
use yii\helpers\Html;
use yii\helpers\HtmlPurifier;
use yii\helpers\Url;
/**
* Formatter provides a set of commonly used data formatting methods.
@ -576,31 +578,26 @@ class Formatter extends Component
/**
* Formats the value as a hyperlink.
* @param mixed $value the value to be formatted.
* @param array $options the tag options in terms of name-value pairs. See [[Html::a()]].
* @param bool|string $scheme the URI scheme to use in the formatted hyperlink (available since 2.0.43):
*
* - `false (default)`: adding non-secure protocol scheme if there is none added already
* - `true`: adding secure protocol scheme if there is none added already
* - string: adding the specified scheme (either `http`, `https` or empty string
* for protocol-relative URL) if there is none added already
*
* @param array $options the tag options in terms of name-value pairs. See [[Html::a()]]. Since 2.0.43 there is
* a special option available `scheme` - if set it won't be passed to [[Html::a()]] but it will control the URL
* protocol part of the link by normalizing URL and ensuring that it uses specified scheme. See [[Url::ensureScheme()]].
* If `scheme` is not set the original behavior is preserved which is to add "http://" prefix when "://" string is
* not found in the $value.
* @return string the formatted result.
*/
public function asUrl($value, $options = [], $scheme = false)
public function asUrl($value, $options = [])
{
if ($value === null) {
return $this->nullDisplay;
}
$url = $value;
if (strpos($url, '://') === false) {
if ($scheme === false || $scheme === 'http') {
$scheme = ArrayHelper::remove($options, 'scheme');
if ($scheme === null) {
if (strpos($url, '://') === false) {
$url = 'http://' . $url;
} elseif ($scheme === true || $scheme === 'https') {
$url = 'https://' . $url;
} elseif ($scheme === '') {
$url = '//' . $url;
}
} else {
$url = Url::ensureScheme($url, $scheme);
}
return Html::a(Html::encode($value), $url, $options);

84
tests/framework/i18n/FormatterTest.php

@ -216,27 +216,79 @@ class FormatterTest extends TestCase
{
$value = 'http://www.yiiframework.com/';
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, [], false));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, [], true));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, [], 'http'));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, [], 'https'));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, [], ''));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => null]));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => false]));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => 'http']));
$this->assertSame(
"<a href=\"https://www.yiiframework.com/\">$value</a>",
$this->formatter->asUrl($value, ['scheme' => 'https'])
);
$this->assertSame(
"<a href=\"//www.yiiframework.com/\">$value</a>",
$this->formatter->asUrl($value, ['scheme' => ''])
);
$value = 'https://www.yiiframework.com/';
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, [], false));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, [], true));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, [], 'http'));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, [], 'https'));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, [], ''));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => false]));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => null]));
$this->assertSame(
"<a href=\"http://www.yiiframework.com/\">$value</a>",
$this->formatter->asUrl($value, ['scheme' => 'http'])
);
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => 'https']));
$this->assertSame(
"<a href=\"//www.yiiframework.com/\">$value</a>",
$this->formatter->asUrl($value, ['scheme' => ''])
);
$value = 'www.yiiframework.com/';
$this->assertSame("<a href=\"http://$value\">$value</a>", $this->formatter->asUrl($value));
$this->assertSame("<a href=\"http://$value\">$value</a>", $this->formatter->asUrl($value, [], false));
$this->assertSame("<a href=\"https://$value\">$value</a>", $this->formatter->asUrl($value, [], true));
$this->assertSame("<a href=\"http://$value\">$value</a>", $this->formatter->asUrl($value, [], 'http'));
$this->assertSame("<a href=\"https://$value\">$value</a>", $this->formatter->asUrl($value, [], 'https'));
$this->assertSame("<a href=\"//$value\">$value</a>", $this->formatter->asUrl($value, [], ''));
$this->assertSame(
"<a href=\"http://www.yiiframework.com/\">$value</a>",
$this->formatter->asUrl($value)
);
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => false]));
$this->assertSame(
"<a href=\"http://www.yiiframework.com/\">$value</a>",
$this->formatter->asUrl($value, ['scheme' => null])
);
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => 'http']));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => 'https']));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => '']));
$value = '//www.yiiframework.com/';
$this->assertSame(
"<a href=\"http:////www.yiiframework.com/\">$value</a>", // invalid but this is how it works
$this->formatter->asUrl($value)
);
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => false]));
$this->assertSame(
"<a href=\"http:////www.yiiframework.com/\">$value</a>", // invalid but this is how it works
$this->formatter->asUrl($value, ['scheme' => null])
);
$this->assertSame(
"<a href=\"http://www.yiiframework.com/\">$value</a>",
$this->formatter->asUrl($value, ['scheme' => 'http'])
);
$this->assertSame(
"<a href=\"https://www.yiiframework.com/\">$value</a>",
$this->formatter->asUrl($value, ['scheme' => 'https'])
);
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => '']));
$value = '/books/about/yii';
$this->assertSame(
"<a href=\"http:///books/about/yii\">$value</a>", // invalid but this is how it works
$this->formatter->asUrl($value)
);
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => false]));
$this->assertSame(
"<a href=\"http:///books/about/yii\">$value</a>", // invalid but this is how it works
$this->formatter->asUrl($value, ['scheme' => null])
);
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => 'http']));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => 'https']));
$this->assertSame("<a href=\"$value\">$value</a>", $this->formatter->asUrl($value, ['scheme' => '']));
$value = 'https://www.yiiframework.com/?name=test&value=5"';
$this->assertSame(

Loading…
Cancel
Save