Location: PHPKode > scripts > CSS Comparer > css-comparer/cssComparer1.0.php
<?php
/**
 * @Id: cssComparer.php
 * @Version: 1.01
 * @Author: Martijn Beulens <hide@address.com>
 * @License: No license
 * @Comment: Compares 2 css files for missing classes and missing arguments
*/


/**
* Usage:
* Create a blank php file with the folowing code
*
* include('cssComparer1.0.php');
*
* new cssComparer();
*
*/

/* class */
class cssComparer
{

	/* Properties */
	
	/**
	 * @Name: FileStructure1
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Access: protected
	 * @Since: version 10.00001
	 * @Comment: Contains css structure for file 1
	*/
	private $FileStructure1;

	/**
	 * @Name: FileStructure2
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Access: protected
	 * @Since: version 10.00001
	 * @Comment: Contains css structure for file 2
	*/
	private $FileStructure2;

	/**
	 * @Name: HtmlReport
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Access: protected
	 * @Since: version 10.00001
	 * @Comment: Contains html report
	*/
	private $HtmlReport;
	

//---------------------------------------------------------------------------------------

	/**
	 * @Name: __construct
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Param: void
	 * @Return: void
	 * @Access: public
	 * @Since: version 10.00001
	 * @Comment: constructor
	*/
	public function __construct()
	{
		//Set
		$this->FileStructure1 = array();
		$this->FileStructure2 = array();
		$this->HtmlReport = array();
	
		//HTTP header
		$this->httpHeader();
		
		//HTML header
		$this->htmlHeader();
		
		//FORM upload
		$this->formUpload();
		
		//Process css files
		$this->processFiles();
		
		//HTML footer
		$this->htmlFooter();
	}

//---------------------------------------------------------------------------------------

	/**
	 * @Name: httpHeader
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Param: void
	 * @Return: void
	 * @Access: private
	 * @Since: version 10.00001
	 * @Comment: http header for output
	*/
	private function httpHeader()
	{
		header("Content-Type: text/html; charset=UTF-8");
		header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 				//Date in past
		header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");	//Always new
		header("Cache-Control: no-store, no-cache, must-revalidate");	// HTTP/1.1
		header("Cache-Control: post-check=0, pre-check=0", false);		//post cehck pre check
		header("Pragma: no-cache");										// HTTP/1.0				
	}

//---------------------------------------------------------------------------------------

	/**
	 * @Name: htmlHeader
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Param: void
	 * @Return: void
	 * @Access: private
	 * @Since: version 10.00001
	 * @Comment: HTML header for page output
	*/
	private function htmlHeader()
	{
		echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"  \"http://www.w3.org/TR/html4/strict.dtd\">\n";
		echo "<html>\n";
		echo "<head>\n";
		echo "<title>CSS comparer</title>\n";
		echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n";
		$this->htmlStylesheet();
		echo "</head>\n";
		echo "<body>\n";
		echo "<h2>CSS comparer</h2>\n";
	}

//---------------------------------------------------------------------------------------

	/**
	 * @Name: htmlFooter
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Param: void
	 * @Return: void
	 * @Access: private
	 * @Since: version 10.00001
	 * @Comment: HTML footer for page output
	*/
	private function htmlFooter()
	{
		echo "<hr>\n";
		echo "<address>Created by Abisvmm cssComparer 1.0</address>\n";
		echo "</body>\n";
		echo "</html>\n";
	}

//---------------------------------------------------------------------------------------

	/**
	 * @Name: htmlStylesheet
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Param: void
	 * @Return: void
	 * @Access: private
	 * @Since: version 10.00001
	 * @Comment: HTML stylesheet for page output
	*/
	private function htmlStylesheet()
	{
		echo "<style type=\"text/css\">\n";
		echo "label input { margin: 0px 0px 0px 4px; width: 600px; } ";
		echo ".function { color: #FF00FF; }\n";
		echo ".argument { color: #000099; }\n";
		echo ".value { color: #0000FF; }\n";
		echo ".error { color: #FF0000; }\n";
		echo ".cell { padding: 4px; border: 1px solid ThreeDShadow; }\n";
		echo ".header { background-color: HighLight; color: HighLightText} \n";
		echo "</style>\n";
		
	}

//---------------------------------------------------------------------------------------

	/**
	 * @Name: formUpload
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Param: void
	 * @Return: void
	 * @Access: private
	 * @Since: version 10.00001
	 * @Comment: Upload form for css files
	*/
	private function formUpload()
	{
		echo "<fieldset>\n";
		echo "<legend>Upload</legend>\n";
		echo "<form action=\"\" method=\"post\" enctype=\"multipart/form-data\" name=\"frmUpload\" id=\"frmUpload\">\n";
		echo "<label>Css file 1<input type=\"file\" name=\"file1\" /></label><br />\n";
		echo "<label>Css file 2<input type=\"file\" name=\"file2\" /></label><br />\n";
		echo "<br />\n";
		echo "<input type=\"submit\" value=\"Compare\">\n";
		echo "</form>\n";
		echo "</fieldset>\n";
	}

//---------------------------------------------------------------------------------------

