An easy CSS compressor
Posted: Mon Aug 15, 2011 1:29 pm
				
				This is a class I wrote some time ago but it still serves me today.
It`s usage is quite simple. You create a new object and you give the paths to the CSS files, also you give an array of CSS files to compress.
Now, the only thing you have to remember is this: in order for this to work, you should have write access on your PHP installation. So this usually means 0755. If this is not the case, try 0777. Be sure to modify them back after you can go in production. 
So in my case it looks like something like this:
			Code: Select all
<?php
class CssCompression
{
    private     $files = array();
    private     $toFile;
    private     $fromPath;
    private     $toPath;
    private     $ext;
    public function CssCompression($files, $toFile='style', $ext='.css',$fromPath='', $toPath='')
    {
        $this->files=$files;
        $this->toFile=$toFile;
        $this->fromPath=$fromPath;
        $this->toPath=$toPath;
        $this->ext=$ext;
        $this->content='';
    }
    /**
     * @param <type> string de content van de file.
     * @return <type> string The compressed string
     */
    public function compress ($file)
    {
        $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $file);
        $buffer = str_replace(array("\r\n", "\r", "\n", "\t", '  ', '    ', '    '), '', $buffer);
        
        return $buffer;
    }
    /**
     * This method checks if the dates of the files have been modified. If the given array
     * has a file more recently edited then the main file, this function will write new output.
     * @return <type> boolean true if a file is newer, flase if not
     */
    public function verifyDates ()
    {
        foreach($this->files as $file)
        {
            if( filemtime($this->fromPath.$file.$this->ext) > filemtime($this->toPath.$this->toFile.$this->ext) )
                return true;
        }
        return false;
    }
    
    function getLatestTime(){
        return filemtime($this->toPath.$this->toFile.$this->ext);
    }
    /**
     * Write all buffered Output back to the main file.
     * @return <type> bool true on succcess, false on failure
     */
    public function writeNewCss ()
    {
        $this->content = "/* Style.css |  | Last edit: ".date("Y-m-d H:i:s")." */\n";
        foreach($this->files as $file)
        {
            $this->content.=$this->getContentFromCss($file);
        }
        if(file_put_contents($this->toPath.$this->toFile.$this->ext, $this->content))
        {
            return true;
        }
        return false;
    }
    /**
     *  Returns all content from the css as a strong
     * 
     * @param <type> string $file
     * @return <type> string $buffer
     */
    public function getContentFromCss ($file)
    {
        $buffer= " \n\n/* File: ".$file.$this->ext." */\n";
        $buffer.= $this->compress(file_get_contents($this->fromPath.$file.$this->ext));
        return $buffer;
    }
    /**
     * print output of all files
     */
    public function printContent()
    {
        return $this->content;
    }
    
}
Code: Select all
require "path/to/CssCompression.php";
$filesToCompress = array('header', 'footer', 'content');
$css = new CssCompression($filesToCompress, "nameOfCompressedFile", ".css", "css/", "css/");
// Now, to actually compress the files, you have to check if the files have been modified
if($css->verifyDates()){ 
     // A newer date was found, so it should recompress
     $css->writeNewCss();
}
So in my case it looks like something like this:
Code: Select all
<?php
require "/my/path/to/CssCompression.php";
$path = "http://localhost/project/resources/css/";
$files = array('header', 'footer', 'content', 'forms', 'ui', 'notify');
$css = new CssCompression($files, 'style', '.css', $path, $path);
if($css->verifyDates() ) {
     $css->writeNewCss();
}
$latest = $css->getLatestTime();
?>
<link type="text/css" rel="stylesheet" href="'.$path.'style.css?v='.$latest.'" />