<?php #charset → utf-8

/**
	Ini parser _and_ writer !
	
    @licence LGPL
	@author Yoan Blanc
	@revision 20060605
    
    @usage
    // for PHP5
    // opens a file
    $ini = new Ini("site.ini");
    // gets the value of the element user of the section ftp
    echo $ini->getValue("user", "ftp");
    // sets the value ftp.user to moo
    $ini->setValue("moo", "user", "ftp");
    // generates the new file
    echo '<pre>'.$ini.'</pre>';
*/

// Ini, a funky ini manipulator for PHP
// Copyright (C) 2006, Yoan Blanc <yoan at dosimple dot ch>
// 
//     This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2.1 of the License, or (at your
// option) any later version.
// 
//     This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// License for more details.
// 
//     You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 


class Ini
{
	function Ini($filename, $process_section=false)
	{
		$this->filename = $filename;
		$this->section = $process_section;
		
		if(file_exists($filename))
			$this->values = parse_ini_file($this->filename, $this->section);
		else
			$this->values = array();
	}
	
	// private
	function __testSection($section)
	{
		if ($section === null && $this->section)
		{
            trigger_error("Specify the name of the section", E_USER_ERROR);
		}
	}
	
	function __testKey($keyname, $section=null)
	{
		if(!$this->keyExists($keyname, $section))
		{
			trigger_error("The key '$section.$keyname' doesn't exist", E_USER_ERROR);
		}
	}
	
	function keyExists($keyname, $section)
	{
		$this->__testSection($section);
		
		return ($section == null)
			? array_key_exists($keyname, $this->values)
			: array_key_exists($keyname, $this->values[$section]);
	}
	
	function & getValue($keyname, $section=null)
	{
		$this->__testKey($keyname, $section);
		
		return ($section == null)
			? $this->values[$keyname]
			: $this->values[$section][$keyname];
	}
	
	function setValue($value, $keyname, $section=null)
	{
		if($section == null)
			$this->values[$keyname] = $value;
		else
		{
			if(!isset($this->values[$section]))
				$this->values[$section] = array();
			
			$this->values[$section][$keyname] = $value;
		}
	}
	
	/// Gets the ini (modified)
	function __toString()
	{
		$newfile = "";
		
		if(file_exists($this->filename))
		{
			$fp = fopen($this->filename, "r");
			$keys = array();
			$sections = array();
			$section = null;
			
			while(!feof($fp))
			{
				$line = trim(fgets($fp));
				
				if(strpos($line, "[") === 0)
				{
					if($this->section)
					{
						preg_match('/^\[(.*?)\]/',$line,$m);
						
						// Adds the added keys
						if(count($keys) > 0)
							foreach(array_diff(array_keys($this->values[$section]), $keys) as $key)
							{
								$newfile .= $key."=".$this->getValue($key, $section)."\n";
							}
						
						$keys = array();
						$section = $m[1];
						$sections[] = $m[1];
					}
					
					$newfile .= $line."\n";
				}
				elseif(preg_match('/^(\w+)\s*=/',$line, $matches))
				{
					if($this->keyExists($matches[1], $section))
					{
						$newfile .= $matches[1]."=".$this->getValue($matches[1], $section)."\n";
						$keys[] = $matches[1];
					}
					else
					{
						$newfile .= $line."\n";
					}
				}
				else
				{
					$newfile .= $line."\n";
				}
			}
			
			if($this->section)
			{
				// Adds the added keys
				foreach(array_diff(array_keys($this->values[$section]), $keys) as $key)
					$newfile .= $key."=".$this->getValue($key, $section)."\n";
				
				foreach(array_diff(array_keys($this->values), $sections) as $section)
				{
					$newfile .= "[$section]\n";
					foreach($this->values[$section] as $key=>$value)
						$newfile .= $key."=".$value."\n";
				}
			}
			else
			{
				foreach(array_diff($keys, array_keys($this->values)) as $key)
					$newfile .= $key."=".$this->getValue($key, $section)."\n";
			}
			
			fclose($fp);
		}
		else
		{
			if($this->section)
				foreach($this->values as $section => $values)
				{
					$newfile .= "[$section]\n";
					foreach($values as $key=>$value)
						$newfile .= $key."=".$value."\n";
				}
			else
				foreach($this->values as $key=>$value)
					$newfile .= $key."=".$value."\n";
		}
		
		return $newfile;
	}
}
?>
