1. <?php
  2. use Illuminate\Console\Command;
  3. use Symfony\Component\Console\Input\InputArgument;
  4. use Symfony\Component\Console\Input\InputOption;
  5. use Assetic\Asset\AssetCollection;
  6. use Assetic\Asset\FileAsset;
  7. use Minifier\MinFilter;
  8. class AssetsWatchCommand extends Command
  9. {
  10.    
  11.     /**
  12.      * The console command name.
  13.      *
  14.      * @var string
  15.      */
  16.     protected $name = 'assets:watch';
  17.  
  18.     /**
  19.      * The console command description.
  20.      *
  21.      * @var string
  22.      */
  23.     protected $description = 'Watch and compile resource files.';
  24.  
  25.     /**
  26.      * Execute the console command.
  27.      *
  28.      * @return void
  29.      */
  30.     public function fire()
  31.     {
  32.         $minify = $this->option('minify');
  33.         //normally you should never target a specific environment, however it's entirely possible to access this same code branch by specifying minify on your vm or dev.
  34.         if (App::environment() == 'production')
  35.         {
  36.             $minify = true;
  37.         }
  38.         $sections = Config::get('assets');
  39.         $listeners = array();
  40.  
  41.         foreach ($sections as $section => $assets)
  42.         {
  43.             foreach ($assets as $output => $input)
  44.             {
  45.                 if (!is_string($output))
  46.                 {
  47.                     continue;
  48.                 }
  49.  
  50.                 if (!is_array($input))
  51.                 {
  52.                     $input = array($input);
  53.                 }
  54.  
  55.                 foreach ($input as $file)
  56.                 {
  57.                     $listeners[public_path().'/assets/'.$file][] = function() use ($output, $input, $file, $minify)
  58.                     {
  59.                         $filters = array();
  60.                         if ($minify)
  61.                         {
  62.                             if (ends_with($output, '.js'))
  63.                             {
  64.                                 $filters[] = new MinFilter('js');
  65.                             }
  66.                             if (ends_with($output, '.css'))
  67.                             {
  68.                                 $filters[] = new MinFilter('css');
  69.                             }
  70.                         }
  71.  
  72.                         $collection = new AssetCollection(array(), $filters);
  73.                         foreach ($input as $asset)
  74.                         {
  75.                             $collection->add(new FileAsset(public_path().'/assets/'.$asset));
  76.                         }
  77.                         $this->info('Detected change in '.$file.' compiling '.$output);
  78.                         File::put(public_path().'/assets/'.$output, $collection->dump());
  79.                        
  80.                     };
  81.                 }
  82.             }
  83.         }
  84.         $watching = true;
  85.         $stats = array();
  86.         $listeners[app_path().'/config/asset.php'][] = function() use (&$watching)
  87.         {
  88.             $watching = false;
  89.             $this->info('Detected config change, exiting');
  90.         };
  91.         while ($watching)
  92.         {
  93.             foreach ($listeners as $file => $callbacks)
  94.             {
  95.                 if (empty($stats[$file]))
  96.                 {
  97.                     $stats[$file] = md5(file_get_contents($file));
  98.                 }
  99.                 else
  100.                 {
  101.                     $md5 = md5(file_get_contents($file));
  102.                     if ($stats[$file] !== $md5)
  103.                     {
  104.                         $stats[$file] = $md5;
  105.                         foreach ($callbacks as $callback)
  106.                         {
  107.                             $callback();
  108.                         }
  109.                     }
  110.                 }
  111.             }
  112.             usleep(500000);
  113.         }
  114.     }
  115.  
  116.  
  117.     protected function getOptions()
  118.     {
  119.         return array(
  120.             array('minify', 'm', InputOption::VALUE_NONE, 'Minify, defaults on in production.', null)
  121.         );
  122.     }
  123. }