	/**
	 * @Name: processFiles
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Param: void
	 * @Return: void
	 * @Access: private
	 * @Since: version 10.00001
	 * @Comment: Process the file upload & compare process
	*/
	private function processFiles()
	{
		//Test post
		if($_SERVER['REQUEST_METHOD']=='POST')
		{

			//Var
			$Validated = true;
			$Log = array();
			$FileNames = array('file1','file2');
			$FileTypes = array('text/css','application/x-css');
			
			//Loop fileNames
			foreach($FileNames as $FileName)
			{
				//Test empty
				if(empty($_FILES[$FileName])) 
				{
					$Validated = false;
					$Log[] = $FileName." is empty";
				}
				else
				{
					if($_FILES[$FileName]['error']!=0)
					{
						$Validated = false;
						$Log[] = $FileName." has upload error ".$_FILES[$FileName]['error'];
					}
					else
					{
						if($_FILES[$FileName]['size'] <= 0)
						{
							$Validated = false;
							$Log[] = $FileName." has no contents. Size = ".$_FILES[$FileName]['size'];
						}
						else
						{
							if(!in_array(strtolower($_FILES[$FileName]['type']),$FileTypes))
							{
								$Validated = false;
								$Log[] = $FileName." has unsupported file type (".$_FILES[$FileName]['type']."). Supported types: ".implode(', ',$FileTypes)."";
							}
						
						}
					}
				}
			
			} //End foreach($FileNames as $FileName)
			
			
			//Test validated
			if($Validated)
			{
				//File names
				$FileName1 = $_FILES['file1']['name'];
				$FileName2 = $_FILES['file2']['name'];
			
				//Read files
				$fileData[1] = $this->formatCss(implode('',file($_FILES['file1']['tmp_name'])));
				$fileData[2] = $this->formatCss(implode('',file($_FILES['file2']['tmp_name'])));
				
				
				//Read structures
				$this->extractCssClasses($this->FileStructure1,$fileData[1]);
				$this->extractCssClasses($this->FileStructure2,$fileData[2]);
				
				//Compare classes
				$this->compareCssClasses($this->FileStructure1,$this->FileStructure2);
				
				//Result
				echo "<h2>Differences</h2>\n";
				
				//Start table
				echo "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">\n";
				
				//Header
				echo "<tr>\n";
				echo "<th class=\"header\">File 1 (".$FileName1.")</th>\n";
				echo "<th class=\"header\">File 2 (".$FileName2.")</th>\n";
				echo "</tr>\n";
				
				//Loop
				foreach($this->HtmlReport as $ar)
				{
					echo "<tr>\n";
					echo "<td valign=\"top\" class=\"cell\"><pre>".$ar['1']."</pre></td>\n";
					echo "<td valign=\"top\" class=\"cell\"><pre>".$ar['2']."</pre></td>\n";
					echo "</tr>\n";
				}
				echo "</table>\n";
				
			}
			else
			{
				echo "<h3 class=\"error\">Error</h3>\n";
			
				//Print log
				echo "<ul>\n";
				foreach($Log as $error)
				{
					echo "<li class=\"\">".$error."</li>\n";
				}
				echo "</ul>\n";
			} //End if($Validated)
			
		} //End if($_SERVER['REQUEST_METHOD']='POST')
		
	}

//---------------------------------------------------------------------------------------

	/**
	 * @Name: formatCss
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Param: (string) data
	 * @Return: (string) data
	 * @Access: private
	 * @Since: version 10.00001
	 * @Comment: Format css data 
	*/
	private function formatCss($data)
	{
		$data = preg_replace("/\/\*[\d\D]*?\*\//is","",$data);
		
		//$data = str_replace(":",": ",$data);
		$data = str_replace(";","; ",$data);
		$data = str_replace(",",", ",$data);
		$data = str_replace("{"," {",$data);
		$data = str_replace("\r"," ",$data);
		$data = str_replace("\n"," ",$data);
		$data = str_replace("\t"," ",$data);
		$data = str_replace("}","}\n",$data);
		$data = str_replace("  "," ",$data);
		$data = str_replace("  "," ",$data);
		$data = str_replace("\n ","\n",$data);
		
		$Lines = explode("\n",$data);
		$newData = '';
		foreach($Lines as $Line)
		{
			$Line = trim($Line);
			if($Line!="")
			{
				$newData .= $Line."\n";
			}
		}
		
		return trim($newData);
	}

//---------------------------------------------------------------------------------------

