Location: PHPKode > scripts > hnwb_ListView for WinBinder > hnwb_listview-for-winbinder/hn_basic.class.php
<?PHP
/*****************************************************************************
  | @script_type -  PHP-CLASS
  | @scriptname  -  hn_basic.class.php
  | @version     -
  | -------------------------------------------------------------------------
  | @author      -  Horst Nogajski <hide@address.com>
  | @copyright   -  (c) 1999 - 2006
  | @licence     -  LGPL
  | -------------------------------------------------------------------------
  | $Source: /WINBINDER/hnwb_ListViewClass/hn_basic.class.php,v $
  | $Id: hn_basic.class.php,v 1.2 2007/01/04 22:21:42 horst Exp $
 ****************************************************************************/




	/** Check for (and Correct) the trailing Slash from DocRoot-Variable.
	  * This dependends on if the Servers- or VirtualHost-Docroot in Apache-config
	  * is written with or without a trailing Slash! (Normaly there should be no slash!)
	  **/
	if(isset($_SERVER['DOCUMENT_ROOT'])) {
		if(strrpos($_SERVER['DOCUMENT_ROOT'],'/') == strlen($_SERVER['DOCUMENT_ROOT']) -1) {
			$_SERVER['DOCUMENT_ROOT'] = substr($_SERVER['DOCUMENT_ROOT'], 0, strlen($_SERVER['DOCUMENT_ROOT']) -1);
		}
	} else { $_SERVER['DOCUMENT_ROOT'] = ''; } // If it isn't set, we run in commandline mode and we set it to an empty string



	// Magic-Constant __FUNCTION__ is only available since PHP 4.3.0
	if(!defined('__FUNCTION__')) define('__FUNCTION__','');



	// 'is_executable' on Windows is only available since PHP 5.0.0
	// this is a workaround for hometesting only ;-)
	if(!function_exists('is_executable'))
	{
		function is_executable($filename)
		{
			return is_file($filename) && is_readable($filename);
		}
	}



	// DEBUG-/LOGTYPE Definitions
	if(!defined('DBG_LOG_NONE')) define('DBG_LOG_NONE',0);	// No log-operations
	if(!defined('DBG_LOG_ECHO')) define('DBG_LOG_ECHO',1);	// Echo to screen for Webbrowser
	if(!defined('DBG_LOG_CMDL')) define('DBG_LOG_CMDL',2);	// Echo to screen for CommandlineConsole
	if(!defined('DBG_LOG_HIDE')) define('DBG_LOG_HIDE',3);	// Echo to HTML comment <!-- -->
	if(!defined('DBG_LOG_WINB')) define('DBG_LOG_WINB',4);	// Write the MessageString to a WinBinder-Object, e.g. an Editbox
	if(!defined('DBG_LOG_FILE')) define('DBG_LOG_FILE',5);	// Logentry into file
															// (you can also use combinations with FILE:
															//  ECHO + FILE | CMDL + FILE | HIDE + FILE)



/** This class holds some basic methods which are often required by any other
  * of my classes, which therefore always extend the hn_basic class.
  *
  * These are mainly small help functions like:
  *
  *    setCacheArray | getCacheArray
  *
  *    string2file | file2string | array2file | file2array | etc.
  *
  *    sorting methods for multidimensional-Arrays (hn_array_sort | hn_arrayKey_sort)
  *
  * or e.g.:
  *
  *    the debug and logging methods
  *
  *    the destructor-method (what is not implemented natively in PHP < 5)
  *
  *    the txt_counter method (and it's selftest method)
  *
  * (have a look to the code)
  *
  *
  * @shortdesc some basic functions
  * @public
  * @author Horst Nogajski, Copyright (c) 2004
  * @version $Revision: 1.2 $
  * @date $Date: 2007/01/04 22:21:42 $
  *
  **/
class hn_basic
{


	/////////////////////////////////////////////
	//	PUBLIC PARAMS

		/** Defines the type of debugging / logging.
          * You can use this constants:
          * [ DBG_LOG_NONE | DBG_LOG_ECHO | DBG_LOG_CMDL | DBG_LOG_HIDE | DBG_LOG_FILE ]
          * or this combinations:
          * [ DBG_LOG_ECHO + DBG_LOG_FILE  | DBG_LOG_CMDL + DBG_LOG_FILE  | DBG_LOG_HIDE + DBG_LOG_FILE ]
          *
		  * @shortdesc defines the type of logging / debugging
		  * @public
		  * @type integer
		  **/
		var $debugoutput 	= 0; // DBG_LOG_NONE


		/** A call to the debug-func (optionally) can have an ID-string.
          * This will checked against this pattern. If it matches, the
          * logging/debugging is allowed, otherwise will be ignored.
          * This allows to define lots of debug-calls in script's
          * (and classes) and having a good method to filter.
          *
		  * @shortdesc a RegEx-pattern used to select debug-output
		  * @public
		  * @type string
		  **/
		var $debugpattern 	= '/.*/';



		/** @shortdesc  A Handle to a WinBinder Object, e.g. an Editbox.
		  *	            This Handle should be passed by reference.
		  * @public
		  * @type string
		  **/
		var	$debug_wb_handle = null;


		/** @shortdesc Contains the message for the Debug-/Loggingfunc
		  * @public
		  * @type string
		  **/
		var $msg 			= '';


		/** @shortdesc Prefix for Logfilename
		  * @public
		  * @type string
		  **/
		var $logfile 		= "hn_classes_log";


		/** @shortdesc The String which should be used as separator for entries in Logfile.
		  * @public
		  * @type string
		  **/
		var $lf_separator 	= "\n";


		/** @shortdesc seconds a script can run, after you have called the func SetScriptTimeout
		  * @public
		  * @type integer
		  **/
		var $hn_SCRIPT_TIMEOUT	= 30;



	/////////////////////////////////////////////
	//	PRIVATE PARAMS

		/** @shortdesc Filehandle to Logfile
		  * @private
		  **/
		var $logfilehdl = null;


		/** @shortdesc stores the value of default error reporting
		  * @private
		  **/
		var $default_error = array();



	/////////////////////////////////////////////
	//	CONSTRUCTOR

		/** Constructor
		  * @public
		  **/
		function hn_basic($config='',$secure=TRUE)
		{
			$this->getErrorLevel();

			// extracts config Array
			if(is_array($config))
			{
				if($secure && strcmp('4.2.0', phpversion()) < 0)
				{
					$valid = get_class_vars(get_class($this));
					$extracted = 0;
					foreach($config as $k=>$v)
					{
						if(array_key_exists($k,$valid))
						{
							$this->$k = $v;
							$extracted++;
						}
					}
					$this->msg = 'Config-Array extracted in secure-mode: $hn_basic->CONSTRUCTOR() [ possible: '.count($valid).' | extracted: '.$extracted.' | skipped: '.(count($config)-$extracted).' ]';
					$this->debug('hn_basic,ini');
				}
				else
				{
					foreach($config as $k=>$v) $this->$k = $v;
					$this->msg = 'Config-Array extracted in _UN_secure-mode: $hn_basic->CONSTRUCTOR() [ extracted: '.count($config).' ]';
					$this->debug('hn_basic,ini');
				}
			}
			else
			{
				$this->msg = 'Initialized without Config-Array: $hn_basic->CONSTRUCTOR()';
				$this->debug('hn_basic,ini');
			}
		}


	/////////////////////////////////////////////
	//	DESTRUCTOR

