Example #1
0
 /**
  * Accepts:
  *  string - a filename (e.g. application.css), or
  *  File object
  *
  * Compiles, minifies and gz-compresses files. Also updates the
  * manifest index file.
  * Note that files with same name will be deleted.
  */
 public function compileFile($filename)
 {
     if (!$this->compilePath()) {
         throw new Exception\RuntimeException("Missing asset configuration 'compile_path'");
     } elseif (!$this->manifestFileName) {
         throw new Exception\RuntimeException(sprintf("Property %s::\$manifestFileName must not be empty", __CLASS__));
     }
     if (is_string($filename)) {
         $file = $this->findFile($filename);
         if (!$file) {
             throw new Exception\RuntimeException(sprintf("Asset file not found: %s", $filename));
         }
     } elseif ($filename instanceof File) {
         $file = $filename;
     } else {
         throw new Exception\InvalidArgumentException(sprintf("Argument must be string or Rails\\Assets\\File, %s passed", gettype($filename)));
     }
     $this->console("Compiling file " . $file->full_path());
     $basePath = $this->compilePath() . $this->prefix();
     $ext = $file->type();
     $relativeDir = $file->relative_dir();
     if ($relativeDir) {
         $relativeDir .= '/';
     }
     $fileroot = $basePath . '/' . $relativeDir . $file->file_root();
     $compiledFileDir = dirname($fileroot);
     if (!is_dir($compiledFileDir)) {
         try {
             mkdir($compiledFileDir, 0755, true);
         } catch (\Exception $e) {
             throw new Exception\RuntimeException(sprintf("Couldn't create dir %s: %s", $compiledFileDir, $e->getMessage()));
         }
     }
     set_time_limit(360);
     $parser = new Parser\Base($file);
     $parser->parse(Parser\Base::PARSE_TYPE_FULL);
     $fileContents = $parser->parsed_file();
     if ($this->config()->compress) {
         $fileContents = $this->compressFile($fileContents, $ext);
     }
     $compileFiles = [$fileroot . '.' . $ext];
     if ($this->config()->digest) {
         $md5 = md5($fileContents);
         $compileFiles[] = $fileroot . '-' . $md5 . '.' . $ext;
     }
     foreach ($compileFiles as $compileFile) {
         $this->createCompiledFile($compileFile, $fileContents);
     }
     $relativePath = $relativeDir . $file->file_root();
     if ($this->config()->digest) {
         # Delete previous md5 files
         $pattern = $fileroot . '-*.' . $ext . '*';
         if ($mfiles = glob($pattern)) {
             $regexp = '/-' . $md5 . '\\.' . $ext . '(\\.gz)?$/';
             foreach ($mfiles as $mfile) {
                 if (!preg_match($regexp, $mfile)) {
                     unlink($mfile);
                 }
             }
         }
         $this->updateManifestIndex($relativePath . '.' . $ext, $relativePath . '-' . $md5 . '.' . $ext);
     }
     return true;
 }
Example #2
0
 /**
  * Returns not only the URL for the file, but also the URLs
  * of the files it requires (if it's a manifest file).
  */
 public function getFileUrls($filename)
 {
     if ($file = $this->findFile($filename)) {
         $parser = new Rails\Assets\Parser\Base($file);
         $parser->parse(Rails\Assets\Parser\Base::PARSE_TYPE_GET_PATHS);
         $urls = [];
         foreach ($parser->urlPaths() as $url) {
             $urls[] = $url . '?body=1';
         }
         return $urls;
     }
     return false;
 }
Example #3
0
 public function serve_file($file_path)
 {
     $file = Rails::assets()->findFile($file_path);
     if (!$file) {
         $this->set_404_headers();
         return;
     }
     $ext = $file->type();
     $parser = null;
     switch ($ext) {
         case 'js':
             $parser = new Parser\Base($file);
             $this->set_javascript_headers();
             break;
         case 'css':
             $parser = new Parser\Base($file);
             $this->set_stylesheet_headers();
             break;
         case 'jpeg':
             $this->headers()->contentType('image/jpeg');
             break;
         case 'jpg':
             $this->headers()->contentType('image/jpeg');
             break;
         case 'png':
             $this->headers()->contentType('image/png');
             break;
         case 'gif':
             $this->headers()->contentType('image/gif');
             break;
         case 'svg':
             $this->headers()->contentType('image/svg+xml');
             break;
         case 'ttf':
             $this->headers()->contentType('application/x-font-ttf');
             break;
         case 'woff':
             $this->headers()->contentType('application/font-woff');
             break;
         default:
             $this->headers()->contentType('application/octet-stream');
             return;
     }
     if ($parser) {
         if ($this->params()->body) {
             $parseType = Parser\Base::PARSE_TYPE_NONE;
         } else {
             $parseType = Parser\Base::PARSE_TYPE_FULL;
         }
         $parser->parse($parseType);
         $file_contents = $parser->parsed_file();
     } else {
         $file_contents = file_get_contents($file->full_path());
     }
     $etag = md5($file_contents);
     $date = date('D, d M Y H:i:s e');
     $last_modified = Rails::cache()->fetch('assets.last_mod.' . $file->full_path(), function () use($date) {
         return $date;
     });
     if ($this->file_modified($etag, $last_modified)) {
         $this->headers()->add("Last-Modified", $last_modified);
         $this->headers()->add("Cache-Control", 'public, max-age=31536000');
         $this->headers()->add("ETag", $etag);
         Rails::application()->dispatcher()->response()->body($file_contents);
     } else {
         $this->headers()->status('HTTP/1.1 304 Not Modified');
         Rails::application()->dispatcher()->response()->body('');
     }
 }