	/**
	 * @Name: extractCssClasses
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Param: &(array) structure
	 * @Return: (string) cssdata
	 * @Access: private
	 * @Since: version 10.00001
	 * @Comment: extractCssClasses
	*/
	private function extractCssClasses(&$structure,$fileData)
	{
		$explodeFile = explode("\n",$fileData);
		foreach($explodeFile as $cssMethod)
		{
			$pattern = "/(.*){(.*)}/is";
			preg_match($pattern,$cssMethod,$result);
			
			//Test
			if(isset($result[1]) && isset($result[2]) )
			{
				$varName = trim($result[1]);
				$arguments = trim($result[2]);
				
				if(!isset($structure[$varName])) { $structure[$varName] = array(); }
				
				//Expplode arguments
				$argExplode = explode(";",$arguments);
				foreach($argExplode as $arg)
				{
					//Explode on :
					$fEx = explode(":",$arg);
					if( isset($fEx[0]) && isset($fEx[1]) )
					{
						$structure[$varName][trim($fEx[0])] = trim($fEx[1]);
					}
					
					
				}
			}
					
		}
	
	}
	
//---------------------------------------------------------------------------------------

	/**
	 * @Name: compareCssClasses
	 * @Author: Martijn Beulens <hide@address.com>
	 * @Param: (array) structure1, (array) structure2
	 * @Return: void
	 * @Access: private
	 * @Since: version 10.00001
	 * @Comment: Compares the classes of 2 files
	*/
	private function compareCssClasses($Structure1,$Structure2)
	{
		//Var
		$Differences = array();
			
		//Loop Structure1
		foreach($Structure1 as $Class=>$Arguments)
		{
			//Test if class exists in other
			if(isset($Structure2[$Class]))
			{
				$diff = array_diff_key($Arguments, $Structure2[$Class]);
				
				if(!empty($diff))
				{
					//Test for diff array
					if(!isset($Differences[$Class])) { $Differences[$Class] = array(); }
	
					//Set
					$Differences[$Class][1] = $diff;
				}
			}
			else
			{
				//Test for diff array
				if(!isset($Differences[$Class])) { $Differences[$Class] = array(); }

				//Set
				$Differences[$Class][2] = array('error'=>'class does not exist');
			
			}
		}

		//Loop Structure2
		foreach($Structure2 as $Class=>$Arguments)
		{
			//Test if class exists in other
			if(isset($Structure1[$Class]))
			{
				$diff = array_diff_key($Arguments, $Structure1[$Class]);
				
				if(!empty($diff))
				{
					//Test for diff array
					if(!isset($Differences[$Class])) { $Differences[$Class] = array(); }
	
					//Set
					$Differences[$Class][2] = $diff;
				}
			}
			else
			{
				//Test for diff array
				if(!isset($Differences[$Class])) { $Differences[$Class] = array(); }

				//Set
				$Differences[$Class][1] = array('error'=>'class does not exist');
				
			}
		}
		
		//Loop differences
		foreach($Differences as $Class=>$DiffFile)
		{
			
			//Var
			$HTML[1] = "";
			$HTML[2] = "";

			//Start class
			$HTML[1] .= "<span class=\"function\">".$Class."</span>\n<span class=\"function\">{</span>\n";
			$HTML[2] .= "<span class=\"function\">".$Class."</span>\n<span class=\"function\">{</span>\n";

			//Get 1
			if(isset($Structure1[$Class]))
			{
				foreach($Structure1[$Class] as $ArgumentName=>$Value)
				{
					//Test difference
					if(!isset($DiffFile[1][$ArgumentName]))
						$HTML[1] .= "\t<span class=\"argument\">".$ArgumentName.": </span><span class=\"value\">".$Value."</span><span class=\"function\">;</span>\n";
					else
						$HTML[1] .= "\t<span class=\"error\">".$ArgumentName.": </span><span class=\"error\">".$Value."</span><span class=\"function\">;</span>\n";
					
				}
			}
			else
				$HTML[1] .= "\t<span class=\"error\">Class not found</span>\n";
			
			//Get 2
			if(isset($Structure2[$Class]))
			{
				foreach($Structure2[$Class] as $ArgumentName=>$Value)
				{
					if(!isset($DiffFile[2][$ArgumentName]))
						$HTML[2] .= "\t<span class=\"argument\">".$ArgumentName.": </span><span class=\"value\">".$Value."</span><span class=\"function\">;</span>\n";
					else
						$HTML[2] .= "\t<span class=\"error\">".$ArgumentName.": </span><span class=\"error\">".$Value."</span><span class=\"function\">;</span>\n";
					
				}
			}
			else
				$HTML[2] .= "\t<span class=\"error\">Class not found</span>\n";
				
			//End class
			$HTML[1] .= "<span class=\"function\">}</span>\n";
			$HTML[2] .= "<span class=\"function\">}</span>\n";
			
			//Append to report			
			$this->HtmlReport[] = $HTML;

		
		}
	
	}
	
//---------------------------------------------------------------------------------------


} //End class cssComparer



?>
Return current item: CSS Comparer