		/** @shortdesc This add a func-call to Globalarray which will executed when Destructor runs!
		  * @public
		  **/
		function runOnShutdown($func='')
		{
			// first call of function
			if(!isset($GLOBALS['__hn_ShutdownFunction__']))
			{
				if($this->msg == '')
				{
					$this->msg = '- Initiate hn_basic_Destructor as main register_shutdown_function!';
					$this->debug('ini,hn_basic,close,shutdown,sys');
				}
				else
				{
					$this->msg = '- Initiate hn_basic_Destructor as main register_shutdown_function!'.$this->lf_separator.$this->msg;
				}
				register_shutdown_function(array(&$this, 'hn_basic_Destructor'));
				$GLOBALS['__hn_ShutdownFunction__']['enabled'] = TRUE;

			}
			if($func!='') {
				$GLOBALS['__hn_ShutdownFunction__']['__THINX2UNSET__'][md5($func)] = addslashes($func);
				if($this->msg == '') {
					$this->msg = "- register a ShutDownFunc: $func";
					$this->debug('ini,hn_basic,close,shutdown,sys');
				} else {
					$this->msg = $this->msg.$this->lf_separator."- register a ShutDownFunc: $func";
				}
			}

		}

		/** @shortdesc This will be registered as ShutdownFunc. It closes the Logfilehandle, and execute all code which was added by the runOnShutdown()-func!
		  * @private
		  **/
		function hn_basic_Destructor()
		{
				// should run only one time!
				if(!isset($GLOBALS['__hn_ShutdownFunction__']['enabled'])) return;
				if($GLOBALS['__hn_ShutdownFunction__']['enabled']===FALSE)
				{
					$this->msg .= $this->lf_separator.'Running shutdown_function was set to FALSE after it was registered!';
					$this->debug('ini,hn_basic,close,shutdown,sys');
					$this->logfile_close();
					unset($GLOBALS['__hn_ShutdownFunction__']['enabled']);
					return;
				}
				unset($GLOBALS['__hn_ShutdownFunction__']['enabled']);
			$this->msg .= $this->msg == '' ? 'Running shutdown_function: $hn_basic->hn_basic_Destructor()' : $this->lf_separator.'Running shutdown_function: $hn_basic->hn_basic_Destructor()';
			$this->debug('ini,hn_basic,close,shutdown,sys');
			if(isset($GLOBALS['__hn_ShutdownFunction__']['__THINX2UNSET__']))
			{
				foreach($GLOBALS['__hn_ShutdownFunction__']['__THINX2UNSET__'] as $func)
				{
					$func = stripslashes($func);
					$this->msg = "- running: $func";
					$this->debug('ini,hn_basic,close,shutdown,sys');
					eval("$func");
				}
			}
			$this->logfile_close();
		}


	/////////////////////////////////////////////
	//  PUBLIC METHODS


		function InputSecurityCheck($exclude_GET=FALSE,$exclude_POST=FALSE,$exclude_COOKIES=FALSE)
		{
			if(!$exclude_GET) {
				if(is_array($_GET)) {
					while(list($key, $value) = each($_GET))
						$_GET["$key"] = strip_tags($value);
				}
			}
			if(!$exclude_POST) {
				if(is_array($_POST)) {
					while(list($key, $value) = each($_POST))
						$_POST["$key"] = strip_tags($value);
				}
			}
			if(!$exclude_COOKIES) {
				if(is_array($_COOKIES)) {
					while(list($key, $value) = each($_COOKIES))
						$_COOKIES["$key"] = strip_tags($value);
				}
			}
		}



		function getErrorLevel()
		{
			$this->default_error['level']   = error_reporting();
			$this->default_error['display'] = ini_get('display_errors');
			$this->default_error['html']    = ini_get('html_errors');
		}

		function setErrorLevel($level=FALSE,$display="",$html="")
		{
			/*
			    Value	Constant (integer)	Description
				1		E_ERROR 			Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted.
				2		E_WARNING 			Run-time warnings (non-fatal errors). Execution of the script is not halted.
				4		E_PARSE 			Compile-time parse errors. Parse errors should only be generated by the parser.
				8		E_NOTICE 			Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.
				16		E_CORE_ERROR 		Fatal errors that occur during PHP's initial startup. This is like an E_ERROR, except it is generated by the core of PHP.
				32		E_CORE_WARNING 		Warnings (non-fatal errors) that occur during PHP's initial startup. This is like an E_WARNING, except it is generated by the core of PHP.
				64		E_COMPILE_ERROR 	Fatal compile-time errors. This is like an E_ERROR, except it is generated by the Zend Scripting Engine.
				128		E_COMPILE_WARNING 	Compile-time warnings (non-fatal errors). This is like an E_WARNING, except it is generated by the Zend Scripting Engine.
				256		E_USER_ERROR 		User-generated error message. This is like an E_ERROR, except it is generated in PHP code by using the PHP func trigger_error().
				512		E_USER_WARNING 		User-generated warning message. This is like an E_WARNING, except it is generated in PHP code by using the PHP func trigger_error().
				1024	E_USER_NOTICE 		User-generated notice message. This is like an E_NOTICE, except it is generated in PHP code by using the PHP func trigger_error().
				2047	E_ALL 				All errors and warnings, as supported, except of level E_STRICT.
				2048	E_STRICT 			Run-time notices. Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code.
			*/

			if($level !== FALSE) error_reporting($level);
			else error_reporting($this->default_errorlevel);

			if($display !== "") ini_set('display_errors', (bool)$display);
			else ini_set('display_errors', (bool)$this->default_error['display']);

			if($html !== "") ini_set('html_errors', (bool)$html);
			else ini_set('html_errors', (bool)$this->default_error['html']);
		}



	/////////////////////////////////////////////
	//	DEBUGGING + LOGGING

		/**
		  * This raise a Debug- or Log-output.
		  * The type, and cases of output is dependend on following settings:
          * 1) $classhandle->debugoutput
          * 2) $classhandle->debugpattern
          * 3) $classhandle->logfile
          * 4) $classhandle->msg
          * Typically it is used like this:
          * $classhandle->msg = "This is my message";
          * $classhandle->debug('ID-string');
		  *
		  * @shortdesc Outputs the string currently stored in $classhandle->msg in the way specified with $classhandle->debugoutput and $classhandle->debugpattern
		  * @public
		  *
		  **/
		function debug($match="alles")
		{
			if(!isset($this->debugpattern) || $this->debugpattern=="") $this->debugpattern = "/.*/";
			if(preg_match($this->debugpattern, $match))
			{
				if($this->debugoutput > 4 && (!$this->logfilehdl)) $this->logfile_init($match);
				switch($this->debugoutput)
				{
					case 0:
						// NO LOG OPERATIONS
						break;
					case 1:
						// SCREEN OUTPUT for Browser
						echo "\n<br>".$this->nlreplace(htmlentities($this->msg),'<br>')."\n";
						break;
					case 2:
						// SCREEN OUTPUT for CommandlineWindow
						echo "\n".$this->msg;
						break;
					case 3:
						// BROWSER SILENT OUTPUT (<!-- -->)
						echo "\n<!-- DEBUG: " . $this->msg . "-->\n";
						break;
					case 4;
						if(function_exists('wb_get_text'))
						{
							if(!isset($this->wb_log)) $this->wb_log = array();
							$this->wb_log[] = $this->msg;
							// write to WinBinder Object
							$s = $this->msg . $this->lf_separator . wb_get_text($this->debug_wb_handle);
							wb_set_text($this->debug_wb_handle,$s);
							wb_refresh($this->debug_wb_handle);
						}
						break;
					case 5:
						// FILE OUTPUT
						fwrite($this->logfilehdl,$this->lf_separator.$this->msg);
						break;
					case 6:
						// FILE + SCREEN OUTPUT for Browser
						fwrite($this->logfilehdl,$this->lf_separator.$this->msg);
						echo "\n<br>".$this->nlreplace(htmlentities($this->msg),'<br>')."\n";
						break;
					case 7:
						// FILE + SCREEN OUTPUT for CommandlineWindow
						fwrite($this->logfilehdl,$this->lf_separator.$this->msg);
						echo "\n".$this->msg;
						break;
					case 8:
						// FILE + BROWSER SILENT OUTPUT (<!-- -->)
						fwrite($this->logfilehdl,$this->lf_separator.$this->msg);
						echo "\n<!-- DEBUG: " . $this->msg . "-->\n";
						break;
					case 9;
						if(function_exists('wb_get_text'))
						{
							if(!isset($this->wb_log)) $this->wb_log = array();
							$this->wb_log[] = $this->msg;
							// write to WinBinder Object
							$s = $this->msg . $this->lf_separator . wb_get_text($this->debug_wb_handle);
							wb_set_text($this->debug_wb_handle,$s);
							wb_refresh($this->debug_wb_handle);
						}
						fwrite($this->logfilehdl,$this->lf_separator.$this->msg);
						break;
				}
				if(preg_match('/[1-3|6-8]/',$this->debugoutput)) flush();
				$this->msg = '';
			}
		}


