diff --git a/framework/console/Application.php b/framework/console/Application.php index e185cc5..2f28cac 100644 --- a/framework/console/Application.php +++ b/framework/console/Application.php @@ -129,7 +129,7 @@ class Application extends \yii\base\Application 'migrate' => 'yii\console\controllers\MigrateController', 'app' => 'yii\console\controllers\AppController', 'cache' => 'yii\console\controllers\CacheController', - 'script' => 'yii\console\controllers\ScriptController', + 'asset' => 'yii\console\controllers\AssetController', ); } diff --git a/framework/console/controllers/ScriptController.php b/framework/console/controllers/AssetController.php similarity index 67% rename from framework/console/controllers/ScriptController.php rename to framework/console/controllers/AssetController.php index ab57f92..71a2cae 100644 --- a/framework/console/controllers/ScriptController.php +++ b/framework/console/controllers/AssetController.php @@ -15,7 +15,7 @@ use yii\console\Controller; * @author Qiang Xue * @since 2.0 */ -class ScriptController extends Controller +class AssetController extends Controller { public $defaultAction = 'compress'; @@ -33,13 +33,15 @@ class ScriptController extends Controller */ public $targets = array(); public $assetManager = array(); + public $jsCompressor = 'java -jar compiler.jar --js {from} --js_output_file {to}'; + public $cssCompressor = 'java -jar yuicompressor.jar {from} -o {to}'; public function actionCompress($configFile, $bundleFile) { $this->loadConfiguration($configFile); $bundles = $this->loadBundles($this->bundles, $this->extensions); $targets = $this->loadTargets($this->targets, $bundles); -// $this->publishBundles($bundles, $this->publishOptions); + $this->publishBundles($bundles, $this->publishOptions); $timestamp = time(); foreach ($targets as $target) { if (!empty($target->js)) { @@ -96,11 +98,38 @@ class ScriptController extends Controller protected function loadTargets($targets, $bundles) { + // build the dependency order of bundles $registered = array(); foreach ($bundles as $name => $bundle) { $this->registerBundle($bundles, $name, $registered); } $bundleOrders = array_combine(array_keys($registered), range(0, count($bundles) - 1)); + + // fill up the target which has empty 'depends'. + $referenced = array(); + foreach ($targets as $name => $target) { + if (empty($target['depends'])) { + if (!isset($all)) { + $all = $name; + } else { + throw new Exception("Only one target can have empty 'depends' option. Found two now: $all, $name"); + } + } else { + foreach ($target['depends'] as $bundle) { + if (!isset($referenced[$bundle])) { + $referenced[$bundle] = $name; + } else { + throw new Exception("Target '{$referenced[$bundle]}' and '$name' cannot contain the bundle '$bundle' at the same time."); + } + } + } + } + if (isset($all)) { + $targets[$all]['depends'] = array_diff(array_keys($registered), array_keys($referenced)); + } + + // adjust the 'depends' order for each target according to the dependency order of bundles + // create an AssetBundle object for each target foreach ($targets as $name => $target) { if (!isset($target['basePath'])) { throw new Exception("Please specify 'basePath' for the '$name' target."); @@ -172,11 +201,7 @@ class ScriptController extends Controller $map = array(); foreach ($targets as $name => $target) { foreach ($target->depends as $bundle) { - if (!isset($map[$bundle])) { - $map[$bundle] = $name; - } else { - throw new Exception("Bundle '$bundle' is found in both target '{$map[$bundle]}' and '$name'."); - } + $map[$bundle] = $name; } } @@ -236,7 +261,8 @@ class ScriptController extends Controller file_put_contents($bundleFile, <<jsCompressor)) { + $tmpFile = $outputFile . '.tmp'; + $this->combineJsFiles($inputFiles, $tmpFile); + $log = shell_exec(strtr($this->jsCompressor, array( + '{from}' => $tmpFile, + '{to}' => $outputFile, + ))); + @unlink($tmpFile); + } else { + $log = call_user_func($this->jsCompressor, $this, $inputFiles, $outputFile); + } } protected function compressCssFiles($inputFiles, $outputFile) { + if (is_string($this->cssCompressor)) { + $tmpFile = $outputFile . '.tmp'; + $this->combineCssFiles($inputFiles, $tmpFile); + $log = shell_exec(strtr($this->cssCompressor, array( + '{from}' => $inputFiles, + '{to}' => $outputFile, + ))); + } else { + $log = call_user_func($this->cssCompressor, $this, $inputFiles, $outputFile); + } + } + + public function combineJsFiles($files, $tmpFile) + { + $content = ''; + foreach ($files as $file) { + $content .= "/*** BEGIN FILE: $file ***/\n" + . file_get_contents($file) + . "/*** END FILE: $file ***/\n"; + } + file_put_contents($tmpFile, $content); + } + + public function combineCssFiles($files, $tmpFile) + { + // todo: adjust url() references in CSS files + $content = ''; + foreach ($files as $file) { + $content .= "/*** BEGIN FILE: $file ***/\n" + . file_get_contents($file) + . "/*** END FILE: $file ***/\n"; + } + file_put_contents($tmpFile, $content); + } + + public function actionTemplate($configFile) + { + $template = << require('path/to/bundles.php'), + // + 'extensions' => require('path/to/namespaces.php'), + // + 'targets' => array( + 'all' => array( + 'basePath' => __DIR__, + 'baseUrl' => '/test', + 'js' => 'all-{ts}.js', + 'css' => 'all-{ts}.css', + ), + ), + 'assetManager' => array( + 'basePath' => __DIR__, + 'baseUrl' => '/test', + ), +); +EOD; + file_put_contents($configFile, $template); } } \ No newline at end of file