Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 163 lines (141 sloc) 5.615 kb
d2536b6 @kriswallsmith [AsseticBundle] initial entry of assetic integration
kriswallsmith authored
1 <?php
2
3 /*
4 * This file is part of the Symfony framework.
5 *
6 * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
7 *
8 * This source file is subject to the MIT license that is bundled
9 * with this source code in the file LICENSE.
10 */
11
12 namespace Symfony\Bundle\AsseticBundle\Command;
13
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
14 use Assetic\Asset\AssetInterface;
15 use Assetic\Factory\LazyAssetManager;
d2536b6 @kriswallsmith [AsseticBundle] initial entry of assetic integration
kriswallsmith authored
16 use Symfony\Bundle\FrameworkBundle\Command\Command;
17 use Symfony\Component\Console\Input\InputArgument;
18 use Symfony\Component\Console\Input\InputInterface;
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
19 use Symfony\Component\Console\Input\InputOption;
d2536b6 @kriswallsmith [AsseticBundle] initial entry of assetic integration
kriswallsmith authored
20 use Symfony\Component\Console\Output\OutputInterface;
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
21 use Symfony\Component\EventDispatcher\Event;
d2536b6 @kriswallsmith [AsseticBundle] initial entry of assetic integration
kriswallsmith authored
22
23 /**
24 * Dumps assets to the filesystem.
25 *
26 * @author Kris Wallsmith <kris.wallsmith@symfony-project.com>
27 */
28 class DumpCommand extends Command
29 {
30 protected function configure()
31 {
32 $this
33 ->setName('assetic:dump')
34 ->setDescription('Dumps all assets to the filesystem')
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
35 ->addArgument('write_to', InputArgument::OPTIONAL, 'Override the configured asset root')
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
36 ->addOption('watch', null, InputOption::VALUE_NONE, 'Check for changes every second')
d2536b6 @kriswallsmith [AsseticBundle] initial entry of assetic integration
kriswallsmith authored
37 ;
38 }
39
40 protected function execute(InputInterface $input, OutputInterface $output)
41 {
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
42 if (!$basePath = $input->getArgument('write_to')) {
43 $basePath = $this->container->getParameter('assetic.write_to');
d2536b6 @kriswallsmith [AsseticBundle] initial entry of assetic integration
kriswallsmith authored
44 }
45
46 $am = $this->container->get('assetic.asset_manager');
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
47
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
48 // notify an event so custom stream wrappers can be registered lazily
49 $this->container->get('event_dispatcher')->notify(new Event(null, 'assetic.write', array('path' => $basePath)));
50
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
51 if ($input->getOption('watch')) {
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
52 return $this->watch($am, $basePath, $output, $this->container->getParameter('kernel.debug'));
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
53 }
54
55 foreach ($am->getNames() as $name) {
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
56 $this->dumpAsset($am->get($name), $basePath, $output);
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
57 }
58 }
59
60 /**
61 * Watches a asset manager for changes.
62 *
63 * This method includes an infinite loop the continuously polls the asset
64 * manager for changes.
65 *
66 * @param LazyAssetManager $am The asset manager
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
67 * @param string $basePath The base directory to write to
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
68 * @param OutputInterface $output The command output
69 * @param Boolean $debug Debug mode
70 */
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
71 protected function watch(LazyAssetManager $am, $basePath, OutputInterface $output, $debug = false)
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
72 {
e2545c1 @kriswallsmith [AsseticBundle] added error handling to --watch
kriswallsmith authored
73 $refl = new \ReflectionClass('Assetic\\AssetManager');
74 $prop = $refl->getProperty('assets');
75 $prop->setAccessible(true);
76
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
77 $cache = sys_get_temp_dir().'/assetic_watch_'.substr(sha1($basePath), 0, 7);
7d62602 @kriswallsmith [AsseticBundle] added a simple cache to --watch so it picks up where it ...
kriswallsmith authored
78 if (file_exists($cache)) {
79 $previously = unserialize(file_get_contents($cache));
80 } else {
81 $previously = array();
82 }
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
83
e2545c1 @kriswallsmith [AsseticBundle] added error handling to --watch
kriswallsmith authored
84 $error = '';
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
85 while (true) {
e2545c1 @kriswallsmith [AsseticBundle] added error handling to --watch
kriswallsmith authored
86 try {
87 foreach ($am->getNames() as $name) {
88 if ($asset = $this->checkAsset($am, $name, $previously)) {
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
89 $this->dumpAsset($asset, $basePath, $output);
e2545c1 @kriswallsmith [AsseticBundle] added error handling to --watch
kriswallsmith authored
90 }
91 }
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
92
e2545c1 @kriswallsmith [AsseticBundle] added error handling to --watch
kriswallsmith authored
93 // reset the asset manager
94 $prop->setValue($am, array());
95 if ($debug) {
96 $am->load();
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
97 }
98
e2545c1 @kriswallsmith [AsseticBundle] added error handling to --watch
kriswallsmith authored
99 file_put_contents($cache, serialize($previously));
100 $error = '';
101
102 sleep(1);
103 } catch (\Exception $e) {
104 if ($error != $msg = $e->getMessage()) {
105 $output->writeln('<error>[error]</error> '.$msg);
106 $error = $msg;
107 }
108 }
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
109 }
110 }
111
112 /**
113 * Checks if an asset should be dumped.
114 *
115 * @param LazyAssetManager $am The asset manager
116 * @param string $name The asset name
117 * @param array $previously An array of previous visits
118 *
119 * @return AssetInterface|Boolean The asset if it should be dumped
120 */
121 protected function checkAsset(LazyAssetManager $am, $name, array &$previously)
122 {
e2545c1 @kriswallsmith [AsseticBundle] added error handling to --watch
kriswallsmith authored
123 $formula = $am->hasFormula($name) ? serialize($am->getFormula($name)) : null;
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
124 $asset = $am->get($name);
125 $mtime = $asset->getLastModified();
126
127 if (isset($previously[$name])) {
128 $changed = $previously[$name]['mtime'] != $mtime || $previously[$name]['formula'] != $formula;
129 } else {
130 $changed = true;
131 }
132
133 $previously[$name] = array('mtime' => $mtime, 'formula' => $formula);
134
135 return $changed ? $asset : false;
136 }
137
138 /**
139 * Writes an asset.
140 *
141 * @param AssetInterface $asset An asset
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
142 * @param string $basePath The base directory to write to
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
143 * @param OutputInterface $output The command output
144 *
145 * @throws RuntimeException If there is a problem writing the asset
146 */
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
147 protected function dumpAsset(AssetInterface $asset, $basePath, OutputInterface $output)
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
148 {
98b9606 @kriswallsmith [AsseticBundle] separated read and write paths to facilitate writing ass...
kriswallsmith authored
149 $target = rtrim($basePath, '/') . '/' . $asset->getTargetUrl();
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
150 if (!is_dir($dir = dirname($target))) {
151 $output->writeln('<info>[dir+]</info> '.$dir);
152 if (false === @mkdir($dir)) {
153 throw new \RuntimeException('Unable to create directory '.$dir);
d2536b6 @kriswallsmith [AsseticBundle] initial entry of assetic integration
kriswallsmith authored
154 }
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
155 }
d2536b6 @kriswallsmith [AsseticBundle] initial entry of assetic integration
kriswallsmith authored
156
49ddc95 @kriswallsmith [AsseticBundle] added a --watch option to the assetic:dump command
kriswallsmith authored
157 $output->writeln('<info>[file+]</info> '.$target);
158 if (false === @file_put_contents($target, $asset->dump())) {
159 throw new \RuntimeException('Unable to write file '.$target);
d2536b6 @kriswallsmith [AsseticBundle] initial entry of assetic integration
kriswallsmith authored
160 }
161 }
162 }
Something went wrong with that request. Please try again.