		/** Wrapper for the Debug-function
		  * Use it (for errors only) like this: $this->Error('my message',__FILE__,__FUNCTION__,__LINE__[,TRUE]);
          *
		  * @shortdesc Wrapper for the debug function.
		  * @public
		  **/
		function Error($msg,$FILE='',$FUNCTION='',$LINE='',$resetGlobalErrMsg=FALSE)
		{
			$this->msg = "ERROR: [$msg] [$FILE] [$FUNCTION] [$LINE]";
			$this->msg .= isset($php_errormsg) ? " [$php_errormsg]" : '';
			$this->debug('error,Error,ERROR');
			if($resetGlobalErrMsg) $php_errormsg = '';
		}

		/** @shortdesc temporary suppress logging
		  * @public
		  **/
		function quiet($mode=TRUE)
		{
			if($mode)
			{
				$this->dbg = $this->debugoutput;
				$this->debugoutput = 0;
			}
			else
			{
				if(isset($this->dbg)) $this->debugoutput = $this->dbg;
			}
		}

		/** @shortdesc logfile initiation
		  * @private
		  **/
		function logfile_init($match)
		{
			if($this->logfilehdl) return;
			switch($this->debugoutput)
			{
				case 0:			// NO LOG OPERATIONS
				case 1:			// only SCREEN OUTPUT TO BROWSER
				case 2:			// only SCREEN OUTPUT TO CONSOLEWINDOW
				case 3:			// only SILENT OUTPUT (<!-- -->) TO BROWSER
				case 4:			// OUTPUT TO WINBINDER-OBJECT
				break;
				case 5: 		// only FILE OUTPUT
				case 6: 		// FILE OUTPUT + SCREEN OUTPUT TO BROWSER
				case 7: 		// FILE OUTPUT + SCREEN OUTPUT TO CONSOLEWINDOW
				case 8: 		// FILE OUTPUT + SILENT OUTPUT (<!-- -->) TO BROWSER
				case 9: 		// FILE OUTPUT + OUTPUT TO WINBINDER-OBJECT
				$d = getdate(gmmktime());
				$this->msg = $this->lf_separator."### ".date("d.m.Y - H:i:s")." START LOGGING ###".$this->lf_separator.$this->msg;
				$this->logfile = $this->logfile . "_" . $d["mon"] . "-" . $d["year"] . ".txt";
				$this->logfilehdl = @fopen($this->logfile,'a+');
				if($this->logfilehdl===FALSE)
				{
					// Fallback to Debug-Output-Mode without Filewriting
					$this->debugoutput -= 5;
					$argh = "ERROR! UNABLE TO OPEN SPECIFIED LOG FILE ".basename($this->logfile).$this->lf_separator."- Fallback to Debug-Output-Mode without Filewriting (".(int)$this->debugoutput.")";
					if($this->debugoutput == 0)
						echo "<!-- $argh -->";
					else
						$this->msg .= $this->lf_separator.$argh;
				}
				else
				{
					$this->runOnShutdown();
					$this->dbgtimer =& new timer();
					$this->dbgtimer->timer_start();
					$this->msg .= $this->lf_separator.'- start timer';
				}
				break;
			}
		}


		/** @shortdesc logfile close
		  * @private
		  **/
		function logfile_close()
		{
			// If we've opened a file to log operations, we need to close it
			if(isset($this->logfilehdl) && is_resource($this->logfilehdl))
			{
				$msg = $this->msg.$this->lf_separator."### ".date("d/m/Y - H:i:s")." STOP LOGGING (Script execution time: ".$this->friendly_timer_str($this->dbgtimer->timer_get_current()).") ###".$this->lf_separator;
				fwrite($this->logfilehdl,$msg);
				fclose($this->logfilehdl);
				unset($this->logfilehdl);
			}
		}


		/** Very useful func for debugging purposes.
          * Slightly modified to suite the needs of my class.
          *
          * Original script:
          * @author: Stefan Eickhoff, URL: http://selfaktuell.teamone.de/tippstricks/php/variablen/index.htm
          *
		  * @shortdesc Func to output a better vardump. $OutputMode: 1=Browser; 2=Commandline-Window; 3=StringVar; 4=file;
		  * @public
		  **/
		function my_var_dump($v,$OutputMode=2,$fn="")
		{
	        // Ausgabe von var_dump über Output-Buffer in Variable einlesen
			ob_start();
		    var_dump($v);
			$content = ob_get_contents();
			ob_end_clean();

	        // maximale Einrueckung ermitteln
	        $m = 0;
	        preg_match_all('#^(.*)=>#mU', $content, $stack);
	        $lines = $stack[1];
	        $indents = array_map('strlen', $lines);
			if($indents) $m = max($indents) + 1;

	        // Ausgabe von var_dump() an maximaler Einrueckung ausrichten
			$content = preg_replace('#^(.*)=>\\n\s+(\S)#eUm', '"\\1" .str_repeat(" ", $m - strlen("\\1")>1 ? $m - strlen("\\1") : 1). "\\2"', $content);

	        // bei Array-Strukturen oeffnende Klammer { in neue Zeile
			$content = preg_replace('#^((\s*).*){$#m', "\\1\n\\2{", $content);

			// pre tags entfernen
			$content = str_replace(array('<pre>','</pre>'),'',$content);

			switch($OutputMode)
			{
				case 1:
					// Output to Browser-Window
					echo '<pre style=" margin: 10px 10px 10px; padding: 10px 10px 10px 10px; background-color:#F2F2F2; color:#000; border: 1px solid #333; font-family: Lucida Console, Courier, monospace; font-size : 12px; overflow: visible;">'.$content.'</pre>';
					break;
				case 2:
					// Output to Commandline-Window or to Browser as hidden comment
					echo isset($_SERVER['HTTP_HOST']) ? "\n<!--\n".$content."\n-->\n" : $content."\n";
					break;
				case 3:
					// Output into a StringVar
					return $content;
					break;
				case 4:
					// Output into a file, if a valid filename is given and we have write access to it
					$fp = @fopen($fn, "a");
					if($fp===FALSE) return FALSE;
					fputs($fp, str_replace(array('&gt;','&quot;','&#10;'), array('>','"',''), strip_tags($content)));
					fclose($fp);
					return TRUE;
			}
		}






	/////////////////////////////////////////////
	//	COMMANDLINE-UTILS


		/**
		  * @shortdesc returns the commandline arguments from argv in an array without the scriptfilename ($argv[0])
          * @public
          *
          **/
		function ClArgs2Array()
		{
			$values = array();
			for($i=1;$i<$GLOBALS['argc'];$i++)
			{
				$values[$i] = strip_tags(trim($GLOBALS['argv'][$i]));
			}
			return $values;
		}


		/**
		  * $name = cl_ask("Question yes/no ?  + ENTER");
          *
		  * @shortdesc
          * @public
          *
          **/
		function cl_ask($q,$length='255')
		{
			echo "\n".$q."\n";
			$StdinPointer = fopen("php://stdin","r");
			$input = fgets($StdinPointer, $length);
			fclose($StdinPointer);
			unset($StdinPointer);
			return trim($input);
		}



