Commit 94f702fe by Klimov Paul

`yii\console\controllers\AssetController` now handles bundle files from external resources properly

parent 95c7a6fe
...@@ -12,6 +12,7 @@ Yii Framework 2 Change Log ...@@ -12,6 +12,7 @@ Yii Framework 2 Change Log
- Bug #6691: Fixed console help description parsing with UTF8 characters (cebe) - Bug #6691: Fixed console help description parsing with UTF8 characters (cebe)
- Bug #6717: Fixed issue with UrlManager not matching a route on url creation when it was prefixed with `/` and pattern was empty (cebe) - Bug #6717: Fixed issue with UrlManager not matching a route on url creation when it was prefixed with `/` and pattern was empty (cebe)
- Enh #4502: Added alias support to URL route when calling `Url::toRoute()` and `Url::to()` (qiangxue, lynicidn) - Enh #4502: Added alias support to URL route when calling `Url::toRoute()` and `Url::to()` (qiangxue, lynicidn)
- Enh #5194: `yii\console\controllers\AssetController` now handles bundle files from external resources properly (klimov-paul)
- Enh #6247: Logger and error handler are now using slightly less memory (stepanselyuk, samdark) - Enh #6247: Logger and error handler are now using slightly less memory (stepanselyuk, samdark)
- Enh #6398: Added support for specifying dependent component in terms of a configuration array for classes such as `DbCache` (qiangxue) - Enh #6398: Added support for specifying dependent component in terms of a configuration array for classes such as `DbCache` (qiangxue)
- Enh #6434: Added `yii\behaviors\SluggableBehavior::immutable` to support keeping the generated slug unchanged (trntv) - Enh #6434: Added `yii\behaviors\SluggableBehavior::immutable` to support keeping the generated slug unchanged (trntv)
......
...@@ -12,6 +12,7 @@ use yii\console\Exception; ...@@ -12,6 +12,7 @@ use yii\console\Exception;
use yii\console\Controller; use yii\console\Controller;
use yii\helpers\Console; use yii\helpers\Console;
use yii\helpers\VarDumper; use yii\helpers\VarDumper;
use yii\web\AssetBundle;
/** /**
* Allows you to combine and compress your JavaScript and CSS files. * Allows you to combine and compress your JavaScript and CSS files.
...@@ -298,9 +299,11 @@ class AssetController extends Controller ...@@ -298,9 +299,11 @@ class AssetController extends Controller
foreach ($target->depends as $name) { foreach ($target->depends as $name) {
if (isset($bundles[$name])) { if (isset($bundles[$name])) {
if (!$this->isBundleExternal($bundles[$name])) {
foreach ($bundles[$name]->$type as $file) { foreach ($bundles[$name]->$type as $file) {
$inputFiles[] = $bundles[$name]->basePath . '/' . $file; $inputFiles[] = $bundles[$name]->basePath . '/' . $file;
} }
}
} else { } else {
throw new Exception("Unknown bundle: '{$name}'"); throw new Exception("Unknown bundle: '{$name}'");
} }
...@@ -352,9 +355,14 @@ class AssetController extends Controller ...@@ -352,9 +355,14 @@ class AssetController extends Controller
} }
foreach ($map as $bundle => $target) { foreach ($map as $bundle => $target) {
$sourceBundle = $bundles[$bundle];
$depends = $sourceBundle->depends;
if (!$this->isBundleExternal($sourceBundle)) {
$depends[] = $target;
}
$targets[$bundle] = Yii::createObject([ $targets[$bundle] = Yii::createObject([
'class' => strpos($bundle, '\\') !== false ? $bundle : 'yii\\web\\AssetBundle', 'class' => strpos($bundle, '\\') !== false ? $bundle : 'yii\\web\\AssetBundle',
'depends' => [$target], 'depends' => $depends,
]); ]);
} }
...@@ -402,6 +410,9 @@ class AssetController extends Controller ...@@ -402,6 +410,9 @@ class AssetController extends Controller
'css' => $target->css, 'css' => $target->css,
]; ];
} else { } else {
if ($this->isBundleExternal($target)) {
$array[$name] = $this->composeBundleConfig($target);
} else {
$array[$name] = [ $array[$name] = [
'sourcePath' => null, 'sourcePath' => null,
'js' => [], 'js' => [],
...@@ -410,6 +421,7 @@ class AssetController extends Controller ...@@ -410,6 +421,7 @@ class AssetController extends Controller
]; ];
} }
} }
}
$array = VarDumper::export($array); $array = VarDumper::export($array);
$version = date('Y-m-d H:i:s', time()); $version = date('Y-m-d H:i:s', time());
$bundleFileContent = <<<EOD $bundleFileContent = <<<EOD
...@@ -683,4 +695,24 @@ EOD; ...@@ -683,4 +695,24 @@ EOD;
} }
return implode(DIRECTORY_SEPARATOR, $realPathParts); return implode(DIRECTORY_SEPARATOR, $realPathParts);
} }
/**
* @param AssetBundle $bundle
* @return boolean whether asset bundle external or not.
*/
private function isBundleExternal($bundle)
{
return (empty($bundle->sourcePath) && empty($bundle->basePath));
}
/**
* @param AssetBundle $bundle asset bundle instance.
* @return array bundle configuration.
*/
private function composeBundleConfig($bundle)
{
$config = Yii::getObjectVars($bundle);
$config['class'] = get_class($bundle);
return $config;
}
} }
...@@ -95,7 +95,9 @@ class AssetControllerTest extends TestCase ...@@ -95,7 +95,9 @@ class AssetControllerTest extends TestCase
*/ */
protected function createCompressConfig(array $bundles) protected function createCompressConfig(array $bundles)
{ {
$className = $this->declareAssetBundleClass(['class' => 'AssetBundleAll']); static $classNumber = 0;
$classNumber++;
$className = $this->declareAssetBundleClass(['class' => 'AssetBundleAll' . $classNumber]);
$baseUrl = '/test'; $baseUrl = '/test';
$config = [ $config = [
'bundles' => $bundles, 'bundles' => $bundles,
...@@ -301,6 +303,73 @@ EOL; ...@@ -301,6 +303,73 @@ EOL;
} }
/** /**
* @depends testActionCompress
*
* @see https://github.com/yiisoft/yii2/issues/5194
*/
public function testCompressExternalAsset()
{
// Given :
$externalAssetConfig = [
'class' => 'ExternalAsset',
'sourcePath' => null,
'basePath' => null,
'js' => [
'//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js',
],
'css' => [
'//ajax.googleapis.com/css/libs/jquery/2.1.1/jquery.ui.min.css'
],
];
$externalAssetBundleClassName = $this->declareAssetBundleClass($externalAssetConfig);
$cssFiles = [
'css/test.css' => 'body {
padding-top: 20px;
padding-bottom: 60px;
}',
];
$this->createAssetSourceFiles($cssFiles);
$jsFiles = [
'js/test.js' => "function test() {
alert('Test message');
}",
];
$this->createAssetSourceFiles($jsFiles);
$regularAssetBundleClassName = $this->declareAssetBundleClass([
'class' => 'RegularAsset',
'css' => array_keys($cssFiles),
'js' => array_keys($jsFiles),
'depends' => [
$externalAssetBundleClassName
],
]);
$bundles = [
$regularAssetBundleClassName
];
$bundleFile = $this->testFilePath . DIRECTORY_SEPARATOR . 'bundle.php';
$configFile = $this->testFilePath . DIRECTORY_SEPARATOR . 'config.php';
$this->createCompressConfigFile($configFile, $bundles);
// When :
$this->runAssetControllerAction('compress', [$configFile, $bundleFile]);
// Then :
$this->assertTrue(file_exists($bundleFile), 'Unable to create output bundle file!');
$compressedBundleConfig = require($bundleFile);
$this->assertTrue(is_array($compressedBundleConfig), 'Output bundle file has incorrect format!');
$this->assertArrayHasKey($externalAssetBundleClassName, $compressedBundleConfig, 'External bundle is lost!');
$compressedExternalAssetConfig = $compressedBundleConfig[$externalAssetBundleClassName];
$this->assertEquals($externalAssetConfig['js'], $compressedExternalAssetConfig['js'], 'External bundle js is lost!');
$this->assertEquals($externalAssetConfig['css'], $compressedExternalAssetConfig['css'], 'External bundle css is lost!');
$compressedRegularAssetConfig = $compressedBundleConfig[$regularAssetBundleClassName];
$this->assertContains($externalAssetBundleClassName, $compressedRegularAssetConfig['depends'], 'Dependency on external bundle is lost!');
}
/**
* Data provider for [[testAdjustCssUrl()]]. * Data provider for [[testAdjustCssUrl()]].
* @return array test data. * @return array test data.
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment