Yii2: AssetManager appendTimestamp not working

Created on 30 Nov 2020  ·  7Comments  ·  Source: yiisoft/yii2

What steps will reproduce the problem?

asset-config:

'app\assets\BootstrapAsset' => [
    'basePath' => '@webroot',
    'baseUrl' => '@web',
    'css' => ['css/site.min.css'],
],

web.php

'components' => [
...
    'assetManager' => [
        'appendTimestamp' => true,
        'bundles' => require(__DIR__ . '/asset-bundles.php'),
    ],

What is the expected result?

the site.min.css with the query parameter v=time()
<link href="/my-project/web/css/site.min.css?v=123" rel="stylesheet">

What do you get instead?

no timestamp:

<link href="/my-project/web/css/site.min.css" rel="stylesheet">

Additional info

this happens because of Line 495 in View.php (https://github.com/yiisoft/yii2/blob/master/framework/web/View.php#L495) it adds @webroot to the url. But the Url comes from the AssetManager (newly introduced getActualAssetUrl method (https://github.com/yiisoft/yii2/blob/c46d209b56fda9aca05a9cc7fc858ce2fe25477d/framework/web/AssetManager.php#L643))
which already includes the @webroot (or other baseUrl) in the url.

The error occours now because the AssetBundle calls this new Method which is the url without the timestamp. In earlier versions the timestamp was alredy included in the $url and no errors occoured.

Possible fixes:

  • Either call the old getAssetUrl method in the AssetBundle
  • Or do not append @webroot in front of the url.

Btw: is there a unit test checking the appendTimestamp behavior?

| Q | A
| ---------------- | ---
| Yii version | 2.0.39
| PHP version | 7.4
| Operating system | Windows / Linux, happens on both

ready for adoption bug

Most helpful comment

Added a pullrequest, maybe you can have a look at it?
It works for me with sites hosted on the root-url (localhost) and sites hosted in subfolders (for example localhost/my-site/something-deep

All 7 comments

Might be what was already reported in https://github.com/yiisoft/yii2/issues/18402

yes but my issue contains the actual error to reproduce.

Я с английским не дружу, но надеюсь, что разработчики поймут. Я столкнулся с аналогичной проблемой: в версии Yii Basic 2.0.38 всё работает, с версии Yii Basic 2.0.39 перестает. PHP 7.3.

Настройки сайта, да и вообще код не меняется, т.е. делаю даунгрейд до 2.0.38 - работает, следом делаю апгрейд до 2.0.39.3 - перестает работать.

В попытках найти проблему я наткнулся на очень интересную вещь: у меня проблема проявляется только тогда, когда сайт лежит в подпапке, т.е. в config/web.php не пустой baseUrl:

'components' => [
    'request' => [
        'baseUrl' => '/subdomain/site',
        ...

Магия происходит в файле yiisoft\yii2\web\View.php в функции registerFile() в этой части кода (строки 495-497):

if ($appendTimestamp && Url::isRelative($url) && ($timestamp = @filemtime(Yii::getAlias('@webroot/' . ltrim($url, '/'), false))) > 0) {
    $url = $timestamp ? "$url?v=$timestamp" : $url;
}

В случае с подпапкой эта часть Yii::getAlias('@webroot/' . ltrim($url, '/'), false) возвращает путь в таком виде:
G:/XAMPP7/htdocs/subdomain/site/web/subdomain/site/css/custom.css

Т.е. baseUrl прописывается дважды: в @webroot и отдельно в относительном пути к файлу.


_I decided to translate it additionally through a translator._

I ran into a similar problem: in Yii Basic version 2.0.38 everything works, from Yii Basic version 2.0.39 it stops. PHP 7.3.

Site settings, and indeed the code does not change, i.e. I downgrade to 2.0.38 - it works, then I upgrade to 2.0.39.3 - it stops working.

While trying to find the problem, I came across a very interesting thing: my problem appears only when the site is in a subfolder, i.e. in config/web.php not empty baseUrl:

'components' => [
    'request' => [
        'baseUrl' => '/subdomain/site',
        ...

The magic happens in the file yiisoft\yii2\web\View.php in the registerFile() function in this part of the code (lines 495-497):

if ($appendTimestamp && Url::isRelative($url) && ($timestamp = @filemtime(Yii::getAlias('@webroot/' . ltrim($url, '/'), false))) > 0) {
    $url = $timestamp ? "$url?v=$timestamp" : $url;
}

In the case of a subfolder, this part Yii::getAlias('@webroot/' . ltrim($url, '/'), false) returns the path like this:
G:/XAMPP7/htdocs/subdomain/site/web/subdomain/site/css/custom.css

Those baseUrl is written twice: in @webroot and separately in the relative path to the file.

Спасибо за дополнительную информацию. Наверняка в ближайшее время это исправят :smile:

Спасибо за дополнительную информацию. Наверняка в ближайшее время это исправят 😄

Будем надеяться, что нам остаётся :)

Будем надеяться, что нам остаётся :)

Исправить и сделать pull request.

Added a pullrequest, maybe you can have a look at it?
It works for me with sites hosted on the root-url (localhost) and sites hosted in subfolders (for example localhost/my-site/something-deep

Was this page helpful?
0 / 5 - 0 ratings