	/////////////////////////////////////////////
	//	PHP-CONFIG + SYSINFOS

		/**
		  * @shortdesc checks if the script runs on a windows system
		  * @public
		  * @type bool
		  * @return bool
          *
		  **/
		function isWin()
		{
			return preg_match("/^Windows/",php_uname()) ? TRUE : FALSE;
		}


		/**
		  * @shortdesc checks if a file is in a folder of systempath. $file must be a basename.
		  * @public
		  * @type bool
		  * @return bool
          *
		  **/
		function isInSyspath($file,$returnpath=FALSE)
		{
			$a = explode(';',getenv('PATH'));
			foreach($a as $path)
			{
				if(file_exists($this->hn_BuildFolderStr($path).$file))
				{
					return $returnpath ? $path : TRUE;
				}
			}
			return FALSE;
		}



	/////////////////////////////////////////////
	//	STRINGS


		/////////////////////////////////////////////
		//	BASIC STRING-PROCESSING

			/**
			  * @shortdesc changes Linebreaks into a defined string/char, default is a space
			  * @public
			  *
			  **/
			function nlReplace($string,$replace=' ')
			{
				return preg_replace('/\r\n|\r|\n/iS', $replace, $string);
			}

			/**
			  * @shortdesc does the opposite of nl2br
			  * @public
			  *
			  **/
			function br2nl($str)
			{
				return preg_replace("=<br(>|([\s/][^>]*)>)\r?\n?=i", "\n", $str);
			}


		/////////////////////////////////////////////
		//	STRINGS with DATE + TIME

			/** $s is something like "Mar 30 19:54"; or "Oct  1  2003"
			  *
			  * @shortdesc converts Date/Time-String from a FTP-RAW-List to a Unix-Timestamp
			  * @public
			  *
			  **/
			function date_ftpraw2timestamp($s)
			{
				$month = array();
				for($i=1;$i<=12;$i++) $month[date('M', mktime(5,5,5,$i,7))] = $i;

				$d = split(' +',$s);
				if(count($d)==3)
				{
					$M = $month[$d[0]];
					$t = split(':',$d[2]);
					if(count($t)==2)
					{
						return mktime($t[0],$t[1],0,$M,$d[1]);
					}
					else
					{
						return mktime(0,0,0,$M,$d[1],$d[2]);
					}
				}
			}

			/**
			  * @shortdesc converts seconds (int) to a human readable time (string)
			  * @public
			  *
			  **/
			function friendly_timer_str($seconds,$lang='en')
			{
				$en = array();
					$en[1] = " seconds";
					$en[2] = " minutes";
					$en[3] = " hours";
				$de = array();
					$de[1] = " Sekunden";
					$de[2] = " Minuten";
					$de[3] = " Stunden";

				if($lang==='de') $ext = $de;
				else $ext = $en;

				$seconds = (int)$seconds;
				$s = "";
				if($seconds <= (2*86400))
				{
					if($seconds <= 180 && $seconds >= 0)
					{
						if(round($seconds,3) > 0.0009)
						{
							$s = strval(round($seconds,3)) . " seconds";
						}
						else
						{
							$s = strval($seconds) . " seconds";
						}
					}
					else
					{
						$i			= 0;
						while($seconds >= pow(60,$i)) :
							$new_size = round($seconds / pow(60,$i),2);
							$i++;
						endwhile;
						$s = $new_size . $ext[$i];
					}
				}
				else
				{
					$s = strval(round(($seconds / 86400),1)) . " days";
				}
				return str_replace(".", ",", $s);
			}


		/////////////////////////////////////////////
		//	STRINGS with FILES & DIRs & URI's/URL's


			/** A Network-Resource like //MACHINE/Resource does not return TRUE when checking with 'is_dir' (on Windows)
              *
			  * @shortdesc checks if a given string is a directory on local machine or in local network
			  * @public
			  *
			  **/
			function hn_is_dir($dir)
			{
				$dir = $this->noTrailingSlash($dir);
				// checken ob der uebergebene string ein Dir ist auf dem lokalen Rechner, ...
				if(is_dir($dir))
					return TRUE;
				// ... oder im lokalen Netzwerk
				$hdl = @opendir($dir);
				if($hdl!== FALSE) {
					closedir($hdl);
					return TRUE;
				}
				return FALSE;
			}


			function noTrailingSlash($dir)
			{
				$dir = $this->noBacks($dir);
				return substr($dir,strlen($dir)-1,1)=='/' ? substr($dir,0,strlen($dir)-1) : $dir;
			}

			/** Some directory- and file-funcs in some (not all) PHP-Versions on Windows have backslashes in their returns,
			  * also if you pass only strings with forwardslashes!
			  * I use this func to correct this behave.
              *
			  * @shortdesc corrects BackSlashes to ForwardSlashes
			  * @public
			  *
			  **/
			function noBacks($PathStr)
			{
				return str_replace("\\","/",$PathStr);
			}


			/**
			  * @shortdesc concatenates 2 strings and/or add a trailing slash if needed
			  * @public
			  *
			  **/
			function hn_BuildFolderStr($Folder,$Subfolder="")
			{
				$Folder = $this->noBacks($Folder);
				$lastChar = substr($Folder,strlen($Folder)-1,1);
				$Folder .= $lastChar <> "/" ? "/" : "";
				if(trim($Subfolder) != "")
				{
					$Subfolder = $this->noBacks($Subfolder);
					$lastChar = substr($Subfolder,strlen($Subfolder)-1,1);
					$Subfolder .= $lastChar <> "/" ? "/" : "";
				}
				return $Folder.$Subfolder;
			}


			/**
			  * @shortdesc return the extension of a file (or only a given string)
			  * @public
			  *
			  **/
			function extension($file,$OnlyCheckString=FALSE)
			{
				if($OnlyCheckString)
				{
					return substr(strrchr(basename($file),'.'),1);
				}
				if(!file_exists($file))
				{
					return FALSE;
				}
				$fileInfo = pathinfo($file);
				if(isset($fileInfo['extension']))
				{
					return strlen(trim($fileInfo['extension'])) > 0 ? $fileInfo['extension'] : '';
				}
				else
				{
					return '';
				}
			}


			/**
			  * @shortdesc returns the last subfolder from a given dir-string
			  * @public
			  *
			  **/
			function LastPathsegment($Pathname,$returnPathWithout)
			{
				$Pathname = $this->nobacks(trim($Pathname));
				if(trim($Pathname) == '/') return trim($Pathname);
				if(strrchr(trim($Pathname),'/')==="/") $Pathname = substr(trim($Pathname),0,strlen(trim($Pathname))-1);
				$PathSegments = split('/',$this->nobacks(dirname(trim($Pathname))));
				//echo "<br>Lastpathsegment of $Pathname is ".end($PathSegments)."<br>";
				return end($PathSegments);
			}



			/** in some (not all) PHP-Versions on Windows some (not all) dir-funcs return lowercase-chars for uppercase-chars, :(
			  *
			  * @shortdesc converts a pathstring to an absolute URL-string, if the directory is in servers DocRoot
			  * @public
			  *
			  **/
			function path2url($fullpathfilename)
			{
				$a = $this->isWin() ? strtolower(substr($fullpathfilename,0,strlen($_SERVER['DOCUMENT_ROOT']))) : substr($fullpathfilename,0,strlen($_SERVER['DOCUMENT_ROOT']));
				$b = $this->isWin() ? strtolower($_SERVER['DOCUMENT_ROOT']) : $_SERVER['DOCUMENT_ROOT'];
				if($a == $b)
				{
					if(is_file($fullpathfilename))
					{
						$d = substr(dirname($fullpathfilename), strlen($_SERVER['DOCUMENT_ROOT']));
						return $this->hn_BuildFolderStr($this->noBacks($d)).basename($fullpathfilename);
					}
					elseif(is_dir($fullpathfilename))
					{
						$s = substr($fullpathfilename, strlen($_SERVER['DOCUMENT_ROOT']));
						return $this->hn_BuildFolderStr($this->noBacks($s));
					}
				}
				else
				{
					return FALSE;
				}
			}


			/**
			  * @shortdesc converts a filesize from (int) bytes into a (for human better readable) string
			  * @public
			  *
			  **/
			function friendly_filesize($file_size)
			{
				$j = 0;
				$ext = array(""," B"," KB"," MB"," GB"," TB");
				while($file_size >= pow(1024,$j)) $j++;
				$file_size = round($file_size / pow(1024,$j-1) * 100) / 100 . $ext[$j];
				return str_replace(".", ",", $file_size);
			}



	/////////////////////////////////////////////
	//	TEXT-FILE-PROCESSING


		/** @shortdesc creates an otl-file (*.otl), readable with e.g. NoteTab. It needs the Fullpathfilename with or without extension, and an array with keys = headingname and values = content
		  * @public
		  **/
		function make_otl_file($fullpath,$contentarray,$sorting=FALSE)
		{
			if(strtolower($this->extension($fullpath,TRUE))!='otl') $fullpath .= '.otl';
			$content = $sorting ? "= V4 Outline MultiLine TabWidth=30\r\n\r\n" : "= V4 Outline MultiLine NoSorting TabWidth=30\r\n\r\n";
			foreach($contentarray as $k=>$v)
			{
				$content .= "H=\"$k\"\r\n$v\r\n\r\n";
			}
			return $this->string2file($content,$fullpath) ? $fullpath : FALSE;
		}


		/** @shortdesc opens a file, processes str_replace on the content and save the new content to same file
		  * @public
		  **/
		function file_str_Replace($search,$replace,$filename)
		{
			//$this->string2file(str_replace($search,$replace,$this->file2string($filename)),$filename);
            // OneLiner der aber immer speichert, und somit auch Datei-lastmodified ändert wenn nichts geändert wurde
			$s1 = $this->file2string($filename);
			$s2 = str_replace($search,$replace,$s1);
			$same = strpos($s1,$s2);
			if($same===FALSE)
			{
				return $this->string2file($s2,$filename);
			}
			elseif($same===0)
			{
				return TRUE;
			}
			else
			{
				return FALSE;
			}
		}


		/** @shortdesc opens a file, processes preg_replace on the content and save the new content to file
		  * @public
		  **/
		function file_preg_Replace($pattern,$replace,$filename)
		{
			//$this->string2file(preg_replace($pattern,$replace,$this->file2string($filename)),$filename);
			$s1 = $this->file2string($filename);
			$s2 = preg_replace($pattern,$replace,$s1);
			$same = strpos($s1,$s2);
			if($same===FALSE)
			{
				return $this->string2file($filename);
			}
			elseif($same===0)
			{
				return TRUE;
			}
			else
			{
				return FALSE;
			}
		}


		/** @shortdesc reads a file into a stringvar
		  * @public
		  **/
		function file2string($filename,$readmode="rb")
		{
			if(!is_file($filename) || !is_readable($filename))
			{
				$this->msg = 'ERROR: NO (readable) FILE:  $hn_basic->file2string('.$filename.')';
				$this->debug('error,hn_basic,file');
				return FALSE;
			}
			$fp = @fopen($filename, $readmode);
			if($fp===FALSE)
			{
				$this->msg = 'ERROR: NO STREAM:  $hn_basic->file2string('.$filename.')';
				$this->debug('error,hn_basic,file');
				return FALSE;
			}
			$size = @filesize($filename);
			clearstatcache();
			if($size<=0)
			{
				@fclose($fp);
				return '';
			}
			$s = @fread($fp, $size);
			@fclose($fp);
			return $s;
		}
		/* ALTERNATIVE:
						function file2string($filename,$readmode='rb')
						{
							if(!is_file($filename) || !is_readable($filename))
							{
								$this->msg = 'ERROR: NO (readable) FILE:  $hn_basic->file2string('.$filename.')';
								$this->debug('error,hn_basic,file');
								return FALSE;
							}
							if(@filesize($filename)<=0)
							{
								clearstatcache();
								return '';
							}
							clearstatcache();
							$fp = @fopen($filename, $readmode);
							if($fp===FALSE)
							{
								$this->msg = 'ERROR: NO STREAM:  $hn_basic->file2string('.$filename.')';
								$this->debug('error,hn_basic,file');
								return FALSE;
							}
							$s = '';
							while(!feof($fp))
							{
							   $s .= @fgets($fp, 4096);
							}
							@fclose($fp);
							return $s;
						}
		 */


		/** @shortdesc reads a file line by line into a string-array
		  * @public
		  **/
		function file2array($filename,$KeepLineEndings=FALSE)
		{
				if(!is_file($filename) || !is_readable($filename))
				{
					$this->msg = 'ERROR: NO FILE:  $hn_basic->file2array('.$filename.')';
					$this->debug('error,hn_basic,file');
					return FALSE;
				}
			if($KeepLineEndings)
			{
				return @file($filename);
			}
			else
			{
				$t = @file($filename);
				foreach($t as $k=>$v)
				{
					$t[$k] = trim($v);
				}
				return $t;
				#$s = $this->file2string($filename);
				#$s = preg_replace('/[\r\n|\n|\r]/',chr(10),$s);
				#return explode(chr(10),$s);
			}
		}

		/** @shortdesc safes a string to a file
		  * @public
		  **/
		function string2file($s,$filename,$APPEND=FALSE,$BINARY=TRUE)
		{
				if($APPEND && (!is_file($filename) || !is_writable($filename))) @touch($filename);
				if($APPEND && (!is_file($filename) || !is_writable($filename)))
				{
					$this->msg = 'ERROR: APPEND $hn_basic->string2file('.$filename.')';
					$this->debug('error,hn_basic,file');
					return FALSE;
				}
			$mode = $APPEND ? 'a' : 'w';
			$mode = $BINARY ? $mode.'b' : $mode;
			$fp = @fopen($filename, $mode);
			if($fp===FALSE)
			{
				$this->msg = 'ERROR: NO STREAM: $hn_basic->string2file($s,'.$filename.')';
				$this->debug('error,hn_basic,file');
				return FALSE;
			}
			fwrite($fp,$s);
			fclose($fp);
			return TRUE;
		}

		/** @shortdesc safes a string-Array to a file
		  * @public
		  **/
		function array2file($a,$filename,$APPEND=FALSE,$BINARY=TRUE)
		{
			$linebreak = $this->isWin() ? "\r\n" : "\n";
			$s = join($linebreak,$a);
			return $this->string2file($s,$filename,$APPEND,$BINARY);
		}



		/** @shortdesc reads a gzcompressed file into a (uncompressed) stringvar
		  * @public
		  **/
		function gzfile2string($filename,$readmode='rb')
		{
				if(!is_file($filename) || !is_readable($filename))
				{
					$this->msg = 'ERROR: NO (readable) FILE:  $hn_basic->gzfile2string('.$filename.')';
					$this->debug('error,hn_basic,file');
					return FALSE;
				}
			$fp = @gzopen($filename, $readmode);
			if($fp===FALSE)
			{
				$this->msg = 'ERROR: NO STREAM:  $hn_basic->gzfile2string('.$filename.')';
				$this->debug('error,hn_basic,file');
				return FALSE;
			}
			$s = '';
			while(!gzeof($fp)) $s .= gzread($fp, 1024);
			gzclose($fp);
			return $s;
		}

		/** @shortdesc reads a gzcompressed file line by line into a (uncompressed) string-array
		  * @public
		  **/
		function gzfile2array($filename)
		{
				if(!is_file($filename) || !is_readable($filename))
				{
					$this->msg = 'ERROR: NO FILE:  $hn_basic->file2array('.$filename.')';
					$this->debug('error,hn_basic,file');
					return FALSE;
				}
			return @gzfile($filename);
		}

		/** @shortdesc safes a string to a gzcompressed file
		  * @public
		  **/
		function string2gzfile($s,$filename,$complevel=FALSE)
		{
			$fp = @gzopen($filename, 'wb'.$complevel);
			if($fp===FALSE)
			{
				$this->msg = 'ERROR: NO STREAM:  $hn_basic->string2gzfile('.$filename.')';
				$this->debug('error,hn_basic,file');
				return FALSE;
			}
			gzwrite($fp, $s);
			gzclose($fp);
			return TRUE;
		}

		/** @shortdesc safes a string-Array to a gzcompressed file
		  * @public
		  **/
		function array2gzfile($a,$filename,$complevel=FALSE)
		{
			$s = implode('',$a);
			return $this->string2gzfile($s,$filename,$complevel);
		}



		/** @shortdesc Sets all Lineendings of a given local file to CRLF or LF depending on the OS
		  * @public
		  **/
		function correctlineendings($filename)
		{
		}



	/////////////////////////////////////////////
	//	ARRAYS

		// ARRAY-SORTING

			// by values:

				/** Sorts the values of a given multidimensional Array in hirarchical order of the sortlist
				  *
				  * @shortdesc USAGE: $SORTED_Array = hn_array_sort($orig_array, array('field3','field1','field2'));
				  * @public
				  *
				  **/
				function hn_array_sort($a,$sl)
				{
					$GLOBALS['__HN_SORTVALUE_LIST__'] = $sl;
					usort($a, array(&$this, 'hn_sortValue_func'));
					return $a;
				}
					// Callback-func for hn_array_sort()
					/** @private **/
					function hn_sortValue_func($a,$b)
					{
						foreach($GLOBALS['__HN_SORTVALUE_LIST__'] as $f)
						{
							$strc = strcmp($a[$f],$b[$f]);
							if($strc != 0) return $strc;
						}
						return 0;
					}

            // by keys:

				/** Sorts the keys of a given Array.
				  * USAGE: $SORTED_Array = hn_arrayKey_sort($orig_array [, TRUE | FALSE ]);
				  *
				  * @shortdesc Sorts a multidimensional array
				  * @private
				  *
				  **/
				function hn_arrayKey_sort($a,$descending=FALSE)
				{
					$GLOBALS['__HN_SORTKEY_LIST__'] = (bool)$descending;
					uksort($a, array(&$this, 'hn_sortKey_func'));
					return $a;
				}
					/**
					  * @shortdesc Callback-func for hn_arrayKey_sort()
					  * @private
					  *
					  **/
					function hn_sortKey_func($a,$b)
					{
						if((int)$a == (int)$b) return 0;
						if((bool)$GLOBALS['__HN_SORTKEY_LIST__'])
						{
							return ((int)$a > (int)$b) ? -1 : 1;
						}
						else
						{
							return ((int)$a > (int)$b) ? 1 : -1;
						}
					}


			/**
			  * @shortdesc returns one or more random entries from a given array
			  * @public
              * @type array
              * @return array with random selection
			  *
			  **/
			function Random_MultiDimArray_Items(&$Array,$ReturnedItems=1)
			{
				$RandomSelection = array();
				if(count($Array) > $ReturnedItems)
				{
					srand((double)microtime() * 10000000);
					if($ReturnedItems < 2)
					{
						$pickOne = array_rand($Array, 1);
						$RandomSelection = $Array[$pickOne];
					}
					else
					{
						$picksome = array_rand($Array, $ReturnedItems);
						foreach($picksome as $v)
						{
							$RandomSelection[$v] = $Array[$v];
						}
					}
				}
				else
				{
					$RandomSelection = $Array;
				}
				return $RandomSelection;
			}



			/**
			  * @shortdesc returns one or more random entries from a given array
			  * @public
              * @type array
              * @return array with random selection
			  *
			  **/
			function RandomArrayItems($Array_input,$ReturnedItems=1)
			{
				if(count($Array_input) == $ReturnedItems)
				{
					return $Array_input;
				}
				$ReturnedItems -= 1;
				$Array_output = array();
				mt_srand((double) microtime() * 1000000);
				for($i=0; $i<=$ReturnedItems; $i++)
				{
					$Array_output[] = $Array_input[mt_rand(0, count($Array_input)-1)];
				}
				return $Array_output;
			}
				#	srand((double)microtime() * 10000000);
				#	if($ReturnedItems < 2)
				#	{
				#		$pickOne = array_rand($Array, 1);
				#		$RandomSelection = $Array[$pickOne];
				#	}
				#	else
				#	{
				#		$picksome = array_rand($Array, $ReturnedItems);
				#		foreach($picksome as $v)
				#		{
				#			$RandomSelection[$v] = $Array[$v];
				#		}
				#	}
				#}
				#else
				#{
				#	$RandomSelection = $Array;
				#}
				#return $RandomSelection;
				#


	/////////////////////////////////////////////
	//	CACHING & ARRAYS


		/////////////////////////////////////////////
		//	Arrays und Objekte per un/serialize speichern/lesen.

			/**
			  * @shortdesc filles a given Array with Values from a (serialized) cachefile
			  * @public
              * @return TRUE, if an array could build, means if the file was available and it'S data was successfully read
			  *
			  **/
			function GetCacheArray(&$Array,$filename)
			{
				$s = $this->file2string($filename);
				if(trim($s)=='') return FALSE;
				$Array = unserialize($s);
				return is_array($Array);
			}

			/**
			  * @shortdesc writes (serialized) data of a given Array into a cachefile
			  * @public
              * @return TRUE, if the file was build
			  *
			  **/
			function SetCacheArray(&$Array,$filename)
			{
				$cache_data = serialize($Array);
				return $this->string2file($cache_data,$filename);
			}


		/////////////////////////////////////////////
		//	OUTPUT-BUFFERING

			/**
			  * @shortdesc starts an outputbuffer and otionally sends HTTP-headers to avoid caching the data by browsers / proxies
			  * @public
			  *
			  **/
			function start_output($HeadersNoCache=FALSE)
			{
				// Output-Buffering starten
				ob_start();
				ob_implicit_flush(0);

				// Header gegen uebereifrige Caches senden
				if(!headers_sent() && $HeadersNoCache)
				{
					header ("expires: Sun, 06 Jan 2002 01:00:00 GMT");                 // Datum in der Vergangenheit
					header ("Last-Modified: " . gmdate ("D, d M Y H:i:s") . " GMT");   // immer geaendert
					header ("pragma: no-cache");                                       // HTTP/1.0
					header ("Cache-Control: no-cache, must-revalidate");               // HTTP/1.1
				}
			}


			/**
			  * @shortdesc stops outputbuffering and return buffer as string or otionally flush it with gzip-compression
			  * @public
			  *
			  **/
			function end_output($compress=false)
			{
				// Output-Buffering beenden
				$contents = ob_get_contents();
				ob_end_clean();

				if($compress && ereg('gzip',$_SERVER["HTTP_ACCEPT_ENCODING"]))
				{
					// Browser will komprimierte Daten geliefert bekommen
					header ("Content-Encoding: gzip");         // Content-Encoding senden (damit der Browser was merkt)
					echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";   // hmm, gzip-start?
					$Size = strlen($contents);                 // Grösse bestimmen
					$Crc = crc32($contents);                   // Checksumme bestimmen
					$contents = gzcompress($contents, 9);      // Komprimieren
					$contents = substr($contents, 0, strlen($contents) - 4); // letzte 4 Bytes abschneiden
					echo $contents;                            // komprimiertes Zeugs ausgeben
					gzip_PrintFourChars($Crc);                 // Checksumme ausgeben
					gzip_PrintFourChars($Size);                // Größe ausgeben
				}
				else
				{
					return $contents;                          // Inhalt unkomprimiert zurueckgeben
				}
			}





	/////////////////////////////////////////////
	//	SONSTIGES



		/////////////////////////////////////////////
		//	COUNTER with TEXTFILE

			/**
			  * @shortdesc Store/Retrieve a counter-value in/from a textfile. Optionally count it up or store a, in third param specified, value.
			  * @public
			  * @type integer
			  * @return counter-value or FALSE
			  *
			  **/
			function txt_counter($filename,$add=FALSE,$fixvalue=FALSE)
			{
				if(is_file($filename) ? TRUE : @touch($filename))
				{
					if(is_readable($filename) && is_writable($filename))
					{
						$orig_abo = ignore_user_abort(true);
	// hier muss noch ein flock() hin !!
						$fp = @fopen($filename, "r");
						if($fp !== FALSE)
						{
							$counter = (int)trim(fgets($fp));
							fclose($fp);

							if($add)
							{
								if($fixvalue !== FALSE)
								{
									$counter = (int)$fixvalue;
								}
								else
								{
									$counter++;
								}
								$fp = @fopen($filename, "w");
								if($fp !== FALSE)
								{
									fputs($fp,$counter);
									fclose($fp);
									ignore_user_abort($orig_abo);
									return $counter;
								}
								else return FALSE;
							}
							else
							{
								ignore_user_abort($orig_abo);
								return $counter;
							}
						}
						else
						{
							ignore_user_abort($orig_abo);
							return FALSE;
						}
					}
					else return FALSE;
				}
				else return FALSE;
			}


			/**
			  * @shortdesc Test against all relevant needs of txt_counter-func for a given filename.
			  * @public
			  * @type boolean
			  * @return TRUE or FALSE
			  *
			  **/
			function txt_counter_check($counter_filename)
			{
				// retrieve current counter-value
				$old = $this->txt_counter($counter_filename);
				if($old===FALSE)
				{
					return FALSE;
				}
				// Count up one and retrieve new counter-value
				$new = $this->txt_counter($counter_filename,TRUE);
				// check if counter works correct
				if(($new !== FALSE) && ($new - $old == 1))
				{
					return $this->txt_counter($counter_filename,TRUE,$old) !== FALSE ? TRUE : FALSE;
				}
				else
				{
					return FALSE;
				}
			}

	// some more little helpers

		/**
		 * This script is supposed to be used together with the HTML2FPDF.php class
		 * Copyright (C) 2004-2005 Renato Coelho
		 *
		 * returns an associative array (keys: R,G,B) from html code (e.g. #3FE5AA)
		 **/
		function ConvertColor($color="#000000")
		{
			//W3C approved color array (disabled)
			//static $common_colors = array('black'=>'#000000','silver'=>'#C0C0C0','gray'=>'#808080', 'white'=>'#FFFFFF','maroon'=>'#800000','red'=>'#FF0000','purple'=>'#800080','fuchsia'=>'#FF00FF','green'=>'#008000','lime'=>'#00FF00','olive'=>'#808000','yellow'=>'#FFFF00','navy'=>'#000080', 'blue'=>'#0000FF','teal'=>'#008080','aqua'=>'#00FFFF');
			//All color names array
			static $common_colors = array('antiquewhite'=>'#FAEBD7','aquamarine'=>'#7FFFD4','beige'=>'#F5F5DC','black'=>'#000000','blue'=>'#0000FF','brown'=>'#A52A2A','cadetblue'=>'#5F9EA0','chocolate'=>'#D2691E','cornflowerblue'=>'#6495ED','crimson'=>'#DC143C','darkblue'=>'#00008B','darkgoldenrod'=>'#B8860B','darkgreen'=>'#006400','darkmagenta'=>'#8B008B','darkorange'=>'#FF8C00','darkred'=>'#8B0000','darkseagreen'=>'#8FBC8F','darkslategray'=>'#2F4F4F','darkviolet'=>'#9400D3','deepskyblue'=>'#00BFFF','dodgerblue'=>'#1E90FF','firebrick'=>'#B22222','forestgreen'=>'#228B22','gainsboro'=>'#DCDCDC','gold'=>'#FFD700','gray'=>'#808080','green'=>'#008000','greenyellow'=>'#ADFF2F','hotpink'=>'#FF69B4','indigo'=>'#4B0082','khaki'=>'#F0E68C','lavenderblush'=>'#FFF0F5','lemonchiffon'=>'#FFFACD','lightcoral'=>'#F08080','lightgoldenrodyellow'=>'#FAFAD2','lightgreen'=>'#90EE90','lightsalmon'=>'#FFA07A','lightskyblue'=>'#87CEFA','lightslategray'=>'#778899','lightyellow'=>'#FFFFE0','limegreen'=>'#32CD32','magenta'=>'#FF00FF','mediumaquamarine'=>'#66CDAA','mediumorchid'=>'#BA55D3','mediumseagreen'=>'#3CB371','mediumspringgreen'=>'#00FA9A','mediumvioletred'=>'#C71585','mintcream'=>'#F5FFFA','moccasin'=>'#FFE4B5','navy'=>'#000080','olive'=>'#808000','orange'=>'#FFA500','orchid'=>'#DA70D6','palegreen'=>'#98FB98','palevioletred'=>'#D87093','peachpuff'=>'#FFDAB9','pink'=>'#FFC0CB','powderblue'=>'#B0E0E6','red'=>'#FF0000','royalblue'=>'#4169E1','salmon'=>'#FA8072','seagreen'=>'#2E8B57','sienna'=>'#A0522D','skyblue'=>'#87CEEB','slategray'=>'#708090','springgreen'=>'#00FF7F','tan'=>'#D2B48C','thistle'=>'#D8BFD8','turquoise'=>'#40E0D0','violetred'=>'#D02090','white'=>'#FFFFFF','yellow'=>'#FFFF00');
			//http://www.w3schools.com/css/css_colornames.asp
			if ( ($color{0} != '#') and ( strstr($color,'(') === false ) ) $color = $common_colors[strtolower($color)];

			if ($color{0} == '#') //case of #nnnnnn or #nnn
			{
				$cor = strtoupper($color);
				if (strlen($cor) == 4) // Turn #RGB into #RRGGBB
				{
					$cor = "#" . $cor{1} . $cor{1} . $cor{2} . $cor{2} . $cor{3} . $cor{3};
				}
				$R = substr($cor, 1, 2);
				$vermelho = hexdec($R);
				$V = substr($cor, 3, 2);
				$verde = hexdec($V);
				$B = substr($cor, 5, 2);
				$azul = hexdec($B);
				$color = array();
				$color['R']=$vermelho;
				$color['G']=$verde;
				$color['B']=$azul;
			}
			else //case of RGB(r,g,b)
			{
				$color = str_replace(array("rgb(","RGB(",")"),'',$color); //remove ´rgb(´ and ')'
				#$color = str_replace(")",'',$color); //remove ´)´
				$cores = explode(",", $color);
				$color = array();
				$color['R']=$cores[0];
				$color['G']=$cores[1];
				$color['B']=$cores[2];
			}
			if (empty($color)) return array('R'=>255,'G'=>255,'B'=>255);
			else return $color; // array['R']['G']['B']
		}

		/**
		 * Depends of maxsize value to make % work properly. Usually maxsize == pagewidth
		 *
		 **/
		function ConvertSize($size=5,$maxsize=0)
		{
			//Identify size (remember: we are using 'mm' units here)
			if ( stristr($size,'px') ) $size *= 0.2645; //pixels
			elseif ( stristr($size,'cm') ) $size *= 10; //centimeters
			elseif ( stristr($size,'mm') ) $size += 0; //millimeters
			elseif ( stristr($size,'in') ) $size *= 25.4; //inches
			elseif ( stristr($size,'pc') ) $size *= 38.1/9; //PostScript picas
			elseif ( stristr($size,'pt') ) $size *= 25.4/72; //72dpi
			elseif ( stristr($size,'%') )
			{
				$size += 0; //make "90%" become simply "90"
				$size *= $maxsize/100;
			}
			else $size *= 0.2645; //nothing == px

			return $size;
		}



	// STRINGS

		function txtentities($html)
		{
			$trans = get_html_translation_table(HTML_ENTITIES);
			$trans = array_flip($trans);
			return strtr($html, $trans);
		}

} // end class hn_basic




/**
  * @shortdesc Stack: First In - Last Out
  * @private
  * @author unknown
  *
  **/
class filo
{

	/** @private **/
	var $elements;
	/** @private **/
	var $debug;

	/** @private **/
	function filo($debug=FALSE)
	{
		$this->debug = $debug;
		$this->zero();
	}

	/** @private **/
	function push( $elm )
	{
		array_push( $this->elements, $elm );
		if($this->debug) echo "<p>filo->push(".$elm.")</p>";
	}

	/** @private **/
	function pop()
	{
		return array_pop( $this->elements );
		if($this->debug) echo "<p>filo->pop()</p>";
	}

	/** @private **/
	function zero()
	{
		$this->elements = array();
		if($this->debug) echo "<p>filo->zero()</p>";
	}

} // end class FILO



/** phpTimer: A simple script to time script execution
  * Copyright (C) 2001 Roger Raymond ~ hide@address.com
  *
  * 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
  *
  * @shortdesc little timer class
  * @private
  * @author Roger Raymond
  * @version 0.1
  * @date 2001
  **/
class timer
{
	/** @private **/
	var $version = '0.1';
	/** @private **/
	var $_enabled = FALSE;

	/** @private **/
	function timer()
	{
		$this->_enabled = true;
	}

	/** @public **/
	function timer_start($name = 'default')
	{
		if($this->_enabled)
		{
			$this->_timing_start_times[$name] = explode(' ', microtime());
		}
	}

	/** @public **/
	function timer_stop($name = 'default')
	{
		if($this->_enabled)
		{
			$this->_timing_stop_times[$name] = explode(' ', microtime());
		}
	}

	/** @public **/
	function timer_get_current($name = 'default')
	{
		if($this->_enabled)
		{
			if(!isset($this->_timing_start_times[$name]))
			{
				return 0;
			}
			if(!isset($this->_timing_stop_times[$name]))
			{
				$stop_time = explode(' ', microtime());
			}
			else
			{
				$stop_time = $this->_timing_stop_times[$name];
			}
			// do the big numbers first so the small ones aren't lost
			$current = $stop_time[1] - $this->_timing_start_times[$name][1];
			$current += $stop_time[0] - $this->_timing_start_times[$name][0];
			return sprintf("%.10f",$current);
		}
		else
		{
			return 0;
		}
	}

} // end class timer





/**
  * @shortdesc This class holds some methods to calculate Picture dimensions
  * @public
  * @author Horst Nogajski, Copyright (c) 2004
  * @version 0.8
  * @date 2004-Jun-21
  **/
class hn_SizeCalc
{

	/////////////////////////////////////////////
	//	PRIVATE PARAMS
	//
		/** @private **/
		var $a = 0;
		/** @private **/
		var $b = 0;
		/** @private **/
		var $landscape = NULL;
	//
	/////////////////////////////////////////////


	/////////////////////////////////////////////
	//	PUBLIC METHODS
	//

		/** Mit der Methode down werden Werte (falls sie groesser sind als die MaxWerte) verkleinert.
		  * Werte die kleiner sind als die MaxWerte bleiben unveraendert.
		  *
		  * @shortdesc Use this for downsizing only. Means: if the source is smaller then the max-sizes, it will not changed.
		  * @public
		  **/
		function down(&$a,&$b,$a_max,$b_max)
		{
			$this->a = 0;
			$this->b = 0;
			$this->landscape = $a >= $b ? TRUE : FALSE;
			$check = 1;
			if($a > $a_max) $check += 3;
			if($b > $b_max) $check += 2;

			switch ($check)
			{
				case 1:
					// Bild ist kleiner als max Groesse fuer a und b
					$this->b = ceil($b);
					$this->a = ceil($a);
					break;
				case 3:
					// Seite b ist groesser als max Groesse,
					// Bild wird unter beruecksichtigung des Seitenverhaeltnisses
					// auf Groesse fuer b gerechnet
					$this->b = ceil($b_max);
					$this->a = ceil($a / ($b / $this->b));
					break;
				case 4:
					// Seite a ist groesser als max Groesse,
					// Bild wird unter beruecksichtigung des Seitenverhaeltnisses
					// auf Groesse fuer a gerechnet
					$this->a = ceil($a_max);
					$this->b = ceil($b / ($a / $this->a));
					break;
				case 6:
					// BEIDE Seiten sind groesser als max Groesse,
					// Bild wird unter beruecksichtigung des Seitenverhaeltnisses
					// zuerst auf Groesse fuer a gerechnet, und wenns dann noch
					// nicht passt, nochmal fuer b. Danach passt's! ;)
					$this->a = ceil($a_max);
					$this->b = ceil($b / ($a / $this->a));
					if($this->b > $b_max)
					{
						$this->b = ceil($b_max);
						$this->a = ceil($a / ($b / $this->b));
					}
					break;
			}

			// RUECKGABE DER WERTE ERFOLGT PER REFERENCE
			$a = $this->a;
			$b = $this->b;
		}


		/** Mit der Methode up werden Werte (falls sie groesser sind als die MaxWerte) verkleinert
		  * und falls sie kleiner sind als die MaxWerte werden sie vergroessert!
		  *
		  * @shortdesc Use this for up- and downsizing. Means: if the source is graeter then the max-sizes,
		  * they become downsized, and if they are smaller then the max-sizes, they become upsized!
		  * @public
		  **/
		function up(&$a,&$b,$a_max,$b_max)
		{
			// falls das Bild zu gross ist wird es jetzt kleiner gerechnet, so das es max_a und max_b nicht ueberschreitet
			$this->down($a,$b,$a_max,$b_max);

			// reset
			$this->a = 0; // width
			$this->b = 0; // height

			//$this->landscape = $a >= $b ? TRUE : FALSE;

			// wenn jetzt a und b kleiner sind dann muss es vergroessert werden
			if($a < $a_max && $b < $b_max)
			{
				// ermitteln der prozentualen differenz vom Sollwert
				$pa = $this->_diffProzent($a,$a_max);
				$pb = $this->_diffProzent($b,$b_max);
				if($pa >= $pb)
				{
					// b auf b_max setzen
					$this->a = ceil($a * ($b_max / $b));
					$this->b = $b_max;
				}
				else
				{
					// a auf a_max setzen
					$this->b = ceil($b * ($a_max / $a));
					$this->a = $a_max;
				}
				// RUECKGABE DER WERTE ERFOLGT PER REFERENCE
				$a = $this->a;
				$b = $this->b;
				$this->down($a,$b,$a_max,$b_max);
			}
		}



		/** @public
		  * conversion pixel -> millimeter in 72 dpi
		  **/
		function px2mm($px)
		{
			return $px*25.4/72;
		}

	//
	/////////////////////////////////////////////


	/////////////////////////////////////////////
	//	PRIVATE METHODS
	//
		/** @private **/
		function _diffProzent($ist,$soll)
		{
			return (int)(($ist * 100) / $soll);
		}
	//
	/////////////////////////////////////////////


} // END CLASS hn_SizeCalc


?>
Return current item: hnwb_ListView for WinBinder