cs-content-commits Mailing List for CS-Content [Dynamic Content System] (Page 8)
PHP Templating & Includes System
Brought to you by:
crazedsanity
You can subscribe to this list here.
2009 |
Jan
(32) |
Feb
(24) |
Mar
(5) |
Apr
(1) |
May
(14) |
Jun
(16) |
Jul
(11) |
Aug
(43) |
Sep
(9) |
Oct
(5) |
Nov
(1) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2010 |
Jan
|
Feb
|
Mar
(1) |
Apr
(1) |
May
(4) |
Jun
|
Jul
(5) |
Aug
(2) |
Sep
(1) |
Oct
|
Nov
|
Dec
|
2011 |
Jan
(6) |
Feb
(3) |
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
(5) |
Aug
|
Sep
|
Oct
(2) |
Nov
(8) |
Dec
|
2012 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <cra...@us...> - 2009-01-29 22:49:19
|
Revision: 337 http://cs-content.svn.sourceforge.net/cs-content/?rev=337&view=rev Author: crazedsanity Date: 2009-01-29 21:48:59 +0000 (Thu, 29 Jan 2009) Log Message: ----------- Renamed cs_tabsClass.php to cs_tabs.class.php /contentSystem.class.php: * MAIN::: -- fixed require_once() path to cs_tabs{} /cs_tabs.class.php [RENAMED FROM cs_tabsClass.php] /cs_tabsClass.php [RENAMED TO cs_tabs.class.php] Modified Paths: -------------- trunk/1.0/contentSystem.class.php Added Paths: ----------- trunk/1.0/cs_tabs.class.php Removed Paths: ------------- trunk/1.0/cs_tabsClass.php Modified: trunk/1.0/contentSystem.class.php =================================================================== --- trunk/1.0/contentSystem.class.php 2009-01-29 21:45:51 UTC (rev 336) +++ trunk/1.0/contentSystem.class.php 2009-01-29 21:48:59 UTC (rev 337) @@ -74,7 +74,7 @@ require_once(dirname(__FILE__) ."/cs_fileSystem.class.php"); require_once(dirname(__FILE__) ."/cs_sessionClass.php"); require_once(dirname(__FILE__) ."/cs_genericPage.class.php"); -require_once(dirname(__FILE__) ."/cs_tabsClass.php"); +require_once(dirname(__FILE__) ."/cs_tabs.class.php"); class contentSystem extends cs_contentAbstract { Copied: trunk/1.0/cs_tabs.class.php (from rev 333, trunk/1.0/cs_tabsClass.php) =================================================================== --- trunk/1.0/cs_tabs.class.php (rev 0) +++ trunk/1.0/cs_tabs.class.php 2009-01-29 21:48:59 UTC (rev 337) @@ -0,0 +1,152 @@ +<?php +/* + * Created on Jan 9, 2007 + * + */ + +require_once(dirname(__FILE__) .'/abstract/cs_content.abstract.class.php'); + + +class cs_tabs extends cs_contentAbstract { + private $tabsArr; + private $selectedTab; + + private $csPageObj; + private $templateVar; + + /** Block row with the "selected" tab */ + private $selectedTabContent; + + /** Block row with the "unselected" tab */ + private $unselectedTabContent; + + //--------------------------------------------------------------------------------------------- + /** + * Build the object, and parses the given template. Tabs must be added & selected manually. + * + * @param $csPageObj (object) Instance of the class "cs_genericPage". + * @param $templateVar (str,optional) What template var to find the tab blockrows in. + */ + public function __construct(cs_genericPage $csPageObj, $templateVar="tabs") { + parent::__construct(false); + if(is_null($csPageObj) || !is_object($csPageObj) || get_class($csPageObj) !== 'cs_genericPage') { + //can't continue without that! + throw new exception("cs_tabs::__construct(): cannot load without cs_genericPage{} object (". get_class($csPageObj) .")"); + } + else { + //set it as a member. + $this->csPageObj = $csPageObj; + } + + + if(is_null($templateVar) || strlen($templateVar) < 3) { + //no template name? AHH!!! + throw new exception("cs_tabs::__construct(): failed to specify proper template file"); + } + else { + //set the internal var. + $this->templateVar = $templateVar; + } + }//end __construct() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Loads & parses the given tabs template. Requires that the given template has "selected_tab" + * and "unselected_tab" block row definitions. + * + * @param (void) + * @return (void) + */ + private function load_tabs_template() { + //now let's parse it for the proper block rows. + $blockRows = $this->csPageObj->rip_all_block_rows($this->templateVar); + + if(count($blockRows) < 2 || !isset($blockRows['selected_tab']) || !isset($blockRows['unselected_tab'])) { + //not enough blocks, or they're not properly named. + throw new exception("cs_tabs::load_tabs_template(): failed to retrieve the required block rows"); + } + else { + //got the rows. Yay! + $this->selectedTabContent = $blockRows['selected_tab']; + $this->unselectedTabContent = $blockRows['unselected_tab']; + } + }//end load_tabs_template() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + public function add_tab_array(array $tabs) { + $retval = 0; + foreach($tabs as $name=>$url) { + //call an internal method to do it. + $retval += $this->add_tab($name, $url); + } + + return($retval); + }//end add_tab_array() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Sets the given tab as selected, provided it exists. + * + * @param $tabName (str) Sets this tab as selected. + * @return (void) + */ + public function select_tab($tabName) { + $this->selectedTab = $tabName; + }//end select_tab() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + public function add_tab($tabName, $url) { + //add it to an array. + $this->tabsArr[$tabName] = $url; + }//end add_tab() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Call this to add the parsed tabs into the page. + */ + public function display_tabs() { + if(is_array($this->tabsArr) && count($this->tabsArr)) { + $this->load_tabs_template(); + $finalString = ""; + //loop through the array. + foreach($this->tabsArr as $tabName=>$url) { + $useTabContent = $this->unselectedTabContent; + if(strtolower($tabName) === strtolower($this->selectedTab)) { + //it's selected. + $useTabContent = $this->selectedTabContent; + } + $parseThis = array( + 'title' => $tabName, + 'url' => $url + ); + $finalString .= $this->csPageObj->mini_parser($useTabContent, $parseThis, '%%', '%%'); + } + + //now parse it onto the page. + $this->csPageObj->add_template_var($this->templateVar, $finalString); + } + else { + //something bombed. + throw new exception("cs_tabs::display_tabs(): no tabs to add"); + } + + }//end display_tabs() + //--------------------------------------------------------------------------------------------- + +} +?> Property changes on: trunk/1.0/cs_tabs.class.php ___________________________________________________________________ Added: svn:mergeinfo + Added: svn:eol-style + native Deleted: trunk/1.0/cs_tabsClass.php =================================================================== --- trunk/1.0/cs_tabsClass.php 2009-01-29 21:45:51 UTC (rev 336) +++ trunk/1.0/cs_tabsClass.php 2009-01-29 21:48:59 UTC (rev 337) @@ -1,152 +0,0 @@ -<?php -/* - * Created on Jan 9, 2007 - * - */ - -require_once(dirname(__FILE__) .'/abstract/cs_content.abstract.class.php'); - - -class cs_tabs extends cs_contentAbstract { - private $tabsArr; - private $selectedTab; - - private $csPageObj; - private $templateVar; - - /** Block row with the "selected" tab */ - private $selectedTabContent; - - /** Block row with the "unselected" tab */ - private $unselectedTabContent; - - //--------------------------------------------------------------------------------------------- - /** - * Build the object, and parses the given template. Tabs must be added & selected manually. - * - * @param $csPageObj (object) Instance of the class "cs_genericPage". - * @param $templateVar (str,optional) What template var to find the tab blockrows in. - */ - public function __construct(cs_genericPage $csPageObj, $templateVar="tabs") { - parent::__construct(false); - if(is_null($csPageObj) || !is_object($csPageObj) || get_class($csPageObj) !== 'cs_genericPage') { - //can't continue without that! - throw new exception("cs_tabs::__construct(): cannot load without cs_genericPage{} object (". get_class($csPageObj) .")"); - } - else { - //set it as a member. - $this->csPageObj = $csPageObj; - } - - - if(is_null($templateVar) || strlen($templateVar) < 3) { - //no template name? AHH!!! - throw new exception("cs_tabs::__construct(): failed to specify proper template file"); - } - else { - //set the internal var. - $this->templateVar = $templateVar; - } - }//end __construct() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Loads & parses the given tabs template. Requires that the given template has "selected_tab" - * and "unselected_tab" block row definitions. - * - * @param (void) - * @return (void) - */ - private function load_tabs_template() { - //now let's parse it for the proper block rows. - $blockRows = $this->csPageObj->rip_all_block_rows($this->templateVar); - - if(count($blockRows) < 2 || !isset($blockRows['selected_tab']) || !isset($blockRows['unselected_tab'])) { - //not enough blocks, or they're not properly named. - throw new exception("cs_tabs::load_tabs_template(): failed to retrieve the required block rows"); - } - else { - //got the rows. Yay! - $this->selectedTabContent = $blockRows['selected_tab']; - $this->unselectedTabContent = $blockRows['unselected_tab']; - } - }//end load_tabs_template() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - public function add_tab_array(array $tabs) { - $retval = 0; - foreach($tabs as $name=>$url) { - //call an internal method to do it. - $retval += $this->add_tab($name, $url); - } - - return($retval); - }//end add_tab_array() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Sets the given tab as selected, provided it exists. - * - * @param $tabName (str) Sets this tab as selected. - * @return (void) - */ - public function select_tab($tabName) { - $this->selectedTab = $tabName; - }//end select_tab() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - public function add_tab($tabName, $url) { - //add it to an array. - $this->tabsArr[$tabName] = $url; - }//end add_tab() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Call this to add the parsed tabs into the page. - */ - public function display_tabs() { - if(is_array($this->tabsArr) && count($this->tabsArr)) { - $this->load_tabs_template(); - $finalString = ""; - //loop through the array. - foreach($this->tabsArr as $tabName=>$url) { - $useTabContent = $this->unselectedTabContent; - if(strtolower($tabName) === strtolower($this->selectedTab)) { - //it's selected. - $useTabContent = $this->selectedTabContent; - } - $parseThis = array( - 'title' => $tabName, - 'url' => $url - ); - $finalString .= $this->csPageObj->mini_parser($useTabContent, $parseThis, '%%', '%%'); - } - - //now parse it onto the page. - $this->csPageObj->add_template_var($this->templateVar, $finalString); - } - else { - //something bombed. - throw new exception("cs_tabs::display_tabs(): no tabs to add"); - } - - }//end display_tabs() - //--------------------------------------------------------------------------------------------- - -} -?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-29 21:26:02
|
Revision: 335 http://cs-content.svn.sourceforge.net/cs-content/?rev=335&view=rev Author: crazedsanity Date: 2009-01-29 21:25:58 +0000 (Thu, 29 Jan 2009) Log Message: ----------- Renamed cs_globalFunctions.php to cs_globalFunctions.class.php. /cs_globalFunctions.php [RENAMED TO cs_globalFunctions.class.php] /cs_globalFunctions.class.php [RENAMED FROM cs_globalFunctions.php] /abstract/cs_content/abstract.class.php: * fix name of cs_globalFunctions{} file. /sample_files/public_html/index.php: * fix name of cs_globalFunctions{} file. /tests/testOfCSContent.php: * fix name of cs_globalFunctions{} file. Modified Paths: -------------- trunk/1.0/abstract/cs_content.abstract.class.php trunk/1.0/sample_files/public_html/index.php trunk/1.0/tests/testOfCSContent.php Added Paths: ----------- trunk/1.0/cs_globalFunctions.class.php Removed Paths: ------------- trunk/1.0/cs_globalFunctions.php Modified: trunk/1.0/abstract/cs_content.abstract.class.php =================================================================== --- trunk/1.0/abstract/cs_content.abstract.class.php 2009-01-29 21:15:20 UTC (rev 334) +++ trunk/1.0/abstract/cs_content.abstract.class.php 2009-01-29 21:25:58 UTC (rev 335) @@ -24,7 +24,7 @@ if($makeGfObj === true) { //make a cs_globalFunctions{} object. - require_once(dirname(__FILE__) ."/../cs_globalFunctions.php"); + require_once(dirname(__FILE__) ."/../cs_globalFunctions.class.php"); $this->gfObj = new cs_globalFunctions(); } }//end __construct() Copied: trunk/1.0/cs_globalFunctions.class.php (from rev 333, trunk/1.0/cs_globalFunctions.php) =================================================================== --- trunk/1.0/cs_globalFunctions.class.php (rev 0) +++ trunk/1.0/cs_globalFunctions.class.php 2009-01-29 21:25:58 UTC (rev 335) @@ -0,0 +1,844 @@ +<?php + +require_once(dirname(__FILE__) ."/../cs-versionparse/cs_version.abstract.class.php"); + +class cs_globalFunctions extends cs_versionAbstract { + + + /* DEBUG PRINT OPTIONS */ + /** Remove the separator below the output of each debug_print()? */ + public $debugRemoveHr = 0; + public $debugPrintOpt = 0; + + private $forceSqlQuotes=0; + private $oldForceSqlQuotes=0; + + //========================================================================= + public function __construct() { + //These checks have been implemented for pseudo backwards-compatibility + // (internal vars won't change if GLOBAL vars changed). + if(defined('DEBUGREMOVEHR')) { + $this->debugRemoveHr = constant('DEBUGREMOVEHR'); + } + elseif(isset($GLOBALS['DEBUGREMOVEHR'])) { + $this->debugRemoveHr = $GLOBALS['DEBUGREMOVEHR']; + } + + if(defined('DEBUGPRINTOPT')) { + $this->debugPrintOpt = constant('DEBUGPRINTOPT'); + } + elseif(isset($GLOBALS['DEBUGPRINTOPT'])) { + $this->debugPrintOpt = $GLOBALS['DEBUGPRINTOPT']; + } + $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); + }//end __construct() + //========================================================================= + + + + //========================================================================= + public function switch_force_sql_quotes($newSetting) { + if(is_bool($newSetting)) { + if($newSetting === true) { + $newSetting = 1; + } + else { + $newSetting = 1; + } + } + elseif(is_numeric($newSetting)) { + if($newSetting > 0) { + $newSetting = 1; + } + else { + $newSetting = 0; + } + } + else { + throw new exception(__METHOD__ .": invalid new setting (". $newSetting .")"); + } + + if($newSetting !== $this->forceSqlQuotes) { + $this->oldForceSqlQuotes = $this->forceSqlQuotes; + $this->forceSqlQuotes = $newSetting; + $retval = true; + } + else { + $retval = false; + } + + return($retval); + }//end switch_force_sql_quotes() + //========================================================================= + + + + //================================================================================================================ + /** + * Automatically selects either the header() function, or printing meta-refresh data for redirecting a browser. + */ + public function conditional_header($url, $exitAfter=TRUE, $permRedir=FALSE) { + + if(is_array($_SESSION)) { + //do some things to help protect against recursive redirects. + if(isset($_SESSION['__conditional_header__'])) { + $number = $_SESSION['__conditional_header__']['number']; + $lastTime = $_SESSION['__conditional_header__']['last_time']; + if((time() - $lastTime) <= 1 && $number > 5) { + unset($_SESSION['__conditional_header__']); + throw new exception(__METHOD__ .": too many redirects (". $number .") in a short time, last url: (". $url .")"); + } + else { + $_SESSION['__conditional_header__']['number']++; + $_SESSION['__conditional_header__']['last_time'] = time(); + } + } + else { + $_SESSION['__conditional_header__'] = array( + 'last_time' => time(), + 'number' => 0 + ); + } + } + + if(!strlen($url)) { + throw new exception(__METHOD__ .": failed to specify URL (". $url .")"); + } + else { + if(headers_sent()) { + //headers sent. Use the meta redirect. + print " + <HTML> + <HEAD> + <TITLE>Redirect Page</TITLE> + <META HTTP-EQUIV='refresh' content='0; URL=$url'> + </HEAD> + <a href=\"$url\"></a> + </HTML> + "; + } + else { + if($permRedir) { + //NOTE: can't do much for permanent redirects if headers have already been sent. + header("HTTP/1.1 301 Moved Permanently"); + } + header("location:$url"); + } + } + + if($exitAfter) { + exit; + } + }//end conditional_header() + //================================================================================================================ + + + + //================================================================================================================ + /** + * Basically, just a wrapper for create_list(), which returns a list or + * an array of lists, depending upon what was requested. + * + * @param $array <array> list for the array... + * @param $style <str,optional> what "style" it should be returned + * as (select, update, etc). + * @param $separator <str,optional> what separattes key from value: see each + * style for more information. + * @param $cleanString <mixed,optional> clean the values in $array by sending it + * to cleanString(), with this as the second argument. + * @param $removeEmptyVals <bool,optional> If $cleanString is an ARRAY and this + * evaluates as TRUE, indexes of $array whose values have + * a length of 0 will be removed. + */ + public function string_from_array($array,$style=NULL,$separator=NULL, $cleanString=NULL, $removeEmptyVals=FALSE) { + + $retval = NULL; + //precheck... if it's not an array, kill it. + if(!is_array($array)) { + return(NULL); + } + + //make sure $style is valid. + $typesArr = array("insert", "update"); + $style = strtolower($style); + + if(is_array($array)) { + + //if $cleanString is an array, assume it's arrayIndex => cleanStringArg + if(is_array($cleanString) && (!is_null($style) && (strlen($style)))) { + $cleanStringArr = array_intersect_key($cleanString, $array); + if(count($cleanStringArr) > 0 && is_array($cleanStringArr)) { + foreach($cleanStringArr as $myIndex=>$myCleanStringArg) { + if(($removeEmptyVals) && (strlen($array[$myIndex]) == 0)) { + //remove the index. + unset($array[$myIndex]); + } + else { + //now format it properly. + $array[$myIndex] = $this->cleanString($array[$myIndex], $myCleanStringArg); + } + } + } + } + switch($style) { + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case "insert": + if(!$separator) { + $separator = " VALUES "; + } + //build temporary data... + $tmp = array(); + foreach($array as $key=>$value) { + @$tmp[0] = $this->create_list($tmp[0], $key); + //clean the string, if required. + if($cleanString) { + //make sure it's not full of poo... + $value = $this->cleanString($value, "sql"); + #$value = "'". $value ."'"; + } + if((is_null($value)) OR ($value == "")) { + $value = "NULL"; + } + @$tmp[1] = $this->create_list($tmp[1], $value, ",", 1); + } + + //make the final product. + $retval = "(". $tmp[0] .")" . $separator . "(". $tmp[1] .")"; + + break; + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case "update": + if(!$separator) { + $separator = "="; + } + //build final product. + foreach($array as $field=>$value) { + $sqlQuotes = 1; + if(($value === "NULL" || $value === NULL) && !$this->forceSqlQuotes) { + $sqlQuotes = 0; + } + if($cleanString && !preg_match('/^\'/',$value)) { + //make sure it doesn't have crap in it... + $value = $this->cleanString($value, "sql",$sqlQuotes); + } + $retval = $this->create_list($retval, $field . $separator . $value); + } + break; + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case "order": + case "limit": + //for creating the "limit 50 offset 35" part of a query... or at least using that "style". + $separator = " "; + //build final product. + foreach($array as $field=>$value) { + if($cleanString) { + //make sure it doesn't have crap in it... + $value = $this->cleanString($value, "sql", $this->forceSqlQuotes); + $value = "'". $value ."'"; + } + $retval = $this->create_list($retval, $value, ", "); + } + if($style == "order" && !preg_match('/order by/', strtolower($retval))) { + $retval = "ORDER BY ". $retval; + } + break; + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case "select": + //build final product. + $separator = "="; + foreach($array as $field=>$value) { + + //allow for tricksie things... + /* + * Example: + * string_from_array(array("y"=>3, "x" => array(1,2,3))); + * + * would yield: "y=3 AND (x=1 OR x=2 OR x=3)" + */ + $delimiter = "AND"; + if(is_array($value)) { + //doing tricksie things!!! + $retval = $this->create_list($retval, $field ." IN (". $this->string_from_array($value) .")", + " $delimiter ", $this->forceSqlQuotes); + } + else { + //if there's already an operator ($separator), don't specify one. + if(preg_match('/^[\(<=>]/', $value)) { + $separator = NULL; + } + if($cleanString) { + //make sure it doesn't have crap in it... + $value = $this->cleanString($value, "sql"); + } + if(!is_numeric($value) && isset($separator)) { + $value = "'". $value ."'"; + } + $retval = $this->create_list($retval, $field . $separator . $value, " $delimiter ", $this->forceSqlQuotes); + } + } + break; + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case "url":{ + //an array like "array('module'='todo','action'='view','ID'=164)" to "module=todo&action=view&ID=164" + if(!$separator) { + $separator = "&"; + } + foreach($array as $field=>$value) { + if($cleanString && !is_array($cleanString)) { + $value = $this->cleanString($value, $cleanString); + } + $retval = $this->create_list($retval, "$field=$value", $separator); + } + } + break; + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case "text_list":{ + if(is_null($separator)) { + $separator = '='; + } + foreach($array as $field=>$value) { + $retval = $this->create_list($retval, $field . $separator . $value, "\n"); + } + } + break; + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + case "html_list":{ + if(is_null($separator)) { + $separator = '='; + } + foreach($array as $field=>$value) { + $retval = $this->create_list($retval, $field . $separator . $value, "<BR>\n"); + } + } + break; + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + DEFAULT: + if(!$separator) { + $separator = ", "; + } + foreach($array as $field=>$value) { + if($cleanString) { + $value = $this->cleanString($value, $cleanString); + } + $retval = $this->create_list($retval, $value, $separator, $this->forceSqlQuotes); + } + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + } + } + else { + //not an array. + $retval = NULL; + } + + return($retval); + }//end string_from_array() + //================================================================================================================ + + + + //================================================================================================================ + /** + * Easy way of cleaning data using types/styles of cleaning, with optional quoting. + * + * @param $cleanThis (str) data to be cleaned + * @param $cleanType (str,optional) how to clean the data. + * @param $sqlQuotes (bool,optional) quote the string for SQL + * + * @return (string) Cleaned data. + */ + function cleanString($cleanThis=NULL, $cleanType="all",$sqlQuotes=0) { + $cleanType = strtolower($cleanType); + switch ($cleanType) { + case "none": + //nothing to see here (no cleaning wanted/needed). Move along. + $sqlQuotes = 0; + break; + + case "query": + /* + replace \' with ' + gets rid of evil characters that might lead to SQL injection attacks. + replace line-break characters + */ + $evilChars = array("\$", "%", "~", "*",">", "<", "-", "{", "}", "[", "]", ")", "(", "&", "#", "?", ".", "\,","\/","\\","\"","\|","!","^","+","`","\n","\r"); + $cleanThis = preg_replace("/\|/","",$cleanThis); + $cleanThis = preg_replace("/\'/", "", $cleanThis); + $cleanThis = str_replace($evilChars,"", $cleanThis); + $cleanThis = stripslashes(addslashes($cleanThis)); + break; + + case "sql": + $cleanThis = addslashes(stripslashes($cleanThis)); + break; + + + case "sql_insert": + /* + * This is for descriptive fields, where double quotes don't need to be escaped: in these + * cases, escaping the double-quotes might lead to inserting something that looks different + * than the original, but in fact is identical. + */ + $cleanThis = addslashes(stripslashes($cleanThis)); + $cleanThis = preg_replace('/\\\\"/', '"', $cleanThis); + $cleanThis = preg_replace("/'/", "\\\'", $cleanThis); + + break; + + + case "sql92_insert": + /* + * Just like 'sql_insert', except that single quotes are "delimited" by + * adding another single quote, which works *at least* with postgres & sqlite. + */ + $cleanThis = preg_replace("/'/", "''", $cleanThis); + $cleanThis = preg_replace('/\\\\"/', '"', $cleanThis); + $cleanThis = stripslashes($cleanThis); + $sqlQuotes = 0; + break; + + case "double_quote": + //This will remove all double quotes from a string. + $cleanThis = str_replace('"',"",$cleanThis); + break; + + case "htmlspecial": + /* + This function is useful in preventing user-supplied text from containing HTML markup, such as in a message board or guest book application. + The translations performed are: + '&' (ampersand) becomes '&' + '"' (double quote) becomes '"'. + '<' (less than) becomes '<' + '>' (greater than) becomes '>' + */ + + $cleanThis = htmlspecialchars($cleanThis); + break; + + case "htmlspecial_q": + /* + '&' (ampersand) becomes '&' + '"' (double quote) becomes '"'. + ''' (single quote) becomes '''. + '<' (less than) becomes '<' + '>' (greater than) becomes '> + */ + $cleanThis = htmlspecialchars($cleanThis,ENT_QUOTES); + break; + + case "htmlspecial_nq": + /* + '&' (ampersand) becomes '&' + '<' (less than) becomes '<' + '>' (greater than) becomes '> + */ + $cleanThis = htmlspecialchars($cleanThis,ENT_NOQUOTES); + break; + + case "htmlentity": + /* + Convert all applicable text to its html entity + Will convert double-quotes and leave single-quotes alone + */ + $cleanThis = htmlentities(html_entity_decode($cleanThis)); + break; + + case "htmlentity_plus_brackets": + /* + Just like htmlentity, but also converts "{" and "}" (prevents template + from being incorrectly parse). + Also converts "{" and "}" to their html entity. + */ + $cleanThis = htmlentities(html_entity_decode($cleanThis)); + $cleanThis = str_replace('$', '$', $cleanThis); + $cleanThis = str_replace('{', '{', $cleanThis); + $cleanThis = str_replace('}', '}', $cleanThis); + break; + + case "double_entity": + //Removed double quotes, then calls html_entities on it. + $cleanThis = str_replace('"',"",$cleanThis); + $cleanThis = htmlentities(html_entity_decode($cleanThis)); + break; + + case "meta": + // Returns a version of str with a backslash character (\) before every character that is among these: + // . \\ + * ? [ ^ ] ( $ ) + $cleanThis = quotemeta($cleanThis); + break; + + case "email": + //Remove all characters that aren't allowed in an email address. + $cleanThis = preg_replace("/[^A-Za-z0-9\._@-]/","",$cleanThis); + break; + + case "email_plus_spaces": + //Remove all characters that aren't allowed in an email address. + $cleanThis = preg_replace("/[^A-Za-z0-9\ \._@-]/","",$cleanThis); + break; + + case "phone_fax": + //Remove everything that's not numeric or +()- example: +1 (555)-555-2020 is valid + $cleanThis = preg_replace("/[^0-9-+() ]/","",$cleanThis); + break; + + case "integer": + case "numeric": + //Remove everything that's not numeric. + if(is_null($cleanThis)) { + $cleanThis = "NULL"; + $sqlQuotes = 0; + } + else { + $cleanThis = preg_replace("/[^0-9]/","",$cleanThis); + } + break; + + case "decimal": + case "float": + //same as integer only the decimal point is allowed + $cleanThis = preg_replace("/[^0-9\.]/","",$cleanThis); + break; + + case "name": + case "names": + //allows only things in the "alpha" case and single quotes. + $cleanThis = preg_replace("/[^a-zA-Z']/", "", $cleanThis); + break; + + case "alpha": + //Removes anything that's not English a-zA-Z + $cleanThis = preg_replace("/[^a-zA-Z]/","",$cleanThis); + break; + + case "bool": + case "boolean": + //makes it either T or F (gotta lower the string & only check the first char to ensure accurate results). + $cleanThis = $this->interpret_bool($cleanThis, array('f', 't')); + break; + + case "varchar": + $cleanThis=$this->cleanString($cleanThis,"query"); + $cleanThis="'" . $cleanThis . "'"; + if($cleanThis == "''") { + $cleanThis="NULL"; + } + break; + + case "date": + $cleanThis = preg_replace("/[^0-9\-]/","",$cleanThis); + break; + + case "datetime": + $cleanThis=preg_replace("/[^A-Za-z0-9\/: \-\'\.]/","",$cleanThis); + break; + + case "all": + default: + // 1. Remove all naughty characters we can think of except alphanumeric. + $cleanThis = preg_replace("/[^A-Za-z0-9]/","",$cleanThis); + break; + + } + if($sqlQuotes) { + $cleanThis = "'". $cleanThis ."'"; + } + return $cleanThis; + }//end cleanString() + //================================================================================================================ + + + + + //================================================================================================================ + /** + * Returns a list delimited by the given delimiter. Does the work of checking if the given variable has data + * in it already, that needs to be added to, vs. setting the variable with the new content. + */ + public function create_list($string=NULL, $addThis=NULL, $delimiter=", ", $useSqlQuotes=0) { + if(strlen($string)) { + if($useSqlQuotes && !(preg_match("/^'/", $addThis) && preg_match("/'\$/", $addThis))) { + $addThis = "'". $addThis ."'"; + } + $retVal = $string . $delimiter . $addThis; + } + else { + $retVal = $addThis; + if($useSqlQuotes && !(preg_match("/^'/", $retVal) && preg_match("/'\$/", $retVal))) { + $retVal = "'". $retVal ."'"; + } + } + + return($retVal); + } //end create_list() + //================================================================================================================ + + + + //================================================================================================================ + /** + * A way of printing out human-readable information, especially arrays & objects, either to a web browser or via + * the command line. + * + * @param $input (mixed,optional) data to print/return + * @param $printItForMe (bool,optional) whether it should be printed or just returned. + * + * @return (string) printed data. + */ + public function debug_print($input=NULL, $printItForMe=NULL, $removeHR=NULL) { + if(!is_numeric($removeHR)) { + $removeHR = $this->debugRemoveHr; + } + + if(!is_numeric($printItForMe)) { + $printItForMe = $this->debugPrintOpt; + } + + ob_start(); + print_r($input); + $output = ob_get_contents(); + ob_end_clean(); + + $output = "<pre>$output</pre>"; + + if(!isset($_SERVER['SERVER_PROTOCOL']) || !$_SERVER['SERVER_PROTOCOL']) { + $output = strip_tags($output); + $hrString = "\n***************************************************************\n"; + } + else { + $hrString = "<hr>"; + } + if($removeHR) { + $hrString = NULL;; + } + + if($printItForMe) { + print "$output". $hrString ."\n"; + } + + return($output); + } //end debug_print() + //================================================================================================================ + + + + //================================================================================================================ + function swapValue(&$value, $c1, $c2) { + if(!$value) { + $value = $c1; + } + + + /* choose the next color */ + if($value == "$c1") { + $value = "$c2"; + } + else { + $value = "$c1"; + } + + return($value); + } + //================================================================================================================ + + + + //--------------------------------------------------------------------------------------------- + /** + * Using the given template, it will replace each index (in $repArr) with it's value: each + * var to be replaced must begin the given begin & end delimiters. + * + * @param $template (str) Data to perform the replacements on. + * @param $repArr (array) Array of name=>value pairs, where name is to be replaced with value. + * @param $b (str,optional) beginning delimiter. + * @param $e (str,optional) ending delimiter. + */ + public function mini_parser($template, $repArr, $b='%%', $e='%%') { + if(!isset($b) OR !isset($e)){ + $b="{"; + $e="}"; + } + + foreach($repArr as $key=>$value) { + //run the replacements. + $key = "$b" . $key . "$e"; + $template = str_replace("$key", $value, $template); + } + + return($template); + }//end mini_parser() + //--------------------------------------------------------------------------------------------- + + + //--------------------------------------------------------------------------------------------- + /** + * Takes the given string & truncates it so the final string is the given + * maximum length. Optionally adds a chunk of text to the end, and also + * optionally STRICTLY truncates (non-strict means the endString will be + * added blindly, while strict means the length of the endString will be + * subtracted from the total length, so the final string is EXACTLY the + * given length or shorter). + * + * @param string (str) the string to truncate + * @param $maxLength (int) maximum length for the result. + * @param $endString (str,optional) this is added to the end of the + * truncated string, if it exceeds $maxLength + * @param $strict (bool,optional) if non-strict, the length of + * the return would be $maxLength + length($endString) + */ + function truncate_string($string,$maxLength,$endString="...",$strict=FALSE) { + + //determine if it's even worth truncating. + if(is_string($string) && is_numeric($maxLength) && $maxLength > 0) { + $strLength = strlen($string); + if($strLength <= $maxLength) { + //no need to truncate. + $retval = $string; + } + else { + //actually needs to be truncated... + if($strict) { + $trueMaxLength = $maxLength - strlen($endString); + } + else { + $trueMaxLength = $maxLength; + } + + //rip the first ($trueMaxLength) characters from string, append $endString, and go. + $tmp = substr($string,0,$trueMaxLength); + $retval = $tmp . $endString; + } + } + else { + $retval = $string; + } + + return($retval); + + }//end truncate_string() + //--------------------------------------------------------------------------------------------- + + + + //########################################################################## + public function array_as_option_list(array $data, $checkedValue=NULL, $type="select", $useTemplateString=NULL, array $repArr=NULL) { + $typeArr = array ( + "select" => "selected", + "radio" => "checked", + "checkbox" => "checked" + ); + + $myType = $typeArr[$type]; + if(is_null($useTemplateString)) { + // + $useTemplateString = "\t\t<option value='%%value%%'%%selectedString%%>%%display%%</option>"; + } + + $retval = ""; + foreach($data as $value=>$display) { + //see if it's the value that's been selected. + $selectedString = ""; + if($value == $checkedValue || $display == $checkedValue) { + //yep, it's selected. + $selectedString = " ". $myType; + } + + //create the string. + $myRepArr = array( + 'value' => $value, + 'display' => $display, + 'selectedString' => $selectedString + ); + if(is_array($repArr) && is_array($repArr[$value])) { + //merge the arrays. + $myRepArr = array_merge($repArr[$value], $myRepArr); + } + $addThis = $this->mini_parser($useTemplateString, $myRepArr, "%%", "%%"); + $retval = $this->create_list($retval, $addThis, "\n"); + } + + return($retval); + }//end array_as_option_list() + //########################################################################## + + + + //########################################################################## + public function interpret_bool($interpretThis, array $trueFalseMapper=null) { + $interpretThis = preg_replace('/ /', '', $interpretThis); + if(is_array($trueFalseMapper)) { + if(count($trueFalseMapper) == 2 && isset($trueFalseMapper[0]) && isset($trueFalseMapper[1])) { + $realVals = $trueFalseMapper; + } + else { + throw new exception(__METHOD__ .": invalid true/false map"); + } + } + else { + //set an array that defines what "0" and "1" return. + $realVals = array( + 0 => false, + 1 => true + ); + } + + //now figure out the value to return. + if(is_numeric($interpretThis)) { + settype($interpretThis, 'integer'); + if($interpretThis == '0') { + $index=0; + } + else { + $index=1; + } + } + elseif(is_bool($interpretThis)) { + if($interpretThis == true) { + $index=1; + } + else { + $index=0; + } + } + elseif(preg_match('/^true$/i', $interpretThis) || preg_match('/^false$/', $interpretThis) || preg_match("/^[tf]$/", $interpretThis)) { + if(preg_match('/^true$/i', $interpretThis) || preg_match('/^t$/', $interpretThis)) { + $index=1; + } + else { + $index=0; + } + } + else { + //straight-up PHP if/else evaluation. + if($interpretThis) { + $index=1; + } + else { + $index=0; + } + } + + return($realVals[$index]); + }//end interpret_bool() + //########################################################################## + +}//end cs_globalFunctions{} + +?> Property changes on: trunk/1.0/cs_globalFunctions.class.php ___________________________________________________________________ Added: svn:executable + * Added: svn:mergeinfo + Added: svn:eol-style + native Deleted: trunk/1.0/cs_globalFunctions.php =================================================================== --- trunk/1.0/cs_globalFunctions.php 2009-01-29 21:15:20 UTC (rev 334) +++ trunk/1.0/cs_globalFunctions.php 2009-01-29 21:25:58 UTC (rev 335) @@ -1,844 +0,0 @@ -<?php - -require_once(dirname(__FILE__) ."/../cs-versionparse/cs_version.abstract.class.php"); - -class cs_globalFunctions extends cs_versionAbstract { - - - /* DEBUG PRINT OPTIONS */ - /** Remove the separator below the output of each debug_print()? */ - public $debugRemoveHr = 0; - public $debugPrintOpt = 0; - - private $forceSqlQuotes=0; - private $oldForceSqlQuotes=0; - - //========================================================================= - public function __construct() { - //These checks have been implemented for pseudo backwards-compatibility - // (internal vars won't change if GLOBAL vars changed). - if(defined('DEBUGREMOVEHR')) { - $this->debugRemoveHr = constant('DEBUGREMOVEHR'); - } - elseif(isset($GLOBALS['DEBUGREMOVEHR'])) { - $this->debugRemoveHr = $GLOBALS['DEBUGREMOVEHR']; - } - - if(defined('DEBUGPRINTOPT')) { - $this->debugPrintOpt = constant('DEBUGPRINTOPT'); - } - elseif(isset($GLOBALS['DEBUGPRINTOPT'])) { - $this->debugPrintOpt = $GLOBALS['DEBUGPRINTOPT']; - } - $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); - }//end __construct() - //========================================================================= - - - - //========================================================================= - public function switch_force_sql_quotes($newSetting) { - if(is_bool($newSetting)) { - if($newSetting === true) { - $newSetting = 1; - } - else { - $newSetting = 1; - } - } - elseif(is_numeric($newSetting)) { - if($newSetting > 0) { - $newSetting = 1; - } - else { - $newSetting = 0; - } - } - else { - throw new exception(__METHOD__ .": invalid new setting (". $newSetting .")"); - } - - if($newSetting !== $this->forceSqlQuotes) { - $this->oldForceSqlQuotes = $this->forceSqlQuotes; - $this->forceSqlQuotes = $newSetting; - $retval = true; - } - else { - $retval = false; - } - - return($retval); - }//end switch_force_sql_quotes() - //========================================================================= - - - - //================================================================================================================ - /** - * Automatically selects either the header() function, or printing meta-refresh data for redirecting a browser. - */ - public function conditional_header($url, $exitAfter=TRUE, $permRedir=FALSE) { - - if(is_array($_SESSION)) { - //do some things to help protect against recursive redirects. - if(isset($_SESSION['__conditional_header__'])) { - $number = $_SESSION['__conditional_header__']['number']; - $lastTime = $_SESSION['__conditional_header__']['last_time']; - if((time() - $lastTime) <= 1 && $number > 5) { - unset($_SESSION['__conditional_header__']); - throw new exception(__METHOD__ .": too many redirects (". $number .") in a short time, last url: (". $url .")"); - } - else { - $_SESSION['__conditional_header__']['number']++; - $_SESSION['__conditional_header__']['last_time'] = time(); - } - } - else { - $_SESSION['__conditional_header__'] = array( - 'last_time' => time(), - 'number' => 0 - ); - } - } - - if(!strlen($url)) { - throw new exception(__METHOD__ .": failed to specify URL (". $url .")"); - } - else { - if(headers_sent()) { - //headers sent. Use the meta redirect. - print " - <HTML> - <HEAD> - <TITLE>Redirect Page</TITLE> - <META HTTP-EQUIV='refresh' content='0; URL=$url'> - </HEAD> - <a href=\"$url\"></a> - </HTML> - "; - } - else { - if($permRedir) { - //NOTE: can't do much for permanent redirects if headers have already been sent. - header("HTTP/1.1 301 Moved Permanently"); - } - header("location:$url"); - } - } - - if($exitAfter) { - exit; - } - }//end conditional_header() - //================================================================================================================ - - - - //================================================================================================================ - /** - * Basically, just a wrapper for create_list(), which returns a list or - * an array of lists, depending upon what was requested. - * - * @param $array <array> list for the array... - * @param $style <str,optional> what "style" it should be returned - * as (select, update, etc). - * @param $separator <str,optional> what separattes key from value: see each - * style for more information. - * @param $cleanString <mixed,optional> clean the values in $array by sending it - * to cleanString(), with this as the second argument. - * @param $removeEmptyVals <bool,optional> If $cleanString is an ARRAY and this - * evaluates as TRUE, indexes of $array whose values have - * a length of 0 will be removed. - */ - public function string_from_array($array,$style=NULL,$separator=NULL, $cleanString=NULL, $removeEmptyVals=FALSE) { - - $retval = NULL; - //precheck... if it's not an array, kill it. - if(!is_array($array)) { - return(NULL); - } - - //make sure $style is valid. - $typesArr = array("insert", "update"); - $style = strtolower($style); - - if(is_array($array)) { - - //if $cleanString is an array, assume it's arrayIndex => cleanStringArg - if(is_array($cleanString) && (!is_null($style) && (strlen($style)))) { - $cleanStringArr = array_intersect_key($cleanString, $array); - if(count($cleanStringArr) > 0 && is_array($cleanStringArr)) { - foreach($cleanStringArr as $myIndex=>$myCleanStringArg) { - if(($removeEmptyVals) && (strlen($array[$myIndex]) == 0)) { - //remove the index. - unset($array[$myIndex]); - } - else { - //now format it properly. - $array[$myIndex] = $this->cleanString($array[$myIndex], $myCleanStringArg); - } - } - } - } - switch($style) { - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - case "insert": - if(!$separator) { - $separator = " VALUES "; - } - //build temporary data... - $tmp = array(); - foreach($array as $key=>$value) { - @$tmp[0] = $this->create_list($tmp[0], $key); - //clean the string, if required. - if($cleanString) { - //make sure it's not full of poo... - $value = $this->cleanString($value, "sql"); - #$value = "'". $value ."'"; - } - if((is_null($value)) OR ($value == "")) { - $value = "NULL"; - } - @$tmp[1] = $this->create_list($tmp[1], $value, ",", 1); - } - - //make the final product. - $retval = "(". $tmp[0] .")" . $separator . "(". $tmp[1] .")"; - - break; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - case "update": - if(!$separator) { - $separator = "="; - } - //build final product. - foreach($array as $field=>$value) { - $sqlQuotes = 1; - if(($value === "NULL" || $value === NULL) && !$this->forceSqlQuotes) { - $sqlQuotes = 0; - } - if($cleanString && !preg_match('/^\'/',$value)) { - //make sure it doesn't have crap in it... - $value = $this->cleanString($value, "sql",$sqlQuotes); - } - $retval = $this->create_list($retval, $field . $separator . $value); - } - break; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - case "order": - case "limit": - //for creating the "limit 50 offset 35" part of a query... or at least using that "style". - $separator = " "; - //build final product. - foreach($array as $field=>$value) { - if($cleanString) { - //make sure it doesn't have crap in it... - $value = $this->cleanString($value, "sql", $this->forceSqlQuotes); - $value = "'". $value ."'"; - } - $retval = $this->create_list($retval, $value, ", "); - } - if($style == "order" && !preg_match('/order by/', strtolower($retval))) { - $retval = "ORDER BY ". $retval; - } - break; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - case "select": - //build final product. - $separator = "="; - foreach($array as $field=>$value) { - - //allow for tricksie things... - /* - * Example: - * string_from_array(array("y"=>3, "x" => array(1,2,3))); - * - * would yield: "y=3 AND (x=1 OR x=2 OR x=3)" - */ - $delimiter = "AND"; - if(is_array($value)) { - //doing tricksie things!!! - $retval = $this->create_list($retval, $field ." IN (". $this->string_from_array($value) .")", - " $delimiter ", $this->forceSqlQuotes); - } - else { - //if there's already an operator ($separator), don't specify one. - if(preg_match('/^[\(<=>]/', $value)) { - $separator = NULL; - } - if($cleanString) { - //make sure it doesn't have crap in it... - $value = $this->cleanString($value, "sql"); - } - if(!is_numeric($value) && isset($separator)) { - $value = "'". $value ."'"; - } - $retval = $this->create_list($retval, $field . $separator . $value, " $delimiter ", $this->forceSqlQuotes); - } - } - break; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - case "url":{ - //an array like "array('module'='todo','action'='view','ID'=164)" to "module=todo&action=view&ID=164" - if(!$separator) { - $separator = "&"; - } - foreach($array as $field=>$value) { - if($cleanString && !is_array($cleanString)) { - $value = $this->cleanString($value, $cleanString); - } - $retval = $this->create_list($retval, "$field=$value", $separator); - } - } - break; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - case "text_list":{ - if(is_null($separator)) { - $separator = '='; - } - foreach($array as $field=>$value) { - $retval = $this->create_list($retval, $field . $separator . $value, "\n"); - } - } - break; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - case "html_list":{ - if(is_null($separator)) { - $separator = '='; - } - foreach($array as $field=>$value) { - $retval = $this->create_list($retval, $field . $separator . $value, "<BR>\n"); - } - } - break; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - DEFAULT: - if(!$separator) { - $separator = ", "; - } - foreach($array as $field=>$value) { - if($cleanString) { - $value = $this->cleanString($value, $cleanString); - } - $retval = $this->create_list($retval, $value, $separator, $this->forceSqlQuotes); - } - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - } - } - else { - //not an array. - $retval = NULL; - } - - return($retval); - }//end string_from_array() - //================================================================================================================ - - - - //================================================================================================================ - /** - * Easy way of cleaning data using types/styles of cleaning, with optional quoting. - * - * @param $cleanThis (str) data to be cleaned - * @param $cleanType (str,optional) how to clean the data. - * @param $sqlQuotes (bool,optional) quote the string for SQL - * - * @return (string) Cleaned data. - */ - function cleanString($cleanThis=NULL, $cleanType="all",$sqlQuotes=0) { - $cleanType = strtolower($cleanType); - switch ($cleanType) { - case "none": - //nothing to see here (no cleaning wanted/needed). Move along. - $sqlQuotes = 0; - break; - - case "query": - /* - replace \' with ' - gets rid of evil characters that might lead to SQL injection attacks. - replace line-break characters - */ - $evilChars = array("\$", "%", "~", "*",">", "<", "-", "{", "}", "[", "]", ")", "(", "&", "#", "?", ".", "\,","\/","\\","\"","\|","!","^","+","`","\n","\r"); - $cleanThis = preg_replace("/\|/","",$cleanThis); - $cleanThis = preg_replace("/\'/", "", $cleanThis); - $cleanThis = str_replace($evilChars,"", $cleanThis); - $cleanThis = stripslashes(addslashes($cleanThis)); - break; - - case "sql": - $cleanThis = addslashes(stripslashes($cleanThis)); - break; - - - case "sql_insert": - /* - * This is for descriptive fields, where double quotes don't need to be escaped: in these - * cases, escaping the double-quotes might lead to inserting something that looks different - * than the original, but in fact is identical. - */ - $cleanThis = addslashes(stripslashes($cleanThis)); - $cleanThis = preg_replace('/\\\\"/', '"', $cleanThis); - $cleanThis = preg_replace("/'/", "\\\'", $cleanThis); - - break; - - - case "sql92_insert": - /* - * Just like 'sql_insert', except that single quotes are "delimited" by - * adding another single quote, which works *at least* with postgres & sqlite. - */ - $cleanThis = preg_replace("/'/", "''", $cleanThis); - $cleanThis = preg_replace('/\\\\"/', '"', $cleanThis); - $cleanThis = stripslashes($cleanThis); - $sqlQuotes = 0; - break; - - case "double_quote": - //This will remove all double quotes from a string. - $cleanThis = str_replace('"',"",$cleanThis); - break; - - case "htmlspecial": - /* - This function is useful in preventing user-supplied text from containing HTML markup, such as in a message board or guest book application. - The translations performed are: - '&' (ampersand) becomes '&' - '"' (double quote) becomes '"'. - '<' (less than) becomes '<' - '>' (greater than) becomes '>' - */ - - $cleanThis = htmlspecialchars($cleanThis); - break; - - case "htmlspecial_q": - /* - '&' (ampersand) becomes '&' - '"' (double quote) becomes '"'. - ''' (single quote) becomes '''. - '<' (less than) becomes '<' - '>' (greater than) becomes '> - */ - $cleanThis = htmlspecialchars($cleanThis,ENT_QUOTES); - break; - - case "htmlspecial_nq": - /* - '&' (ampersand) becomes '&' - '<' (less than) becomes '<' - '>' (greater than) becomes '> - */ - $cleanThis = htmlspecialchars($cleanThis,ENT_NOQUOTES); - break; - - case "htmlentity": - /* - Convert all applicable text to its html entity - Will convert double-quotes and leave single-quotes alone - */ - $cleanThis = htmlentities(html_entity_decode($cleanThis)); - break; - - case "htmlentity_plus_brackets": - /* - Just like htmlentity, but also converts "{" and "}" (prevents template - from being incorrectly parse). - Also converts "{" and "}" to their html entity. - */ - $cleanThis = htmlentities(html_entity_decode($cleanThis)); - $cleanThis = str_replace('$', '$', $cleanThis); - $cleanThis = str_replace('{', '{', $cleanThis); - $cleanThis = str_replace('}', '}', $cleanThis); - break; - - case "double_entity": - //Removed double quotes, then calls html_entities on it. - $cleanThis = str_replace('"',"",$cleanThis); - $cleanThis = htmlentities(html_entity_decode($cleanThis)); - break; - - case "meta": - // Returns a version of str with a backslash character (\) before every character that is among these: - // . \\ + * ? [ ^ ] ( $ ) - $cleanThis = quotemeta($cleanThis); - break; - - case "email": - //Remove all characters that aren't allowed in an email address. - $cleanThis = preg_replace("/[^A-Za-z0-9\._@-]/","",$cleanThis); - break; - - case "email_plus_spaces": - //Remove all characters that aren't allowed in an email address. - $cleanThis = preg_replace("/[^A-Za-z0-9\ \._@-]/","",$cleanThis); - break; - - case "phone_fax": - //Remove everything that's not numeric or +()- example: +1 (555)-555-2020 is valid - $cleanThis = preg_replace("/[^0-9-+() ]/","",$cleanThis); - break; - - case "integer": - case "numeric": - //Remove everything that's not numeric. - if(is_null($cleanThis)) { - $cleanThis = "NULL"; - $sqlQuotes = 0; - } - else { - $cleanThis = preg_replace("/[^0-9]/","",$cleanThis); - } - break; - - case "decimal": - case "float": - //same as integer only the decimal point is allowed - $cleanThis = preg_replace("/[^0-9\.]/","",$cleanThis); - break; - - case "name": - case "names": - //allows only things in the "alpha" case and single quotes. - $cleanThis = preg_replace("/[^a-zA-Z']/", "", $cleanThis); - break; - - case "alpha": - //Removes anything that's not English a-zA-Z - $cleanThis = preg_replace("/[^a-zA-Z]/","",$cleanThis); - break; - - case "bool": - case "boolean": - //makes it either T or F (gotta lower the string & only check the first char to ensure accurate results). - $cleanThis = $this->interpret_bool($cleanThis, array('f', 't')); - break; - - case "varchar": - $cleanThis=$this->cleanString($cleanThis,"query"); - $cleanThis="'" . $cleanThis . "'"; - if($cleanThis == "''") { - $cleanThis="NULL"; - } - break; - - case "date": - $cleanThis = preg_replace("/[^0-9\-]/","",$cleanThis); - break; - - case "datetime": - $cleanThis=preg_replace("/[^A-Za-z0-9\/: \-\'\.]/","",$cleanThis); - break; - - case "all": - default: - // 1. Remove all naughty characters we can think of except alphanumeric. - $cleanThis = preg_replace("/[^A-Za-z0-9]/","",$cleanThis); - break; - - } - if($sqlQuotes) { - $cleanThis = "'". $cleanThis ."'"; - } - return $cleanThis; - }//end cleanString() - //================================================================================================================ - - - - - //================================================================================================================ - /** - * Returns a list delimited by the given delimiter. Does the work of checking if the given variable has data - * in it already, that needs to be added to, vs. setting the variable with the new content. - */ - public function create_list($string=NULL, $addThis=NULL, $delimiter=", ", $useSqlQuotes=0) { - if(strlen($string)) { - if($useSqlQuotes && !(preg_match("/^'/", $addThis) && preg_match("/'\$/", $addThis))) { - $addThis = "'". $addThis ."'"; - } - $retVal = $string . $delimiter . $addThis; - } - else { - $retVal = $addThis; - if($useSqlQuotes && !(preg_match("/^'/", $retVal) && preg_match("/'\$/", $retVal))) { - $retVal = "'". $retVal ."'"; - } - } - - return($retVal); - } //end create_list() - //================================================================================================================ - - - - //================================================================================================================ - /** - * A way of printing out human-readable information, especially arrays & objects, either to a web browser or via - * the command line. - * - * @param $input (mixed,optional) data to print/return - * @param $printItForMe (bool,optional) whether it should be printed or just returned. - * - * @return (string) printed data. - */ - public function debug_print($input=NULL, $printItForMe=NULL, $removeHR=NULL) { - if(!is_numeric($removeHR)) { - $removeHR = $this->debugRemoveHr; - } - - if(!is_numeric($printItForMe)) { - $printItForMe = $this->debugPrintOpt; - } - - ob_start(); - print_r($input); - $output = ob_get_contents(); - ob_end_clean(); - - $output = "<pre>$output</pre>"; - - if(!isset($_SERVER['SERVER_PROTOCOL']) || !$_SERVER['SERVER_PROTOCOL']) { - $output = strip_tags($output); - $hrString = "\n***************************************************************\n"; - } - else { - $hrString = "<hr>"; - } - if($removeHR) { - $hrString = NULL;; - } - - if($printItForMe) { - print "$output". $hrString ."\n"; - } - - return($output); - } //end debug_print() - //================================================================================================================ - - - - //================================================================================================================ - function swapValue(&$value, $c1, $c2) { - if(!$value) { - $value = $c1; - } - - - /* choose the next color */ - if($value == "$c1") { - $value = "$c2"; - } - else { - $value = "$c1"; - } - - return($value); - } - //================================================================================================================ - - - - //--------------------------------------------------------------------------------------------- - /** - * Using the given template, it will replace each index (in $repArr) with it's value: each - * var to be replaced must begin the given begin & end delimiters. - * - * @param $template (str) Data to perform the replacements on. - * @param $repArr (array) Array of name=>value pairs, where name is to be replaced with value. - * @param $b (str,optional) beginning delimiter. - * @param $e (str,optional) ending delimiter. - */ - public function mini_parser($template, $repArr, $b='%%', $e='%%') { - if(!isset($b) OR !isset($e)){ - $b="{"; - $e="}"; - } - - foreach($repArr as $key=>$value) { - //run the replacements. - $key = "$b" . $key . "$e"; - $template = str_replace("$key", $value, $template); - } - - return($template); - }//end mini_parser() - //--------------------------------------------------------------------------------------------- - - - //--------------------------------------------------------------------------------------------- - /** - * Takes the given string & truncates it so the final string is the given - * maximum length. Optionally adds a chunk of text to the end, and also - * optionally STRICTLY truncates (non-strict means the endString will be - * added blindly, while strict means the length of the endString will be - * subtracted from the total length, so the final string is EXACTLY the - * given length or shorter). - * - * @param string (str) the string to truncate - * @param $maxLength (int) maximum length for the result. - * @param $endString (str,optional) this is added to the end of the - * truncated string, if it exceeds $maxLength - * @param $strict (bool,optional) if non-strict, the length of - * the return would be $maxLength + length($endString) - */ - function truncate_string($string,$maxLength,$endString="...",$strict=FALSE) { - - //determine if it's even worth truncating. - if(is_string($string) && is_numeric($maxLength) && $maxLength > 0) { - $strLength = strlen($string); - if($strLength <= $maxLength) { - //no need to truncate. - $retval = $string; - } - else { - //actually needs to be truncated... - if($strict) { - $trueMaxLength = $maxLength - strlen($endString); - } - else { - $trueMaxLength = $maxLength; - } - - //rip the first ($trueMaxLength) characters from string, append $endString, and go. - $tmp = substr($string,0,$trueMaxLength); - $retval = $tmp . $endString; - } - } - else { - $retval = $string; - } - - return($retval); - - }//end truncate_string() - //--------------------------------------------------------------------------------------------- - - - - //########################################################################## - public function array_as_option_list(array $data, $checkedValue=NULL, $type="select", $useTemplateString=NULL, array $repArr=NULL) { - $typeArr = array ( - "select" => "selected", - "radio" => "checked", - "checkbox" => "checked" - ); - - $myType = $typeArr[$type]; - if(is_null($useTemplateString)) { - // - $useTemplateString = "\t\t<option value='%%value%%'%%selectedString%%>%%display%%</option>"; - } - - $retval = ""; - foreach($data as $value=>$display) { - //see if it's the value that's been selected. - $selectedString = ""; - if($value == $checkedValue || $display == $checkedValue) { - //yep, it's selected. - $selectedString = " ". $myType; - } - - //create the string. - $myRepArr = array( - 'value' => $value, - 'display' => $display, - 'selectedString' => $selectedString - ); - if(is_array($repArr) && is_array($repArr[$value])) { - //merge the arrays. - $myRepArr = array_merge($repArr[$value], $myRepArr); - } - $addThis = $this->mini_parser($useTemplateString, $myRepArr, "%%", "%%"); - $retval = $this->create_list($retval, $addThis, "\n"); - } - - return($retval); - }//end array_as_option_list() - //########################################################################## - - - - //########################################################################## - public function interpret_bool($interpretThis, array $trueFalseMapper=null) { - $interpretThis = preg_replace('/ /', '', $interpretThis); - if(is_array($trueFalseMapper)) { - if(count($trueFalseMapper) == 2 && isset($trueFalseMapper[0]) && isset($trueFalseMapper[1])) { - $realVals = $trueFalseMapper; - } - else { - throw new exception(__METHOD__ .": invalid true/false map"); - } - } - else { - //set an array that defines what "0" and "1" return. - $realVals = array( - 0 => false, - 1 => true - ); - } - - //now figure out the value to return. - if(is_numeric($interpretThis)) { - settype($interpretThis, 'integer'); - if($interpretThis == '0') { - $index=0; - } - else { - $index=1; - } - } - elseif(is_bool($interpretThis)) { - if($interpretThis == true) { - $index=1; - } - else { - $index=0; - } - } - elseif(preg_match('/^true$/i', $interpretThis) || preg_match('/^false$/', $interpretThis) || preg_match("/^[tf]$/", $interpretThis)) { - if(preg_match('/^true$/i', $interpretThis) || preg_match('/^t$/', $interpretThis)) { - $index=1; - } - else { - $index=0; - } - } - else { - //straight-up PHP if/else evaluation. - if($interpretThis) { - $index=1; - } - else { - $index=0; - } - } - - return($realVals[$index]); - }//end interpret_bool() - //########################################################################## - -}//end cs_globalFunctions{} - -?> Modified: trunk/1.0/sample_files/public_html/index.php =================================================================== --- trunk/1.0/sample_files/public_html/index.php 2009-01-29 21:15:20 UTC (rev 334) +++ trunk/1.0/sample_files/public_html/index.php 2009-01-29 21:25:58 UTC (rev 335) @@ -1,6 +1,6 @@ <?php -require(dirname(__FILE__) . "/../lib/cs-content/cs_globalFunctions.php"); +require(dirname(__FILE__) . "/../lib/cs-content/cs_globalFunctions.class.php"); $gf = new cs_globalFunctions; $gf->conditional_header("/content/index.php"); exit; Modified: trunk/1.0/tests/testOfCSContent.php =================================================================== --- trunk/1.0/tests/testOfCSContent.php 2009-01-29 21:15:20 UTC (rev 334) +++ trunk/1.0/tests/testOfCSContent.php 2009-01-29 21:25:58 UTC (rev 335) @@ -19,7 +19,7 @@ //------------------------------------------------------------------------- function __construct() { - require_once(dirname(__FILE__) .'/../cs_globalFunctions.php'); + require_once(dirname(__FILE__) .'/../cs_globalFunctions.class.php'); require_once(dirname(__FILE__) .'/../cs_siteConfig.class.php'); $this->gf = new cs_globalFunctions; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-29 21:15:25
|
Revision: 334 http://cs-content.svn.sourceforge.net/cs-content/?rev=334&view=rev Author: crazedsanity Date: 2009-01-29 21:15:20 +0000 (Thu, 29 Jan 2009) Log Message: ----------- Fix references from cs_genericPageClass.php to cs_genericPage.class.php. /contentSystem.class.php: * MAIN::: -- fix include to point to new cs_genericPage{} class file /cs_genericPage.class.php [RENAMED FROM cs_genericPageClass.php] /cs_genericPageClass.php [RENAMED TO cs_genericPage.class.php] Modified Paths: -------------- trunk/1.0/contentSystem.class.php Added Paths: ----------- trunk/1.0/cs_genericPage.class.php Removed Paths: ------------- trunk/1.0/cs_genericPageClass.php Modified: trunk/1.0/contentSystem.class.php =================================================================== --- trunk/1.0/contentSystem.class.php 2009-01-29 21:04:18 UTC (rev 333) +++ trunk/1.0/contentSystem.class.php 2009-01-29 21:15:20 UTC (rev 334) @@ -73,7 +73,7 @@ require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); require_once(dirname(__FILE__) ."/cs_fileSystem.class.php"); require_once(dirname(__FILE__) ."/cs_sessionClass.php"); -require_once(dirname(__FILE__) ."/cs_genericPageClass.php"); +require_once(dirname(__FILE__) ."/cs_genericPage.class.php"); require_once(dirname(__FILE__) ."/cs_tabsClass.php"); class contentSystem extends cs_contentAbstract { Copied: trunk/1.0/cs_genericPage.class.php (from rev 331, trunk/1.0/cs_genericPageClass.php) =================================================================== --- trunk/1.0/cs_genericPage.class.php (rev 0) +++ trunk/1.0/cs_genericPage.class.php 2009-01-29 21:15:20 UTC (rev 334) @@ -0,0 +1,619 @@ +<?php +/* + * FILE INFORMATION: + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ +require_once(dirname(__FILE__) ."/template.inc"); +require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); + +class cs_genericPage extends cs_contentAbstract { + var $templateObj; //template object to parse the pages + var $templateVars = array(); //our copy of the global templateVars + var $mainTemplate; //the default layout of the site + + private $tmplDir; + private $libDir; + private $siteRoot; + private $allowRedirect; + + private $showEditableLink = FALSE; + + private $allowInvalidUrls=NULL; + + //--------------------------------------------------------------------------------------------- + /** + * The constructor. + */ + public function __construct($restrictedAccess=TRUE, $mainTemplateFile=NULL, $allowRedirect=TRUE) { + //handle some configuration. + $this->allowRedirect = $allowRedirect; + + //initialize stuff from our parent... + parent::__construct(); + + //initialize some internal stuff. + $this->initialize_locals($mainTemplateFile); + + //if they need to be logged-in... + $this->check_login($restrictedAccess); + + if(!defined('CS-CONTENT_SESSION_NAME')) { + define("CS-CONTENT_SESSION_NAME", ini_get('session.name')); + } + + //TODO: if the end page doesn't want to allow the "edit" links, will this still work? + if(defined("CS_CONTENT_MODIFIABLE") && constant("CS_CONTENT_MODIFIABLE") === TRUE) { + $this->showEditableLink = TRUE; + } + }//end __construct() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Initializes some internal objects, variables, and so on. + */ + protected function initialize_locals($mainTemplateFile) { + + //NOTE: this **requires** that the global variable "SITE_ROOT" is already set. + $this->siteRoot = preg_replace('/\/public_html/', '', $_SERVER['DOCUMENT_ROOT']); + $this->tmplDir = $this->siteRoot .'/templates'; + $this->libDir = $this->siteRoot .'/lib'; + + //if there have been some global template vars (or files) set, read 'em in here. + if(is_array($GLOBALS['templateVars']) && count($GLOBALS['templateVars'])) { + foreach($GLOBALS['templateVars'] as $key=>$value) { + $this->add_template_var($key, $value); + } + } + if(isset($GLOBALS['templateFiles']) && is_array($GLOBALS['templateFiles'])) { + foreach($GLOBALS['templateFiles'] as $key => $value) { + $this->templateFiles[$key] = $value; + } + } + unset($GLOBALS['templateVars'], $GLOBALS['templateFiles']); + + //build a new instance of the template library (from PHPLib) + $this->templateObj=new Template($this->tmplDir,"keep"); //initialize a new template parser + + if(preg_match('/^\//', $mainTemplateFile)) { + $mainTemplateFile = $this->tmplDir ."/". $mainTemplateFile; + } + $this->mainTemplate=$mainTemplateFile; //load the default layout + }//end initialize_locals() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Should just check to see if they've authenticated. In reality, this + * just performs blind redirection if $restrictedAccess is set (and if + * redirecting is allowed). + */ + public function check_login($restrictedAccess) { + if($restrictedAccess) { + $myUri = $_SERVER['SCRIPT_NAME']; + $doNotRedirectArr = array('/login.php', '/admin/login.php', '/index.php', '/admin.php', + '/content', '/content/index.php' + ); + $myUrlString=""; + $myGetArr = $_GET; + if(is_array($myGetArr) && count($myGetArr) > 0) { + unset($myGetArr['PHPSESSID']); + unset($myGetArr[CS-CONTENT_SESSION_NAME]); + $myUrlString = string_from_array($myGetArr, NULL, 'url'); + } + + //TODO: make the redirectHere variable dynamic--an argument, methinks. + $redirectHere = '/login.php?destination='. $myUrlString; + + //Not exitting after conditional_header() is... bad, m'kay? + $this->conditional_header($redirectHere, TRUE); + exit; + } + }//end check_login() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Remove all data from the special template var "content" (or optionally another ver). + * + * @param $section (str,optional) defines what template var to wip-out. + * @return (NULL) + */ + public function clear_content($section="content"){ + $this->change_content(" ",$section); + }//end clear_content() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Change the content of a template to the given data. + * + * @param $htmlString (str) data to use. + * @param $section (str,optional) define a different section. + * + * @return (NULL) + */ + public function change_content($htmlString,$section="content"){ + $this->templateVars[$section] = $htmlString; + }//end change_content() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Adds a template file (with the given handle) to be parsed. + * + * TODO: check if $fileName exists before blindly trying to parse it. + */ + public function add_template_file($handleName, $fileName){ + if($this->showEditableLink) { + $prefix = '[<a href="#NULL_page='. $fileName .'"><font color="red"><b>Edit "'. $handleName .'"</b></font></a>]<BR>'; + $this->add_template_var($handleName, $prefix .$this->file_to_string($fileName)); + } + else { + $this->add_template_var($handleName, $this->file_to_string($fileName)); + } + }//end add_template_file() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Adds a value for a template placeholder. + */ + public function add_template_var($varName, $varValue){ + $this->templateVars[$varName]=$varValue; + }//end add_template_var(); + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Rips the given block row name from the parent templateVar, (optionally) replacing it with + * a template var of the same name. + * + * @param $parent (str) name of the templateVar to pull the block row from. + * @param $handle (str) name of the block row to rip from it's parent. + * @param $removeDefs (bool,optional) if evaluated as FALSE, no template var is left in + * place of the block row. + * + * @return (bool false) FAIL: unable to find block row. + * @return (str) PASS: content of the block row. + */ + public function set_block_row($parent, $handle, $removeDefs=0) { + $name = $handle; + $str = $this->templateVars[$parent]; + + $reg = "/<!-- BEGIN $handle -->.+<!-- END $handle -->/sU"; + preg_match_all($reg, $str, $m); + if(!is_string($m[0][0])) { + #exit("set_block_row(): couldn't find '$handle' in var '$parent'"); + $retval = FALSE; + } else { + if($removeDefs) { + $openHandle = "<!-- BEGIN $handle -->"; + $endHandle = "<!-- END $handle -->"; + $m[0][0] = str_replace($openHandle, "", $m[0][0]); + $m[0][0] = str_replace($endHandle, "", $m[0][0]); + } + + $str = preg_replace($reg, "{" . "$name}", $str); + $this->templateVars[$parent] = $str; + $this->templateRows[$name] = $m[0][0]; + $this->add_template_var($name, ""); + $retval = $m[0][0]; + } + return($retval); + }//end set_block_row() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Using the given template, it will replace each index (in $repArr) with it's value: each + * var to be replaced must begin the given begin & end delimiters. + * + * @param $template (str) Data to perform the replacements on. + * @param $repArr (array) Array of name=>value pairs, where name is to be replaced with value. + * @param $b (str,optional) beginning delimiter. + * @param $e (str,optional) ending delimiter. + */ + public function mini_parser($template, $repArr, $b='%%', $e='%%') { + return($this->gfObj->mini_parser($template, $repArr, $b, $e)); + }//end mini_parser() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Processes all template vars & files, etc, to produce the final page. NOTE: it is a wise idea + * for most pages to have this called *last*. + * + * @param $stripUndefVars (bool,optional) Remove all undefined template vars. + * + * @return (str) Final, parsed page. + */ + public function print_page($stripUndefVars=1) { + //Show any available messages. + $this->process_set_message(); + + //Load the default page layout. + $this->templateObj->set_file("main", $this->mainTemplate); + + //load the placeholder names and thier values + $this->templateObj->set_var($this->templateVars); + $this->templateObj->parse("out","main"); //parse the sub-files into the main page + + if($stripUndefVars) { + $numLoops = 0; + while(preg_match_all('/\{.\S+?\}/', $this->templateObj->varvals['out'], $tags) && $numLoops < 50) { + $tags = $tags[0]; + + //TODO: figure out why this works when running it twice. + foreach($tags as $key=>$str) { + $str2 = str_replace("{", "", $str); + $str2 = str_replace("}", "", $str2); + if(!$this->templateVars[$str2] && $stripUndefVars) { + //TODO: set an internal pointer or something to use here, so they can see what was missed. + $this->templateObj->varvals[out] = str_replace($str, '', $this->templateObj->varvals[out]); + } + } + $this->templateObj->parse("out", "out"); + $numLoops++; + } + } + $this->templateObj->pparse("out","out"); //parse the main page + + }//end of print_page() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Handles a message that was set into the session. + */ + public function process_set_message() { + //if there's not a message set, skip. + $errorBox = ""; + if(isset($_SESSION['message']) && is_array($_SESSION['message'])) { + $errorBox = $this->file_to_string("system/message_box.tmpl"); + //let's make sure the "type" value is *lowercase*. + $_SESSION['message']['type'] = strtolower($_SESSION['message']['type']); + + //WARNING::: if you give it the wrong type, it'll STILL be parsed. Otherwise + // this has to match set_message() FAR too closely. And it's a pain. + $_SESSION['message']['messageType'] = $_SESSION['message']['type']; + $errorBox = $this->gfObj->mini_parser($errorBox, $_SESSION['message'], '{', '}'); + if($_SESSION['message']['type'] == "fatal") { + //replace content of the page with our error. + $this->change_content($errorBox); + } else { + //Non-fatal: put it into a template var. + $this->add_template_var("error_msg", $errorBox); + } + + //now that we're done displaying the message, let's get it out of the session (otherwise + // they'll never get past this point). + unset($_SESSION['message']); + } + return($errorBox); + }//end of process_set_message() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Takes a template file, whose root must be within $GLOBALS['TMPLDIR'], pulls it's + * content & returns it. + */ + public function file_to_string($templateFileName) { + $templateFileName = preg_replace('/\/\//', '\/', $templateFileName); + if($this->template_file_exists($templateFileName)) { + $retval = file_get_contents($this->tmplDir .'/'. $templateFileName); + } else { + $this->set_message_wrapper(array( + "title" => 'Template File Error', + "message" => 'Not all templates could be found for this page.', + "type" => 'error' + )); + } + return($retval); + }//end file_to_string() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Checks to see if the given filename exists within the template directory. + */ + public function template_file_exists($file) { + $retval = 0; + //If the string doesn't start with a /, add one + if (strncmp("/",$file,1)) { + //strncmp returns 0 if they match, so we're putting a / on if they don't + $file="/".$file; + } + $filename=$this->tmplDir.$file; + + if(file_exists($filename)) { + $retval = $filename; + } + return($retval); + }//end template_file_exists() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Creates an array in the session, used by the templating system as a way to + * get messages generated by the code into the page, without having to add + * special templates & such each time. + * + * @param $title (str) the title of the message. + * @param $message (str) text beneath the title. + * @param $linkURL (str,optional) URL for the link below the message. + * @param $type (str) notice/status/error/fatal message, indicating + * it's importance. Generally, fatal messages + * cause only the message to be shown. + * @param $linkText (str,optional) text that the link wraps. + * @param $overwriteSame (bool,optional) whether setting a message which has + * the same type as an already set message will + * overwite the previous. More important messages + * always overwrite lesser ones. + * @param $priority (int,optional) specify the message's priority. + * + * @return (bool) Indicates pass (true)/fail (false) + */ + function set_message($title=NULL, $message=NULL, $linkURL=NULL, $type=NULL, $linkText=NULL, $overwriteSame=NULL, $priority=NULL) { + if(!isset($overwriteSame)) { + $overwriteSame = 1; + } + + //defines the importance level of each type of message: the higher the value, the more important it is. + $priorityArr = array( + 'notice' => 10, + 'status' => 20, + 'error' => 30, + 'fatal' => 100 + ); + if(!isset($type) || !isset($priorityArr[$type])) { + //set a default type. + $arrayKeys = array_keys(); + $type = $arrayKeys[0]; + } + + if(strlen($linkURL)) { + if(!strlen($linkText) || is_null($linkText)) { + $linkText = "Link"; + } + $redirectText = '<a href="'. $linkURL .'">'. $linkText .'</a>'; + } + + //Create the array. + $myArr = array( + "title" => $title, + "message" => $message, + "redirect" => $redirectText, + "type" => $type, + "priority" => $priority + + ); + + //make sure the message type is IN the priority array... + if(!in_array($type, array_keys($priorityArr))) { + //invalid type. + $retval = FALSE; + } elseif($_SESSION['message']) { + //there's already a message... check if the new one should overwrite the existing. + if((!$overwriteSame) AND ($priorityArr[$_SESSION['message']['type']] == $priorityArr[$type])) { + //no overwriting. + $retval = FALSE; + } elseif($priorityArr[$_SESSION['message']['type']] <= $priorityArr[$type]) { + // the existing message is less important. Overwrite it. + $_SESSION['message'] = $myArr; + } + } + else { + $_SESSION['message'] = $myArr; + $retval = TRUE; + } + + return($retval); + + } // end of set_message() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + public function set_message_wrapper($array) { + @$this->set_message( + $array['title'], + $array['message'], + $array['linkURL'], + $array['type'], + $array['linkText'], + $array['overwriteSame'], + $array['priority'] + ); + }//end set_message_wrapper() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Performs redirection, provided it is allowed. + */ + function conditional_header($url, $exitAfter=TRUE) { + if($this->allowRedirect) { + //checks to see if headers were sent; if yes: use a meta redirect. + // if no: send header("location") info... + if(headers_sent()) { + //headers sent. Use the meta redirect. + print " + <HTML> + <HEAD> + <TITLE>Redirect Page</TITLE> + <META HTTP-EQUIV='refresh' content='0; URL=$url'> + </HEAD> + <a href=\"$url\"></a> + </HTML> + "; + } + else { + header("location:$url"); + } + + if($exitAfter) { + //redirecting without exitting is bad, m'kay? + exit; + } + } + else { + //TODO: should an exception be thrown, or maybe exit here anyway? + throw new exception(__METHOD__ .": auto redirects not allowed...?"); + } + }//end conditional_header() + //--------------------------------------------------------------------------------------------- + + + //--------------------------------------------------------------------------------------------- + /** + * Given the name of a templateVar (defaults to "content"), this method will retrieve all block + * row definitions in the order that they can safely be ripped-out/set by set_block_row(). + * + * @parm $templateVar (str,optional) templateVar to parse. + * + * @return (array) Contains all rows, complete & incomplete. + * + * NOTE: Layout of array::: + * array( + * incomplete => array( + * begin => array(), + * end => array() + * ), + * ordered => array() + * NOTE2: each "array()" above is a list of block row names. + * NOTE3: failure to parse the template will return a blank array. + * + * + */ + function get_block_row_defs($templateVar="content") { + //cast $retArr as an array, so it's clean. + $retArr = array(); + + //NOTE: the value 31 isn't just a randomly chosen length; it's the minimum + // number of characters to have a block row. EG: "<!-- BEGIN x -->o<!-- END x -->" + $templateContents = $this->templateVars[$templateVar]; + if(strlen($templateContents) >= 31) { + //looks good to me. Run the regex... + $flags = PREG_PATTERN_ORDER; + $reg = "/<!-- BEGIN (.+) -->/"; + preg_match_all($reg, $templateContents, $beginArr, $flags); + $beginArr = $beginArr[1]; + + $endReg = "/<!-- END (.+) -->/"; + preg_match_all($endReg, $templateContents, $endArr, $flags); + $endArr = $endArr[1]; + + //create a part of the array that shows any orphaned "BEGIN" statements (no matching "END" + // statement), and orphaned "END" statements (no matching "BEGIN" statements) + // NOTE::: by doing this, should easily be able to tell if the block rows were defined + // properly or not. + if(count($retArr['incomplete']['begin'] = array_diff($beginArr, $endArr)) > 0) { + //I'm sure there's an easier way to do this, but my head hurts too much when + // I try to do the magic. Maybe I need to put another level in CodeMancer... + foreach($retArr['incomplete']['begin'] as $num=>$val) { + unset($beginArr[$num]); + } + } + if(count($retArr['incomplete']['end'] = array_diff($endArr, $beginArr)) > 0) { + //both of the below foreach's simply pulls undefined vars out of the + // proper arrays, so I don't have to deal with them later. + foreach($retArr['incomplete']['end'] as $num=>$val) { + unset($endArr[$num]); + } + } + + //YAY!!! we've got valid data!!! + //reverse the order of the array, so when the ordered array + // is looped through, all block rows can be pulled. + $retArr['ordered'] = array_reverse($beginArr); + } else { + //nothin' doin'. Return a blank array. + $retArr = array(); + } + + return($retArr); + }//end get_block_row_defs() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + function rip_all_block_rows($templateVar="content", $exceptionArr=array()) { + $rowDefs = $this->get_block_row_defs($templateVar); + + $useTheseBlockRows = $rowDefs['ordered']; + $retval = array(); + if(is_array($useTheseBlockRows)) { + foreach($useTheseBlockRows as $blockRowName) + { + if(!in_array($blockRowName, $exceptionArr)) + { + //remove the block row. + $rowData = $this->set_block_row($templateVar, $blockRowName); + $retval[$blockRowName] = $rowData; + } + } + } + + return($retval); + }//end rip_all_block_rows() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + public function set_all_block_rows($templateVar="content", $exceptionArr=array()) + { + $retval = $this->rip_all_block_rows($templateVar, $exceptionArr); + return($retval); + }//end set_all_block_rows() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + public function allow_invalid_urls($newSetting=NULL) { + if(!is_null($newSetting) && is_bool($newSetting)) { + $this->allowInvalidUrls = $newSetting; + } + return($this->allowInvalidUrls); + }//end allow_invalid_urls() + //--------------------------------------------------------------------------------------------- + +}//end cs_genericPage{} +?> Property changes on: trunk/1.0/cs_genericPage.class.php ___________________________________________________________________ Added: svn:executable + * Added: svn:keywords + HeadURL Id LastChangedBy LastChangedDate LastChangedRevision Added: svn:mergeinfo + Added: svn:eol-style + native Deleted: trunk/1.0/cs_genericPageClass.php =================================================================== --- trunk/1.0/cs_genericPageClass.php 2009-01-29 21:04:18 UTC (rev 333) +++ trunk/1.0/cs_genericPageClass.php 2009-01-29 21:15:20 UTC (rev 334) @@ -1,619 +0,0 @@ -<?php -/* - * FILE INFORMATION: - * $HeadURL$ - * $Id$ - * $LastChangedDate$ - * $LastChangedBy$ - * $LastChangedRevision$ - */ -require_once(dirname(__FILE__) ."/template.inc"); -require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); - -class cs_genericPage extends cs_contentAbstract { - var $templateObj; //template object to parse the pages - var $templateVars = array(); //our copy of the global templateVars - var $mainTemplate; //the default layout of the site - - private $tmplDir; - private $libDir; - private $siteRoot; - private $allowRedirect; - - private $showEditableLink = FALSE; - - private $allowInvalidUrls=NULL; - - //--------------------------------------------------------------------------------------------- - /** - * The constructor. - */ - public function __construct($restrictedAccess=TRUE, $mainTemplateFile=NULL, $allowRedirect=TRUE) { - //handle some configuration. - $this->allowRedirect = $allowRedirect; - - //initialize stuff from our parent... - parent::__construct(); - - //initialize some internal stuff. - $this->initialize_locals($mainTemplateFile); - - //if they need to be logged-in... - $this->check_login($restrictedAccess); - - if(!defined('CS-CONTENT_SESSION_NAME')) { - define("CS-CONTENT_SESSION_NAME", ini_get('session.name')); - } - - //TODO: if the end page doesn't want to allow the "edit" links, will this still work? - if(defined("CS_CONTENT_MODIFIABLE") && constant("CS_CONTENT_MODIFIABLE") === TRUE) { - $this->showEditableLink = TRUE; - } - }//end __construct() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Initializes some internal objects, variables, and so on. - */ - protected function initialize_locals($mainTemplateFile) { - - //NOTE: this **requires** that the global variable "SITE_ROOT" is already set. - $this->siteRoot = preg_replace('/\/public_html/', '', $_SERVER['DOCUMENT_ROOT']); - $this->tmplDir = $this->siteRoot .'/templates'; - $this->libDir = $this->siteRoot .'/lib'; - - //if there have been some global template vars (or files) set, read 'em in here. - if(is_array($GLOBALS['templateVars']) && count($GLOBALS['templateVars'])) { - foreach($GLOBALS['templateVars'] as $key=>$value) { - $this->add_template_var($key, $value); - } - } - if(isset($GLOBALS['templateFiles']) && is_array($GLOBALS['templateFiles'])) { - foreach($GLOBALS['templateFiles'] as $key => $value) { - $this->templateFiles[$key] = $value; - } - } - unset($GLOBALS['templateVars'], $GLOBALS['templateFiles']); - - //build a new instance of the template library (from PHPLib) - $this->templateObj=new Template($this->tmplDir,"keep"); //initialize a new template parser - - if(preg_match('/^\//', $mainTemplateFile)) { - $mainTemplateFile = $this->tmplDir ."/". $mainTemplateFile; - } - $this->mainTemplate=$mainTemplateFile; //load the default layout - }//end initialize_locals() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Should just check to see if they've authenticated. In reality, this - * just performs blind redirection if $restrictedAccess is set (and if - * redirecting is allowed). - */ - public function check_login($restrictedAccess) { - if($restrictedAccess) { - $myUri = $_SERVER['SCRIPT_NAME']; - $doNotRedirectArr = array('/login.php', '/admin/login.php', '/index.php', '/admin.php', - '/content', '/content/index.php' - ); - $myUrlString=""; - $myGetArr = $_GET; - if(is_array($myGetArr) && count($myGetArr) > 0) { - unset($myGetArr['PHPSESSID']); - unset($myGetArr[CS-CONTENT_SESSION_NAME]); - $myUrlString = string_from_array($myGetArr, NULL, 'url'); - } - - //TODO: make the redirectHere variable dynamic--an argument, methinks. - $redirectHere = '/login.php?destination='. $myUrlString; - - //Not exitting after conditional_header() is... bad, m'kay? - $this->conditional_header($redirectHere, TRUE); - exit; - } - }//end check_login() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Remove all data from the special template var "content" (or optionally another ver). - * - * @param $section (str,optional) defines what template var to wip-out. - * @return (NULL) - */ - public function clear_content($section="content"){ - $this->change_content(" ",$section); - }//end clear_content() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Change the content of a template to the given data. - * - * @param $htmlString (str) data to use. - * @param $section (str,optional) define a different section. - * - * @return (NULL) - */ - public function change_content($htmlString,$section="content"){ - $this->templateVars[$section] = $htmlString; - }//end change_content() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Adds a template file (with the given handle) to be parsed. - * - * TODO: check if $fileName exists before blindly trying to parse it. - */ - public function add_template_file($handleName, $fileName){ - if($this->showEditableLink) { - $prefix = '[<a href="#NULL_page='. $fileName .'"><font color="red"><b>Edit "'. $handleName .'"</b></font></a>]<BR>'; - $this->add_template_var($handleName, $prefix .$this->file_to_string($fileName)); - } - else { - $this->add_template_var($handleName, $this->file_to_string($fileName)); - } - }//end add_template_file() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Adds a value for a template placeholder. - */ - public function add_template_var($varName, $varValue){ - $this->templateVars[$varName]=$varValue; - }//end add_template_var(); - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Rips the given block row name from the parent templateVar, (optionally) replacing it with - * a template var of the same name. - * - * @param $parent (str) name of the templateVar to pull the block row from. - * @param $handle (str) name of the block row to rip from it's parent. - * @param $removeDefs (bool,optional) if evaluated as FALSE, no template var is left in - * place of the block row. - * - * @return (bool false) FAIL: unable to find block row. - * @return (str) PASS: content of the block row. - */ - public function set_block_row($parent, $handle, $removeDefs=0) { - $name = $handle; - $str = $this->templateVars[$parent]; - - $reg = "/<!-- BEGIN $handle -->.+<!-- END $handle -->/sU"; - preg_match_all($reg, $str, $m); - if(!is_string($m[0][0])) { - #exit("set_block_row(): couldn't find '$handle' in var '$parent'"); - $retval = FALSE; - } else { - if($removeDefs) { - $openHandle = "<!-- BEGIN $handle -->"; - $endHandle = "<!-- END $handle -->"; - $m[0][0] = str_replace($openHandle, "", $m[0][0]); - $m[0][0] = str_replace($endHandle, "", $m[0][0]); - } - - $str = preg_replace($reg, "{" . "$name}", $str); - $this->templateVars[$parent] = $str; - $this->templateRows[$name] = $m[0][0]; - $this->add_template_var($name, ""); - $retval = $m[0][0]; - } - return($retval); - }//end set_block_row() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Using the given template, it will replace each index (in $repArr) with it's value: each - * var to be replaced must begin the given begin & end delimiters. - * - * @param $template (str) Data to perform the replacements on. - * @param $repArr (array) Array of name=>value pairs, where name is to be replaced with value. - * @param $b (str,optional) beginning delimiter. - * @param $e (str,optional) ending delimiter. - */ - public function mini_parser($template, $repArr, $b='%%', $e='%%') { - return($this->gfObj->mini_parser($template, $repArr, $b, $e)); - }//end mini_parser() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Processes all template vars & files, etc, to produce the final page. NOTE: it is a wise idea - * for most pages to have this called *last*. - * - * @param $stripUndefVars (bool,optional) Remove all undefined template vars. - * - * @return (str) Final, parsed page. - */ - public function print_page($stripUndefVars=1) { - //Show any available messages. - $this->process_set_message(); - - //Load the default page layout. - $this->templateObj->set_file("main", $this->mainTemplate); - - //load the placeholder names and thier values - $this->templateObj->set_var($this->templateVars); - $this->templateObj->parse("out","main"); //parse the sub-files into the main page - - if($stripUndefVars) { - $numLoops = 0; - while(preg_match_all('/\{.\S+?\}/', $this->templateObj->varvals['out'], $tags) && $numLoops < 50) { - $tags = $tags[0]; - - //TODO: figure out why this works when running it twice. - foreach($tags as $key=>$str) { - $str2 = str_replace("{", "", $str); - $str2 = str_replace("}", "", $str2); - if(!$this->templateVars[$str2] && $stripUndefVars) { - //TODO: set an internal pointer or something to use here, so they can see what was missed. - $this->templateObj->varvals[out] = str_replace($str, '', $this->templateObj->varvals[out]); - } - } - $this->templateObj->parse("out", "out"); - $numLoops++; - } - } - $this->templateObj->pparse("out","out"); //parse the main page - - }//end of print_page() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Handles a message that was set into the session. - */ - public function process_set_message() { - //if there's not a message set, skip. - $errorBox = ""; - if(isset($_SESSION['message']) && is_array($_SESSION['message'])) { - $errorBox = $this->file_to_string("system/message_box.tmpl"); - //let's make sure the "type" value is *lowercase*. - $_SESSION['message']['type'] = strtolower($_SESSION['message']['type']); - - //WARNING::: if you give it the wrong type, it'll STILL be parsed. Otherwise - // this has to match set_message() FAR too closely. And it's a pain. - $_SESSION['message']['messageType'] = $_SESSION['message']['type']; - $errorBox = $this->gfObj->mini_parser($errorBox, $_SESSION['message'], '{', '}'); - if($_SESSION['message']['type'] == "fatal") { - //replace content of the page with our error. - $this->change_content($errorBox); - } else { - //Non-fatal: put it into a template var. - $this->add_template_var("error_msg", $errorBox); - } - - //now that we're done displaying the message, let's get it out of the session (otherwise - // they'll never get past this point). - unset($_SESSION['message']); - } - return($errorBox); - }//end of process_set_message() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Takes a template file, whose root must be within $GLOBALS['TMPLDIR'], pulls it's - * content & returns it. - */ - public function file_to_string($templateFileName) { - $templateFileName = preg_replace('/\/\//', '\/', $templateFileName); - if($this->template_file_exists($templateFileName)) { - $retval = file_get_contents($this->tmplDir .'/'. $templateFileName); - } else { - $this->set_message_wrapper(array( - "title" => 'Template File Error', - "message" => 'Not all templates could be found for this page.', - "type" => 'error' - )); - } - return($retval); - }//end file_to_string() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Checks to see if the given filename exists within the template directory. - */ - public function template_file_exists($file) { - $retval = 0; - //If the string doesn't start with a /, add one - if (strncmp("/",$file,1)) { - //strncmp returns 0 if they match, so we're putting a / on if they don't - $file="/".$file; - } - $filename=$this->tmplDir.$file; - - if(file_exists($filename)) { - $retval = $filename; - } - return($retval); - }//end template_file_exists() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Creates an array in the session, used by the templating system as a way to - * get messages generated by the code into the page, without having to add - * special templates & such each time. - * - * @param $title (str) the title of the message. - * @param $message (str) text beneath the title. - * @param $linkURL (str,optional) URL for the link below the message. - * @param $type (str) notice/status/error/fatal message, indicating - * it's importance. Generally, fatal messages - * cause only the message to be shown. - * @param $linkText (str,optional) text that the link wraps. - * @param $overwriteSame (bool,optional) whether setting a message which has - * the same type as an already set message will - * overwite the previous. More important messages - * always overwrite lesser ones. - * @param $priority (int,optional) specify the message's priority. - * - * @return (bool) Indicates pass (true)/fail (false) - */ - function set_message($title=NULL, $message=NULL, $linkURL=NULL, $type=NULL, $linkText=NULL, $overwriteSame=NULL, $priority=NULL) { - if(!isset($overwriteSame)) { - $overwriteSame = 1; - } - - //defines the importance level of each type of message: the higher the value, the more important it is. - $priorityArr = array( - 'notice' => 10, - 'status' => 20, - 'error' => 30, - 'fatal' => 100 - ); - if(!isset($type) || !isset($priorityArr[$type])) { - //set a default type. - $arrayKeys = array_keys(); - $type = $arrayKeys[0]; - } - - if(strlen($linkURL)) { - if(!strlen($linkText) || is_null($linkText)) { - $linkText = "Link"; - } - $redirectText = '<a href="'. $linkURL .'">'. $linkText .'</a>'; - } - - //Create the array. - $myArr = array( - "title" => $title, - "message" => $message, - "redirect" => $redirectText, - "type" => $type, - "priority" => $priority - - ); - - //make sure the message type is IN the priority array... - if(!in_array($type, array_keys($priorityArr))) { - //invalid type. - $retval = FALSE; - } elseif($_SESSION['message']) { - //there's already a message... check if the new one should overwrite the existing. - if((!$overwriteSame) AND ($priorityArr[$_SESSION['message']['type']] == $priorityArr[$type])) { - //no overwriting. - $retval = FALSE; - } elseif($priorityArr[$_SESSION['message']['type']] <= $priorityArr[$type]) { - // the existing message is less important. Overwrite it. - $_SESSION['message'] = $myArr; - } - } - else { - $_SESSION['message'] = $myArr; - $retval = TRUE; - } - - return($retval); - - } // end of set_message() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - public function set_message_wrapper($array) { - @$this->set_message( - $array['title'], - $array['message'], - $array['linkURL'], - $array['type'], - $array['linkText'], - $array['overwriteSame'], - $array['priority'] - ); - }//end set_message_wrapper() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - /** - * Performs redirection, provided it is allowed. - */ - function conditional_header($url, $exitAfter=TRUE) { - if($this->allowRedirect) { - //checks to see if headers were sent; if yes: use a meta redirect. - // if no: send header("location") info... - if(headers_sent()) { - //headers sent. Use the meta redirect. - print " - <HTML> - <HEAD> - <TITLE>Redirect Page</TITLE> - <META HTTP-EQUIV='refresh' content='0; URL=$url'> - </HEAD> - <a href=\"$url\"></a> - </HTML> - "; - } - else { - header("location:$url"); - } - - if($exitAfter) { - //redirecting without exitting is bad, m'kay? - exit; - } - } - else { - //TODO: should an exception be thrown, or maybe exit here anyway? - throw new exception(__METHOD__ .": auto redirects not allowed...?"); - } - }//end conditional_header() - //--------------------------------------------------------------------------------------------- - - - //--------------------------------------------------------------------------------------------- - /** - * Given the name of a templateVar (defaults to "content"), this method will retrieve all block - * row definitions in the order that they can safely be ripped-out/set by set_block_row(). - * - * @parm $templateVar (str,optional) templateVar to parse. - * - * @return (array) Contains all rows, complete & incomplete. - * - * NOTE: Layout of array::: - * array( - * incomplete => array( - * begin => array(), - * end => array() - * ), - * ordered => array() - * NOTE2: each "array()" above is a list of block row names. - * NOTE3: failure to parse the template will return a blank array. - * - * - */ - function get_block_row_defs($templateVar="content") { - //cast $retArr as an array, so it's clean. - $retArr = array(); - - //NOTE: the value 31 isn't just a randomly chosen length; it's the minimum - // number of characters to have a block row. EG: "<!-- BEGIN x -->o<!-- END x -->" - $templateContents = $this->templateVars[$templateVar]; - if(strlen($templateContents) >= 31) { - //looks good to me. Run the regex... - $flags = PREG_PATTERN_ORDER; - $reg = "/<!-- BEGIN (.+) -->/"; - preg_match_all($reg, $templateContents, $beginArr, $flags); - $beginArr = $beginArr[1]; - - $endReg = "/<!-- END (.+) -->/"; - preg_match_all($endReg, $templateContents, $endArr, $flags); - $endArr = $endArr[1]; - - //create a part of the array that shows any orphaned "BEGIN" statements (no matching "END" - // statement), and orphaned "END" statements (no matching "BEGIN" statements) - // NOTE::: by doing this, should easily be able to tell if the block rows were defined - // properly or not. - if(count($retArr['incomplete']['begin'] = array_diff($beginArr, $endArr)) > 0) { - //I'm sure there's an easier way to do this, but my head hurts too much when - // I try to do the magic. Maybe I need to put another level in CodeMancer... - foreach($retArr['incomplete']['begin'] as $num=>$val) { - unset($beginArr[$num]); - } - } - if(count($retArr['incomplete']['end'] = array_diff($endArr, $beginArr)) > 0) { - //both of the below foreach's simply pulls undefined vars out of the - // proper arrays, so I don't have to deal with them later. - foreach($retArr['incomplete']['end'] as $num=>$val) { - unset($endArr[$num]); - } - } - - //YAY!!! we've got valid data!!! - //reverse the order of the array, so when the ordered array - // is looped through, all block rows can be pulled. - $retArr['ordered'] = array_reverse($beginArr); - } else { - //nothin' doin'. Return a blank array. - $retArr = array(); - } - - return($retArr); - }//end get_block_row_defs() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - function rip_all_block_rows($templateVar="content", $exceptionArr=array()) { - $rowDefs = $this->get_block_row_defs($templateVar); - - $useTheseBlockRows = $rowDefs['ordered']; - $retval = array(); - if(is_array($useTheseBlockRows)) { - foreach($useTheseBlockRows as $blockRowName) - { - if(!in_array($blockRowName, $exceptionArr)) - { - //remove the block row. - $rowData = $this->set_block_row($templateVar, $blockRowName); - $retval[$blockRowName] = $rowData; - } - } - } - - return($retval); - }//end rip_all_block_rows() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - public function set_all_block_rows($templateVar="content", $exceptionArr=array()) - { - $retval = $this->rip_all_block_rows($templateVar, $exceptionArr); - return($retval); - }//end set_all_block_rows() - //--------------------------------------------------------------------------------------------- - - - - //--------------------------------------------------------------------------------------------- - public function allow_invalid_urls($newSetting=NULL) { - if(!is_null($newSetting) && is_bool($newSetting)) { - $this->allowInvalidUrls = $newSetting; - } - return($this->allowInvalidUrls); - }//end allow_invalid_urls() - //--------------------------------------------------------------------------------------------- - -}//end cs_genericPage{} -?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-29 21:04:23
|
Revision: 333 http://cs-content.svn.sourceforge.net/cs-content/?rev=333&view=rev Author: crazedsanity Date: 2009-01-29 21:04:18 +0000 (Thu, 29 Jan 2009) Log Message: ----------- Rename cs_fileSystemClass.php to cs_fileSystem.class.php & change name to match. /contentSystem.class.php: * MAIN::: -- fix require_once() statement to point to proper file * __construct(): -- use new class name cs_fileSystem{} /cs_fileSystem.class.php [RENAMED FROM cs_fileSystemClass.php] /cs_fileSystemClass.php [RENAMED TO cs_fileSystem.class.php] /cs_siteConfig.class.php: * MAIN::: -- fix require_once statement for cs_fileSystem. -- update comments to reference appropriate class name. * __construct(): -- update references to use new class name. Modified Paths: -------------- trunk/1.0/contentSystem.class.php trunk/1.0/cs_siteConfig.class.php Added Paths: ----------- trunk/1.0/cs_fileSystem.class.php Removed Paths: ------------- trunk/1.0/cs_fileSystemClass.php Modified: trunk/1.0/contentSystem.class.php =================================================================== --- trunk/1.0/contentSystem.class.php 2009-01-29 20:40:16 UTC (rev 332) +++ trunk/1.0/contentSystem.class.php 2009-01-29 21:04:18 UTC (rev 333) @@ -71,7 +71,7 @@ } require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); -require_once(dirname(__FILE__) ."/cs_fileSystemClass.php"); +require_once(dirname(__FILE__) ."/cs_fileSystem.class.php"); require_once(dirname(__FILE__) ."/cs_sessionClass.php"); require_once(dirname(__FILE__) ."/cs_genericPageClass.php"); require_once(dirname(__FILE__) ."/cs_tabsClass.php"); @@ -145,7 +145,7 @@ $this->templateObj->add_template_var('CURRENT_URL', $myUrl); //create a fileSystem object. - $this->fileSystemObj = new cs_fileSystemClass(); + $this->fileSystemObj = new cs_fileSystem(); //create a tabs object, in case they want to load tabs on the page. $this->tabs = new cs_tabs($this->templateObj); Copied: trunk/1.0/cs_fileSystem.class.php (from rev 331, trunk/1.0/cs_fileSystemClass.php) =================================================================== --- trunk/1.0/cs_fileSystem.class.php (rev 0) +++ trunk/1.0/cs_fileSystem.class.php 2009-01-29 21:04:18 UTC (rev 333) @@ -0,0 +1,969 @@ +<?php + +/* + * FILE INFORMATION: + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); + +class cs_fileSystem extends cs_contentAbstract { + + public $root; //actual root directory. + public $cwd; //current directory; relative to $this->root + public $realcwd; //$this->root .'/'. $this->cwd + public $dh; //directory handle. + public $fh; //file handle. + public $filename; //filename currently being used. + public $lineNum = NULL; + + + //======================================================================================== + /** + * The constructor. + */ + public function __construct($rootDir=NULL, $cwd=NULL, $initialMode=NULL) { + //set the root directory that we'll be using; this is considered just like "/" in + // linux. Directories above it are considered non-existent. + if(($rootDir) AND (is_dir($rootDir))) { + // yup... use it. + $this->root = $rootDir; + } elseif(($GLOBALS['SITE_ROOT']) AND (is_dir($GLOBALS['SITE_ROOT']))) { + //not set, but SITE_ROOT is... use it. + $this->root = $GLOBALS['SITE_ROOT']; + } else { + //nothing useable... die. + exit("UNUSEABLE ROOT: $rootDir"); + } + + parent::__construct(); + + $this->root = $this->resolve_path_with_dots($this->root); + + //set the CURRENT working directory... this should be a RELATIVE path to $this->root. + if(($cwd) AND (is_dir($rootDir .'/'. $cwd)) AND (!ereg($this->root, $cwd))) { + //looks good. Use it. + $this->cwd = $cwd; + $this->realcwd = $this->root .'/'. $cwd; + } else { + //no dice. Use the root. + $this->cwd = '/'; + $this->realcwd = $this->root ; + } + chdir($this->realcwd); + + //check for the initialMode... + $useableModes = array('r', 'r+', 'w', 'w+', 'a', 'a+', 'x', 'x+'); + if(($initialMode) AND (in_array($initialMode, $useableModes))) { + // + $this->mode = $initialMode; + } else { + //define the DEFAULT mode. + $this->mode = "r+"; + } + + }//end __construct() + //======================================================================================== + + + + //======================================================================================== + public function cdup() { + $retval = FALSE; + //easy way to go "up" a directory (just like doing "cd .." in linux) + if(strlen($this->cwd) > 1) { + $myCwd = preg_replace('/\/$/', '', $this->cwd); + if(!preg_match('/^\//', $myCwd)) { + $myCwd = '/'. $myCwd; + } + $myParts = explode('/', $myCwd); + array_pop($myParts); + $myCwd = $this->gfObj->string_from_array($myParts, NULL, '/'); + $realCwd = $this->gfObj->create_list($this->root, $myCwd, '/'); + if(file_exists($realCwd)) { + $retval = TRUE; + $this->realcwd = $realCwd; + $this->cwd = '/'. $myCwd; + } + } + + return($retval); + }//end cdup() + //======================================================================================== + + + + //======================================================================================== + /** + * Think of the linux version of "cd": we're changing the current directory. + * + * @param $newDir (str) dir to change to, either absolutte or relative. + * + * @return 0 (FAIL) unable to change directory + * @return 1 (PASS) success. + */ + public function cd($newDir) { + + //check to see if it's a relative path or not... + //NOTE: non-relative paths should NOT include $this->root. + if((preg_match('/^\//', $newDir)) AND (is_dir($this->root .'/'. $newDir))) { + //not a relative path. + $this->cwd = '/'. $newDir; + $this->realcwd = $this->root . $newDir; + $retval = 1; + } elseif(is_dir($this->realcwd .'/'. $newDir)) { + //relative path... + $this->cwd = $this->gfObj->create_list($this->cwd, $newDir, '/'); + $this->realcwd .= '/'. $newDir; + $retval = 1; + } else { + //bad. + $retval = 0; + } + $this->cwd = preg_replace('/\/\//', '/', $this->cwd); + $this->realcwd = preg_replace('/\/\//', '/', $this->realcwd); + + return($retval); + }//end cd() + //======================================================================================== + + + //======================================================================================== + /** + * Just like the linux version of the 'ls' command. + */ + public function ls($filename=NULL, $args=NULL) { + + clearstatcache(); + //open the directory for reading. + $this->dh = opendir($this->realcwd); + clearstatcache(); + if(is_string($filename)) { + //check to make sure the file exists. + $tFile=$this->filename2absolute($filename); + if(file_exists($tFile)) { + //it's there... get info about it. + $info = $this->get_fileinfo($tFile); + if($info['type'] == 'dir') { + $oldCwd = $this->cwd; + $oldRealCwd = $this->realcwd; + + $this->cd($filename); + $retval = $this->ls(); + + $this->cwd = $oldCwd; + $this->realcwd = $oldRealCwd; + } + else { + $retval[$filename] = $info; + } + } else { + //stupid! + $retval[$filename] = "FILE NOT FOUND."; + } + } else { + //array if file/directory names to ignore if matched exactly. + $ignoreArr = array("CVS", ".svn", ".", ".."); + while (($file = readdir($this->dh)) !== false) { + if(!in_array($file, $ignoreArr)) { + $tFile = $this->realcwd .'/'. $file; + $tType = filetype($tFile); + $retval[$file] = $this->get_fileinfo($tFile); + if(!$tType) { + debug_print("FILE: $tFile || TYPE: $tType || is_file(): ". is_file($tFile) ."is_dir(): ". is_dir($tFile)); + exit; + } + #debug_print("FILE: $file || $dir". $file); + unset($tType); + } + } + } + #debug_print($retval); + #debug_print(readdir($this->dh)); + return($retval); + }//end ls() + //======================================================================================== + + + //======================================================================================== + /** + * Grabs an array of information for a given file. + */ + public function get_fileinfo($tFile) { + + $retval = array( + "size" => filesize($tFile), + "type" => @filetype($tFile), + "accessed" => fileatime($tFile), + "modified" => filemtime($tFile), + "owner" => $this->my_getuser_group(fileowner($tFile), 'uid'), + "uid" => fileowner($tFile), + "group" => $this->my_getuser_group(filegroup($tFile), 'gid'), + "gid" => filegroup($tFile), + "perms" => $this->translate_perms(fileperms($tFile)), + "perms_num" => substr(sprintf('%o', fileperms($tFile)), -4) + ); + + return($retval); + }//end get_fileinfo() + //======================================================================================== + + + + //======================================================================================== + /** + * Gets the username/groupname of the given uid/gid. + * + * @param $int (int) uid/gid to check. + * @param $type (str) is it a uid or a gid? + * + * @return (string) groupname/username + */ + private function my_getuser_group($int, $type='uid') { + + if($type == 'uid') { + $func = 'posix_getpwuid'; + } elseif($type == 'gid') { + $func = 'posix_getgrgid'; + } else { + $retval = $int; + } + + if(!function_exists($func)) { + throw new exception(__METHOD__ .": required function missing (". $func .")"); + } + $t = $func($int); + return($t['name']); + + }//end my_getpwuid() + //======================================================================================== + + + + //======================================================================================== + /** + * Translates the permissions string (like "0700") into a *nix-style permissions + * string (i.e. "rwx------"). + * + * @param $in_Perms (int) permission number string + * + * @return (string) permissions string. + * + * NOTE: pretty sure I copied this from php.net, though I don't know the owner. If anybody + * can enlighten me, I'd be glad to give them credit. + */ + private function translate_perms($in_Perms) { + $sP = ""; + $sP .= (($in_Perms & 0x0100) ? 'r' : '-') . + (($in_Perms & 0x0080) ? 'w' : '-') . + (($in_Perms & 0x0040) ? (($in_Perms & 0x0800) ? 's' : 'x' ) : + (($in_Perms & 0x0800) ? 'S' : '-')); + // group + $sP .= (($in_Perms & 0x0020) ? 'r' : '-') . + (($in_Perms & 0x0010) ? 'w' : '-') . + (($in_Perms & 0x0008) ? (($in_Perms & 0x0400) ? 's' : 'x' ) : + (($in_Perms & 0x0400) ? 'S' : '-')); + + // world + $sP .= (($in_Perms & 0x0004) ? 'r' : '-') . + (($in_Perms & 0x0002) ? 'w' : '-') . + (($in_Perms & 0x0001) ? (($in_Perms & 0x0200) ? 't' : 'x' ) : + (($in_Perms & 0x0200) ? 'T' : '-')); + return($sP); + }//end translate_perms() + //======================================================================================== + + + //======================================================================================== + /** + * Creates an empty file... think of the linux command "touch". + * + * @param $filename (string) filename to create. + * + * @return 0 (FAIL) unable to create file. + * @return 1 (PASS) file created successfully. + */ + public function create_file($filename, $truncateFile=FALSE) { + + $retval = 0; + $filename = $this->filename2absolute($filename); + $filename = $this->resolve_path_with_dots($filename); + $this->filename = $filename; + + //check to see if the file exists... + if(!file_exists($filename)) { + if($this->is_writable(dirname($filename))) { + //no file. Create it. + $createFileRes = touch($filename); + if($createFileRes) { + $retval = 1; + } + else { + throw new exception(__METHOD__ .": invalid return from touch(". $filename ."), return was (". $createFileRes .")"); + } + } + else { + throw new exception(__METHOD__ .": directory (". dirname($filename) .") is not writable"); + } + } + elseif($truncateFile === TRUE) { + $this->truncate_file($filename); + } + else { + throw new exception(__METHOD__ .": file (". $filename .") exists and truncate not set"); + } + return($retval); + }//end create_file() + //======================================================================================== + + + + //======================================================================================== + /** + * Opens a stream/resource handle to use for doing file i/o. + * + * @param $filename (string) filename to open: should be relative to the current dir. + * @param $mode (string) mode to use: consult PHP.net's info for fopen(). + * + * @return 0 (FAIL) unable to open file. + * @return 1 (PASS) file opened successfully. + */ + public function openFile($filename=NULL, $mode="r+") { + clearstatcache(); + if(!strlen($filename) || is_null($filename)) { + $filename = $this->filename; + } + $filename = $this->filename2absolute($filename); + $this->filename = $filename; + + if($this->is_readable($filename)) { + //make sure we've got a mode to use. + + if(!is_string($mode)) { + $mode = "r+"; + } + $this->mode = $mode; + + if(in_array($this->mode, array("r+", "w", "w+", "a", "a+", "x", "x+")) && !$this->is_writable($filename)) { + throw new exception(__METHOD__ .": file is not writable (". $filename .") (". $this->is_writable($filename) ."), mode=(". $this->mode .")"); + } + + //attempt to open a stream to a file... + $this->fh = fopen($this->filename, $this->mode); + if(is_resource($this->fh)) { + //looks like we opened successfully. + $retval = 1; + $this->lineNum = 0; + } else { + //something bad happened. + $retval = 0; + } + } + else { + throw new exception(__METHOD__ .": file is unreadable (". $filename .")"); + } + + return($retval); + }//end openFile() + //======================================================================================== + + + //======================================================================================== + /** + * Write the given contents into the current file or the filename given. + * + * @param $content (str) Content to write into the file. + * @param $filename (str,optional) filename to use. If none given, the current one is used. + * + * @return 0 (FAIL) unable to write content to the file. + * @return (n) (PASS) wrote (n) bytes. + */ + public function write($content, $filename=NULL) { + + //open the file for writing. + if(!$filename) { + $filename= $this->filename; + } + $this->filename = $filename; + + //open the file... + $openResult = $this->openFile($this->filename, $this->mode); + + //looks like we made it... + $retval = fwrite($this->fh, $content, strlen($content)); + + //done... return the result. + return($retval); + }//end write() + //======================================================================================== + + + //======================================================================================== + /** + * Takes the given filename & returns the ABSOLUTE pathname: checks to see if the given + * string already has the absolute path in it. + */ + private function filename2absolute($filename) { + + clearstatcache(); + + $filename = $this->resolve_path_with_dots($filename); + + //see if it starts with a "/"... + if(preg_match("/^\//", $filename)) { + $retval = $filename; + } else { + $retval=$this->realcwd .'/'. $filename; + $retval = $this->resolve_path_with_dots($retval); + #debug_print(__METHOD__ .": realcwd=(". $this->realcwd .")"); + #$this->resolve_path_with_dots($retval); + } + + if(!$this->check_chroot($retval, FALSE)) { + $this->gfObj->debug_print(func_get_args()); + throw new exception(__METHOD__ .": file is outside of allowed directory (". $retval .")"); + } + + return($retval); + + }//end filename2absolute() + //======================================================================================== + + + + //======================================================================================== + /** + * Reads-in the contents of an entire file. + */ + function read($filename, $returnArray=FALSE) { + $myFile = $this->filename2absolute($filename); + if(!file_exists($myFile)) { + throw new exception(__METHOD__ .": file doesn't exist (". $myFile .")"); + } + elseif($this->is_readable($myFile)) { + if($returnArray) { + $data = file($myFile); + } + else { + $data = file_get_contents($myFile); + } + + if($data === FALSE) { + throw new exception(__METHOD__. ": file_get_contents() returned FALSE"); + } + } + else { + throw new exception(__METHOD__. ": File isn't readable (". $myFile .")"); + } + return($data); + }//end read() + //======================================================================================== + + + + //======================================================================================== + public function rm($filename) { + $filename = $this->filename2absolute($filename); + return(unlink($filename)); + }//end rm() + //======================================================================================== + + + + //======================================================================================== + public function rmdir($dirname) { + $dirname = $this->filename2absolute($dirname); + return(rmdir($dirname)); + }//end rm() + //======================================================================================== + + + + //======================================================================================== + /** + * Return the next line for a file. + * + * When the end of the file is found, this method returns FALSE (returning NULL might be + * misconstrued as a blank line). + */ + public function get_next_line($maxLength=NULL, $trimLine=TRUE) { + if(is_resource($this->fh) && get_resource_type($this->fh) == 'stream') { + if(feof($this->fh)) { + $retval = FALSE; + } + else { + if(!is_numeric($maxLength)) { + $retval = @fgets($this->fh); + } + else { + $retval = fgets($this->fh, $maxLength); + } + if($trimLine) { + $retval = trim($retval); + } + + if(is_null($this->lineNum) || !is_numeric($this->lineNum) || $this->lineNum < 0) { + throw new exception(__METHOD__ .": invalid data for lineNum (". $this->lineNum .")"); + } + $this->lineNum++; + } + } + else { + throw new exception(__METHOD__ .": invalid filehandle"); + } + + return($retval); + }//end get_next_line() + //======================================================================================== + + + + //======================================================================================== + public function append_to_file($data, $eolChar="\n") { + $retval = FALSE; + if(is_resource($this->fh)) { + $result = fwrite($this->fh, $data . $eolChar); + if($result === FALSE) { + throw new exception(__METHOD__ .": failed to write data to file"); + } + else { + $this->lineNum++; + $retval = $result; + } + } + else { + throw new exception(__METHOD__ .": invalid filehandle"); + } + + return($retval); + }//end append_to_file() + //======================================================================================== + + + + //======================================================================================== + public function closeFile() { + $retval = FALSE; + if(is_resource($this->fh)) { + fclose($this->fh); + $retval = TRUE; + } + + //reset internal pointers. + $this->filename = NULL; + $this->lineNum = NULL; + + return($retval); + }//end closeFile() + //======================================================================================== + + + + //======================================================================================== + /** + * Compare the given filename to the open filename to see if they match (using this allows + * giving a filename instead of comparing the whole path). + */ + public function compare_open_filename($compareToFilename) { + if(!strlen($compareToFilename) || is_null($compareToFilename)) { + throw new exception(__METHOD__ .": invalid filename to compare"); + } + elseif(!strlen($this->filename)) { + $retval = FALSE; + } + else { + $internalFilename = $this->filename2absolute($this->filename); + $compareToFilename = $this->filename2absolute($compareToFilename); + if($internalFilename == $compareToFilename) { + $retval = TRUE; + } + else { + $retval = FALSE; + } + } + + return($retval); + }//end compare_open_filename() + //======================================================================================== + + + + //======================================================================================== + /** + * Give a file a new name. + * + * TODO: check to make sure both files exist within our root. + */ + public function rename($currentFilename, $newFilename) { + if($newFilename == $currentFilename) { + $this->gfObj->debug_print(func_get_args()); + throw new exception(__METHOD__ .": renaming file to same name"); + } + + if($this->compare_open_filename($currentFilename)) { + $this->closeFile(); + } + + if($this->compare_open_filename($newFilename)) { + //renaming a different file to our currently open file... + $this->gfObj->debug_print(func_get_args()); + throw new exception(__METHOD__ .": renaming another file (". $currentFilename .") to the currently open filename (". $newFilename .")"); + } + else { + + $currentFilename = $this->filename2absolute($currentFilename); + $newFilename = $this->filename2absolute($newFilename); + + if(!$this->is_writable(dirname($newFilename))) { + throw new exception(__METHOD__ .": directory isn't writable... "); + } + $retval = rename($currentFilename, $newFilename); + if($retval !== TRUE) { + throw new exception(__METHOD__ .": failed to rename file (". $retval .")"); + } + } + + return($retval); + + }//end rename() + //======================================================================================== + + + + //======================================================================================== + /** + * Check if the given filename is executable. + */ + public function is_executable($filename) { + $filename = $this->filename2absolute($filename); + $retval = FALSE; + if(strlen($filename)) { + $retval = is_executable($filename); + } + + return($retval); + }//end is_executable() + //======================================================================================== + + + + //======================================================================================== + /** + * Check if the given filename is readable. + */ + public function is_readable($filename) { + $filename = $this->filename2absolute($filename); + $retval = FALSE; + if(strlen($filename)) { + $retval = is_readable($filename); + } + + return($retval); + }//end is_readable() + //======================================================================================== + + + + //======================================================================================== + /** + * Check if the given filename/path is writable + */ + public function is_writable($filenameOrPath) { + $filenameOrPath = $this->filename2absolute($filenameOrPath); + $retval = FALSE; + if(strlen($filenameOrPath)) { + $retval = is_writable($filenameOrPath); + } + + return($retval); + }//end is_writable() + //======================================================================================== + + + + //======================================================================================== + /** + * Determines how many lines are left in the current file. + */ + public function count_remaining_lines() { + if(is_resource($this->fh) && get_resource_type($this->fh) == 'stream') { + $originalLineNum = $this->lineNum; + + $myFilename = $this->filename; + $myNextLine = $this->get_next_line(); + $retval = 0; + while($myNextLine !== FALSE) { + $retval++; + $myNextLine = $this->get_next_line(); + } + + $this->closeFile(); + $this->openFile($myFilename, $this->mode); + + if($originalLineNum > 0) { + while($originalLineNum > $this->lineNum) { + $this->get_next_line(); + } + } + + if($this->lineNum !== $originalLineNum) { + throw new exception(__METHOD__ .": failed to match-up old linenum (". $originalLineNum .") with the current one (". $this->lineNum .")"); + } + } + else { + throw new exception(__METHOD__ .": Invalid filehandle, can't count remaining lines"); + } + + return($retval); + }//end count_remaining_files() + //======================================================================================== + + + + //======================================================================================== + /** + * Moves the cursor to the given line number. + * + * NOTE: remember if you're trying to get line #1 (literally), then you'll + * want to go to line #0, then call get_next_line() to retrieve it... this + * is the traditional logical vs. programatic numbering issue. A.k.a. the + * "off-by-one problem". + */ + public function go_to_line($lineNum) { + $retval = FALSE; + if(is_resource($this->fh) && get_resource_type($this->fh) == 'stream') { + if($this->lineNum > $lineNum) { + //gotta "rewind" the cursor back to the beginning. + rewind($this->fh); + $this->lineNum=0; + } + + if($lineNum == $this->lineNum) { + $retval = TRUE; + } + elseif($this->lineNum < $lineNum) { + while($this->lineNum < $lineNum) { + //don't grab any data, just move the cursor... + $this->get_next_line(); + } + if($this->lineNum == $lineNum) { + $retval = TRUE; + } + else { + throw new exception(__METHOD__ .": couldn't reach the line (". $lineNum ."), failed at (". $this->lineNum .")"); + } + } + else { + throw new exception(__METHOD__ .": internal lineNum (". $this->lineNum .") couldn't be retrieved or reset to (". $lineNum .")"); + } + } + + return($retval); + }//end go_to_line() + //======================================================================================== + + + + //======================================================================================== + /** + * Fix a path that contains "../". + * + * EXAMPLE: changes "/home/user/blah/blah/../../test" into "/home/user/test" + */ + public function resolve_path_with_dots($path) { + + while(preg_match('/\/\//', $path)) { + $path = preg_replace('/\/\//', '/', $path); + } + $retval = $path; + if(strlen($path) && preg_match('/\./', $path)) { + + $isAbsolute = FALSE; + if(preg_match('/^\//', $path)) { + $isAbsolute = TRUE; + $path = preg_replace('/^\//', '', $path); + } + $pieces = explode('/', $path); + + $finalPieces = array(); + for($i=0; $i < count($pieces); $i++) { + $dirName = $pieces[$i]; + if($dirName == '.') { + //do nothing; don't bother appending. + } + elseif($dirName == '..') { + $rippedIndex = array_pop($finalPieces); + } + else { + $finalPieces[] = $dirName; + } + } + + $retval = $this->gfObj->string_from_array($finalPieces, NULL, '/'); + if($isAbsolute) { + $retval = '/'. $retval; + } + } + + return($retval); + }//end resolve_path_with_dots() + //======================================================================================== + + + + //======================================================================================== + private function check_chroot($path, $translatePath=TRUE) { + if($translatePath === TRUE) { + $path = $this->filename2absolute($path); + } + + //now, let's go through the root directory structure, & make sure $path is within that. + $rootPieces = explode('/', $this->root); + $pathPieces = explode('/', $path); + + + if($rootPieces[0] == '') { + array_shift($rootPieces); + } + if($rootPieces[(count($rootPieces) -1)] == '') { + array_pop($rootPieces); + } + if($pathPieces[0] == '') { + array_shift($pathPieces); + } + + $retval = TRUE; + $tmp = ''; + foreach($rootPieces as $index=>$dirName) { + $pathDir = $pathPieces[$index]; + if($pathDir != $dirName) { + $retval = FALSE; + $this->gfObj->debug_print(__METHOD__ .": failed... tmp=(". $tmp ."), dirName=(". $dirName .")"); + break; + } + $tmp = $this->gfObj->create_list($tmp, $dirName, '/'); + } + + return($retval); + }//end check_chroot() + //======================================================================================== + + + + //======================================================================================== + public function copy_file($filename, $destination) { + $retval = FALSE; + if($this->openFile($filename)) { + if($this->check_chroot($destination)) { + //okay, try to copy. + $retval = copy($this->fh, $destination); + } + else { + throw new exception(__METHOD__ .':: destination is not in the directory path'); + } + } + + return($retval); + }//end copy_file() + //======================================================================================== + + + + //======================================================================================== + public function move_file($filename, $destination) { + $retval = FALSE; + if($this->is_readable($filename)) { + if($this->check_chroot($destination)) { + //do the move. + $retval = rename($filename, $destination); + } + else { + $this->gfObj->debug_print(__METHOD__ .":: ". $this->check_chroot($destination),1); + throw new exception(__METHOD__ .':: destination is not in the directory path (from=['. $filename .'], to=['. $destination .']'); + } + } + + return($retval); + }//end move_file() + //======================================================================================== + + + + //======================================================================================== + public function mkdir($name, $mode=0777) { + if(!is_numeric($mode) || strlen($mode) != 4) { + $mode = 0777; + } + $retval = NULL; + if(!is_null($name) && strlen($name)) { + $name = $this->filename2absolute($name); + if($this->check_chroot($name)) { + $retval = mkdir($name, $mode); + chmod($name, $mode); + } + else { + throw new exception(__METHOD__ .': ('. $name .') isn\'t within chroot'); + } + } + else { + cs_debug_backtrace(1); + throw new exception(__METHOD__ .': invalid data: ('. $name .')'); + } + + return($retval); + }//end mkdir() + //======================================================================================== + + + + //======================================================================================== + public function truncate_file($filename) { + if($this->is_writable($filename)) { + if($this->openFile($filename)) { + $retval = ftruncate($this->fh,0); + $this->closeFile(); + } + else { + throw new exception(__METHOD__ .": unable to open specified file (". $filename .")"); + } + } + else { + throw new exception(__METHOD__ .": Cannot truncate, file (". $filename .") is not writable"); + } + + return($retval); + }//end truncate_file() + //======================================================================================== + + + + //======================================================================================== + public function go_to_last_line() { + if(is_resource($this->fh) && get_resource_type($this->fh) == 'stream') { + if(feof($this->fh)) { + $retval = TRUE; + } + else { + //NOTE::: fseek() doesn't update the file pointer in $this->fh, so we have to use fgets(), which seems faster anyway. + while(!feof($this->fh)) { + fgets($this->fh); + $this->lineNum++; + } + $retval = TRUE; + } + } + else { + throw new exception(__METHOD__ .": invalid filehandle"); + } + + return($retval); + }//end go_to_last_line() + //======================================================================================== + + +}//end cs_filesystemClass{} +?> Property changes on: trunk/1.0/cs_fileSystem.class.php ___________________________________________________________________ Added: svn:keywords + HeadURL Id LastChangedBy LastChangedDate LastChangedRevision Added: svn:mergeinfo + Added: svn:eol-style + native Deleted: trunk/1.0/cs_fileSystemClass.php =================================================================== --- trunk/1.0/cs_fileSystemClass.php 2009-01-29 20:40:16 UTC (rev 332) +++ trunk/1.0/cs_fileSystemClass.php 2009-01-29 21:04:18 UTC (rev 333) @@ -1,969 +0,0 @@ -<?php - -/* - * FILE INFORMATION: - * $HeadURL$ - * $Id$ - * $LastChangedDate$ - * $LastChangedBy$ - * $LastChangedRevision$ - */ - -require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); - -class cs_fileSystemClass extends cs_contentAbstract { - - public $root; //actual root directory. - public $cwd; //current directory; relative to $this->root - public $realcwd; //$this->root .'/'. $this->cwd - public $dh; //directory handle. - public $fh; //file handle. - public $filename; //filename currently being used. - public $lineNum = NULL; - - - //======================================================================================== - /** - * The constructor. - */ - public function __construct($rootDir=NULL, $cwd=NULL, $initialMode=NULL) { - //set the root directory that we'll be using; this is considered just like "/" in - // linux. Directories above it are considered non-existent. - if(($rootDir) AND (is_dir($rootDir))) { - // yup... use it. - $this->root = $rootDir; - } elseif(($GLOBALS['SITE_ROOT']) AND (is_dir($GLOBALS['SITE_ROOT']))) { - //not set, but SITE_ROOT is... use it. - $this->root = $GLOBALS['SITE_ROOT']; - } else { - //nothing useable... die. - exit("UNUSEABLE ROOT: $rootDir"); - } - - parent::__construct(); - - $this->root = $this->resolve_path_with_dots($this->root); - - //set the CURRENT working directory... this should be a RELATIVE path to $this->root. - if(($cwd) AND (is_dir($rootDir .'/'. $cwd)) AND (!ereg($this->root, $cwd))) { - //looks good. Use it. - $this->cwd = $cwd; - $this->realcwd = $this->root .'/'. $cwd; - } else { - //no dice. Use the root. - $this->cwd = '/'; - $this->realcwd = $this->root ; - } - chdir($this->realcwd); - - //check for the initialMode... - $useableModes = array('r', 'r+', 'w', 'w+', 'a', 'a+', 'x', 'x+'); - if(($initialMode) AND (in_array($initialMode, $useableModes))) { - // - $this->mode = $initialMode; - } else { - //define the DEFAULT mode. - $this->mode = "r+"; - } - - }//end __construct() - //======================================================================================== - - - - //======================================================================================== - public function cdup() { - $retval = FALSE; - //easy way to go "up" a directory (just like doing "cd .." in linux) - if(strlen($this->cwd) > 1) { - $myCwd = preg_replace('/\/$/', '', $this->cwd); - if(!preg_match('/^\//', $myCwd)) { - $myCwd = '/'. $myCwd; - } - $myParts = explode('/', $myCwd); - array_pop($myParts); - $myCwd = $this->gfObj->string_from_array($myParts, NULL, '/'); - $realCwd = $this->gfObj->create_list($this->root, $myCwd, '/'); - if(file_exists($realCwd)) { - $retval = TRUE; - $this->realcwd = $realCwd; - $this->cwd = '/'. $myCwd; - } - } - - return($retval); - }//end cdup() - //======================================================================================== - - - - //======================================================================================== - /** - * Think of the linux version of "cd": we're changing the current directory. - * - * @param $newDir (str) dir to change to, either absolutte or relative. - * - * @return 0 (FAIL) unable to change directory - * @return 1 (PASS) success. - */ - public function cd($newDir) { - - //check to see if it's a relative path or not... - //NOTE: non-relative paths should NOT include $this->root. - if((preg_match('/^\//', $newDir)) AND (is_dir($this->root .'/'. $newDir))) { - //not a relative path. - $this->cwd = '/'. $newDir; - $this->realcwd = $this->root . $newDir; - $retval = 1; - } elseif(is_dir($this->realcwd .'/'. $newDir)) { - //relative path... - $this->cwd = $this->gfObj->create_list($this->cwd, $newDir, '/'); - $this->realcwd .= '/'. $newDir; - $retval = 1; - } else { - //bad. - $retval = 0; - } - $this->cwd = preg_replace('/\/\//', '/', $this->cwd); - $this->realcwd = preg_replace('/\/\//', '/', $this->realcwd); - - return($retval); - }//end cd() - //======================================================================================== - - - //======================================================================================== - /** - * Just like the linux version of the 'ls' command. - */ - public function ls($filename=NULL, $args=NULL) { - - clearstatcache(); - //open the directory for reading. - $this->dh = opendir($this->realcwd); - clearstatcache(); - if(is_string($filename)) { - //check to make sure the file exists. - $tFile=$this->filename2absolute($filename); - if(file_exists($tFile)) { - //it's there... get info about it. - $info = $this->get_fileinfo($tFile); - if($info['type'] == 'dir') { - $oldCwd = $this->cwd; - $oldRealCwd = $this->realcwd; - - $this->cd($filename); - $retval = $this->ls(); - - $this->cwd = $oldCwd; - $this->realcwd = $oldRealCwd; - } - else { - $retval[$filename] = $info; - } - } else { - //stupid! - $retval[$filename] = "FILE NOT FOUND."; - } - } else { - //array if file/directory names to ignore if matched exactly. - $ignoreArr = array("CVS", ".svn", ".", ".."); - while (($file = readdir($this->dh)) !== false) { - if(!in_array($file, $ignoreArr)) { - $tFile = $this->realcwd .'/'. $file; - $tType = filetype($tFile); - $retval[$file] = $this->get_fileinfo($tFile); - if(!$tType) { - debug_print("FILE: $tFile || TYPE: $tType || is_file(): ". is_file($tFile) ."is_dir(): ". is_dir($tFile)); - exit; - } - #debug_print("FILE: $file || $dir". $file); - unset($tType); - } - } - } - #debug_print($retval); - #debug_print(readdir($this->dh)); - return($retval); - }//end ls() - //======================================================================================== - - - //======================================================================================== - /** - * Grabs an array of information for a given file. - */ - public function get_fileinfo($tFile) { - - $retval = array( - "size" => filesize($tFile), - "type" => @filetype($tFile), - "accessed" => fileatime($tFile), - "modified" => filemtime($tFile), - "owner" => $this->my_getuser_group(fileowner($tFile), 'uid'), - "uid" => fileowner($tFile), - "group" => $this->my_getuser_group(filegroup($tFile), 'gid'), - "gid" => filegroup($tFile), - "perms" => $this->translate_perms(fileperms($tFile)), - "perms_num" => substr(sprintf('%o', fileperms($tFile)), -4) - ); - - return($retval); - }//end get_fileinfo() - //======================================================================================== - - - - //======================================================================================== - /** - * Gets the username/groupname of the given uid/gid. - * - * @param $int (int) uid/gid to check. - * @param $type (str) is it a uid or a gid? - * - * @return (string) groupname/username - */ - private function my_getuser_group($int, $type='uid') { - - if($type == 'uid') { - $func = 'posix_getpwuid'; - } elseif($type == 'gid') { - $func = 'posix_getgrgid'; - } else { - $retval = $int; - } - - if(!function_exists($func)) { - throw new exception(__METHOD__ .": required function missing (". $func .")"); - } - $t = $func($int); - return($t['name']); - - }//end my_getpwuid() - //======================================================================================== - - - - //======================================================================================== - /** - * Translates the permissions string (like "0700") into a *nix-style permissions - * string (i.e. "rwx------"). - * - * @param $in_Perms (int) permission number string - * - * @return (string) permissions string. - * - * NOTE: pretty sure I copied this from php.net, though I don't know the owner. If anybody - * can enlighten me, I'd be glad to give them credit. - */ - private function translate_perms($in_Perms) { - $sP = ""; - $sP .= (($in_Perms & 0x0100) ? 'r' : '-') . - (($in_Perms & 0x0080) ? 'w' : '-') . - (($in_Perms & 0x0040) ? (($in_Perms & 0x0800) ? 's' : 'x' ) : - (($in_Perms & 0x0800) ? 'S' : '-')); - // group - $sP .= (($in_Perms & 0x0020) ? 'r' : '-') . - (($in_Perms & 0x0010) ? 'w' : '-') . - (($in_Perms & 0x0008) ? (($in_Perms & 0x0400) ? 's' : 'x' ) : - (($in_Perms & 0x0400) ? 'S' : '-')); - - // world - $sP .= (($in_Perms & 0x0004) ? 'r' : '-') . - (($in_Perms & 0x0002) ? 'w' : '-') . - (($in_Perms & 0x0001) ? (($in_Perms & 0x0200) ? 't' : 'x' ) : - (($in_Perms & 0x0200) ? 'T' : '-')); - return($sP); - }//end translate_perms() - //======================================================================================== - - - //======================================================================================== - /** - * Creates an empty file... think of the linux command "touch". - * - * @param $filename (string) filename to create. - * - * @return 0 (FAIL) unable to create file. - * @return 1 (PASS) file created successfully. - */ - public function create_file($filename, $truncateFile=FALSE) { - - $retval = 0; - $filename = $this->filename2absolute($filename); - $filename = $this->resolve_path_with_dots($filename); - $this->filename = $filename; - - //check to see if the file exists... - if(!file_exists($filename)) { - if($this->is_writable(dirname($filename))) { - //no file. Create it. - $createFileRes = touch($filename); - if($createFileRes) { - $retval = 1; - } - else { - throw new exception(__METHOD__ .": invalid return from touch(". $filename ."), return was (". $createFileRes .")"); - } - } - else { - throw new exception(__METHOD__ .": directory (". dirname($filename) .") is not writable"); - } - } - elseif($truncateFile === TRUE) { - $this->truncate_file($filename); - } - else { - throw new exception(__METHOD__ .": file (". $filename .") exists and truncate not set"); - } - return($retval); - }//end create_file() - //======================================================================================== - - - - //======================================================================================== - /** - * Opens a stream/resource handle to use for doing file i/o. - * - * @param $filename (string) filename to open: should be relative to the current dir. - * @param $mode (string) mode to use: consult PHP.net's info for fopen(). - * - * @return 0 (FAIL) unable to open file. - * @return 1 (PASS) file opened successfully. - */ - public function openFile($filename=NULL, $mode="r+") { - clearstatcache(); - if(!strlen($filename) || is_null($filename)) { - $filename = $this->filename; - } - $filename = $this->filename2absolute($filename); - $this->filename = $filename; - - if($this->is_readable($filename)) { - //make sure we've got a mode to use. - - if(!is_string($mode)) { - $mode = "r+"; - } - $this->mode = $mode; - - if(in_array($this->mode, array("r+", "w", "w+", "a", "a+", "x", "x+")) && !$this->is_writable($filename)) { - throw new exception(__METHOD__ .": file is not writable (". $filename .") (". $this->is_writable($filename) ."), mode=(". $this->mode .")"); - } - - //attempt to open a stream to a file... - $this->fh = fopen($this->filename, $this->mode); - if(is_resource($this->fh)) { - //looks like we opened successfully. - $retval = 1; - $this->lineNum = 0; - } else { - //something bad happened. - $retval = 0; - } - } - else { - throw new exception(__METHOD__ .": file is unreadable (". $filename .")"); - } - - return($retval); - }//end openFile() - //======================================================================================== - - - //======================================================================================== - /** - * Write the given contents into the current file or the filename given. - * - * @param $content (str) Content to write into the file. - * @param $filename (str,optional) filename to use. If none given, the current one is used. - * - * @return 0 (FAIL) unable to write content to the file. - * @return (n) (PASS) wrote (n) bytes. - */ - public function write($content, $filename=NULL) { - - //open the file for writing. - if(!$filename) { - $filename= $this->filename; - } - $this->filename = $filename; - - //open the file... - $openResult = $this->openFile($this->filename, $this->mode); - - //looks like we made it... - $retval = fwrite($this->fh, $content, strlen($content)); - - //done... return the result. - return($retval); - }//end write() - //======================================================================================== - - - //======================================================================================== - /** - * Takes the given filename & returns the ABSOLUTE pathname: checks to see if the given - * string already has the absolute path in it. - */ - private function filename2absolute($filename) { - - clearstatcache(); - - $filename = $this->resolve_path_with_dots($filename); - - //see if it starts with a "/"... - if(preg_match("/^\//", $filename)) { - $retval = $filename; - } else { - $retval=$this->realcwd .'/'. $filename; - $retval = $this->resolve_path_with_dots($retval); - #debug_print(__METHOD__ .": realcwd=(". $this->realcwd .")"); - #$this->resolve_path_with_dots($retval); - } - - if(!$this->check_chroot($retval, FALSE)) { - $this->gfObj->debug_print(func_get_args()); - throw new exception(__METHOD__ .": file is outside of allowed directory (". $retval .")"); - } - - return($retval); - - }//end filename2absolute() - //======================================================================================== - - - - //======================================================================================== - /** - * Reads-in the contents of an entire file. - */ - function read($filename, $returnArray=FALSE) { - $myFile = $this->filename2absolute($filename); - if(!file_exists($myFile)) { - throw new exception(__METHOD__ .": file doesn't exist (". $myFile .")"); - } - elseif($this->is_readable($myFile)) { - if($returnArray) { - $data = file($myFile); - } - else { - $data = file_get_contents($myFile); - } - - if($data === FALSE) { - throw new exception(__METHOD__. ": file_get_contents() returned FALSE"); - } - } - else { - throw new exception(__METHOD__. ": File isn't readable (". $myFile .")"); - } - return($data); - }//end read() - //======================================================================================== - - - - //======================================================================================== - public function rm($filename) { - $filename = $this->filename2absolute($filename); - return(unlink($filename)); - }//end rm() - //======================================================================================== - - - - //======================================================================================== - public function rmdir($dirname) { - $dirname = $this->filename2absolute($dirname); - return(rmdir($dirname)); - }//end rm() - //======================================================================================== - - - - //======================================================================================== - /** - * Return the next line for a file. - * - * When the end of the file is found, this method returns FALSE (returning NULL might be - * misconstrued as a blank line). - */ - public function get_next_line($maxLength=NULL, $trimLine=TRUE) { - if(is_resource($this->fh) && get_resource_type($this->fh) == 'stream') { - if(feof($this->fh)) { - $retval = FALSE; - } - else { - if(!is_numeric($maxLength)) { - $retval = @fgets($this->fh); - } - else { - $retval = fgets($this->fh, $maxLength); - } - if($trimLine) { - $retval = trim($retval); - } - - if(is_null($this->lineNum) || !is_numeric($this->lineNum) || $this->lineNum < 0) { - throw new exception(__METHOD__ .": invalid data for lineNum (". $this->lineNum .")"); - } - $this->lineNum++; - } - } - else { - throw new exception(__METHOD__ .": invalid filehandle"); - } - - return($retval); - }//end get_next_line() - //======================================================================================== - - - - //======================================================================================== - public function append_to_file($data, $eolChar="\n") { - $retval = FALSE; - if(is_resource($this->fh)) { - $result = fwrite($this->fh, $data . $eolChar); - if($result === FALSE) { - throw new exception(__METHOD__ .": failed to write data to file"); - } - else { - $this->lineNum++; - $retval = $result; - } - } - else { - throw new exception(__METHOD__ .": invalid filehandle"); - } - - return($retval); - }//end append_to_file() - //======================================================================================== - - - - //======================================================================================== - public function closeFile() { - $retval = FALSE; - if(is_resource($this->fh)) { - fclose($this->fh); - $retval = TRUE; - } - - //reset internal pointers. - $this->filename = NULL; - $this->lineNum = NULL; - - return($retval); - }//end closeFile() - //======================================================================================== - - - - //======================================================================================== - /** - * Compare the given filename to the open filename to see if they match (using this allows - * giving a filename instead of comparing the whole path). - */ - public function compare_open_filename($compareToFilename) { - if(!strlen($compareToFilename) || is_null($compareToFilename)) { - throw new exception(__METHOD__ .": invalid filename to compare"); - } - elseif(!strlen($this->filename)) { - $retval = FALSE; - } - else { - $internalFilename = $this->filename2absolute($this->filename); - $compareToFilename = $this->filename2absolute($compareToFilename); - if($internalFilename == $compareToFilename) { - $retval = TRUE; - } - else { - $retval = FALSE; - } - } - - return($retval); - }//end compare_open_filename() - //======================================================================================== - - - - //======================================================================================== - /** - * Give a file a new name. - * - * TODO: check to make sure both files exist within our root. - */ - public function rename($currentFilename, $newFilename) { - if($newFilename == $currentFilename) { - $this->gfObj->debug_print(func_get_args()); - throw new exception(__METHOD__ .": renaming file to same name"); - } - - if($this->compare_open_filename($currentFilename)) { - $this->closeFile(); - } - - if($this->compare_open_filename($newFilename)) { - //renaming a different file to our currently open file... - $this->gfObj->debug_print(func_get_args()); - throw new exception(__METHOD__ .": renaming another file (". $currentFilename .") to the currently open filename (". $newFilename .")"); - } - else { - - $currentFilename = $this->filename2absolute($currentFilename); - $newFilename = $this->filename2absolute($newFilename); - - if(!$this->is_writable(dirname($newFilename))) { - throw new exception(__METHOD__ .": directory isn't writable... "); - } - $retval = rename($currentFilename, $newFilename); - if($retval !== TRUE) { - throw new exception(__METHOD__ .": failed to rename file (". $retval .")"); - } - } - - return($retval); - - }//end rename() - //======================================================================================== - - - - //======================================================================================== - /** - * Check if the given filename is executable. - */ - public function is_executable($filename) { - $filename = $this->filename2absolute($filename); - $retval = FALSE; - if(strlen($filename)) { - $retval = is_executable($filename); - } - - return($retval); - }//end is_executable() - //======================================================================================== - - - - //======================================================================================== - /** - * Check if the given filename is readable. - */ - public function is_readable($filename) { - $filename = $this->filename2absolute($filename); - $retval = FALSE; - if(strlen($filename)) { - $retval = is_readable($filename); - } - - return($retval); - }//end is_readable() - //======================================================================================== - - - - //======================================================================================== - /** - * Check if the given filename/path is writable - */ - public function is_writable($filenameOrPath) { - $filenameOrPath = $this->filename2absolute($filenameOrPath); - $retval = FALSE; - if(strlen($filenameOrPath)) { - $retval = is_writable($filenameOrPath); - } - - return($retval); - }//end is_writable() - //======================================================================================== - - - - //======================================================================================== - /** - * Determines how many lines are left in the current file. - */ - public function count_remaining_lines() { - if(is_resource($this->fh) && get_resource_type($this->fh) == 'stream') { - $originalLineNum = $this->lineNum; - - $myFilename = $this->filename; - $myNextLine = $this->get_next_line(); - $retval = 0; - while($myNextLine !== FALSE) { - $retval++; - $myNextLine = $this->get_next_line(); - } - - $this->closeFile(); - $this->openFile($myFilename, $this->mode); - - if($originalLineNum > 0) { - while($originalLineNum > $this->lineNum) { - $this->get_next_line(); - } - } - - if($this->lineNum !== $originalLineNum) { - throw new exception(__METHOD__ .": failed to match-up old linenum (". $originalLineNum .") with the current one (". $this->lineNum .")"); - } - } - else { - throw new exception(__METHOD__ .": Invalid filehandle, can't count remaining lines"); - } - - return($retval); - }//end count_remaining_files() - //======================================================================================== - - - - //======================================================================================== - /** - * Moves the cursor to the given line number. - * - * NOTE: remember if you're trying to get line #1 (literally), then you'll - * want to go to line #0, then call get_next_line() to retrieve it... this - * is the traditional logical vs. programatic numbering issue. A.k.a. the - * "off-by-one problem". - */ - public function go_to_line($lineNum) { - $retval = FALSE; - if(is_resource($this->fh) && get_resource_type($this->fh) == 'stream') { - if($this->lineNum > $lineNum) { - //gotta "rewind" the cursor back to the beginning. - rewind($this->fh); - $this->lineNum=0; - } - - if($lineNum == $this->lineNum) { - $retval = TRUE; - } - elseif($this->lineNum < $lineNum) { - while($this->lineNum < $lineNum) { - //don't grab any data, just move the cursor... - $this->get_next_line(); - } - if($this->lineNum == $lineNum) { - $retval = TRUE; - } - else { - throw new exception(__METHOD__ .": couldn't reach the line (". $lineNum ."), failed at (". $this->lineNum .")"); - } - } - else { - throw new exception(__METHOD__ .": internal lineNum (". $this->lineNum .") couldn't be retrieved or reset to (". $lineNum .")"); - } - } - - return($retval); - }//end go_to_line() - //======================================================================================== - - - - //======================================================================================== - /** - * Fix a path that contains "../". - * - * EXAMPLE: changes "/home/user/blah/blah/../../test" into "/home/user/test" - */ - public function resolve_path_with_dots($path) { - - while(preg_match('/\/\//', $path)) { - $path = preg_replace('/\/\//', '/', $path); - } - $retval = $path; - if(strlen($path) && preg_match('/\./', $path)) { - - $isAbsolute = FALSE; - if(preg_match('/^\//', $path)) { - $isAbsolute = TRUE; - $path = preg_replace('/^\//', '', $path); - } - $pieces = explode('/', $path); - - $finalPieces = array(); - for($i=0; $i < count($pieces); $i++) { - $dirName = $pieces[$i]; - if($dirName == '.') { - //do nothing; don't bother appending. - } - elseif($dirName == '..') { - $rippedIndex = array_pop($finalPieces); - } - else { - $finalPieces[] = $dirName; - } - } - - $retval = $this->gfObj->string_from_array($finalPieces, NULL, '/'); - if($isAbsolute) { - $retval = '/'. $retval; - } - } - - return($retval); - }//end resolve_path_with_dots() - //======================================================================================== - - - - //======================================================================================== - private function check_chroot($path, $translatePath=TRUE) { - if($translatePath === TRUE) { - $path = $this->filename2absolute($path); - } - - //now, let's go through the root directory structure, & make sure $path is within that. - $rootPieces = explode('/', $this->root); - $pathPieces = explode('/', $path); - - - if($rootPieces[0] == '') { - array_shift($rootPieces); - } - if($rootPieces[(count($rootPieces) -1)] == '') { - array_pop($rootPieces); - } - if($pathPieces[0] == '') { - array_shift($pathPieces); - } - - $retval = TRUE; - $tmp = ''; - foreach($rootPieces as $index=>$dirName) { - $pathDir = $pathPieces[$index]; - if($pathDir != $dirName) { - $retval = FALSE; - $this->gfObj->debug_print(__METHOD__ .": failed... tmp=(". $tmp ."), dirName=(". $dirName .")"); - break; - } - $tmp = $this->gfObj->create_list($tmp, $dirName, '/'); - } - - return($retval); - }//end check_chroot() - //======================================================================================== - - - - //======================================================================================== - public function copy_file($filename, $destination) { - $retval = FALSE; - if($this->openFile($filename)) { - if($this->check_chroot($destination)) { - //okay, try to copy. - $retval = copy($this->fh, $destination); - } - else { - throw new exception(__METHOD__ .':: destination is not in the directory path'); - } - } - - return($retval); - }//end copy_file() - //======================================================================================== - - - - //======================================================================================== - public function move_file($filename, $destination) { - $retval = FALSE; - if($this->is_readable($filename)) { - if($this->check_chroot($destination)) { - //do the move. - $retval = rename($filename, $destin... [truncated message content] |
From: <cra...@us...> - 2009-01-29 20:40:24
|
Revision: 332 http://cs-content.svn.sourceforge.net/cs-content/?rev=332&view=rev Author: crazedsanity Date: 2009-01-29 20:40:16 +0000 (Thu, 29 Jan 2009) Log Message: ----------- Renamed "contentSystemClass.php" to contentSystem.class.php (standardized CS naming convention). Modified Paths: -------------- trunk/1.0/sample_files/public_html/content Added Paths: ----------- trunk/1.0/contentSystem.class.php Removed Paths: ------------- trunk/1.0/contentSystemClass.php Copied: trunk/1.0/contentSystem.class.php (from rev 331, trunk/1.0/contentSystemClass.php) =================================================================== --- trunk/1.0/contentSystem.class.php (rev 0) +++ trunk/1.0/contentSystem.class.php 2009-01-29 20:40:16 UTC (rev 332) @@ -0,0 +1,854 @@ +<?php +/* + * FILE INFORMATION: + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedRevision$ + * $LastChangedBy$ + * + * HOW THE SYSTEM WORKS::: + * TEMPLATE FILES: + * Automatically loads templates based on the URL, and optionally includes scripts in the includes directory. + * + * MAIN SECTION: + * For the main section, i.e. "/content", it requires a template in a directory of that name beneath + * /templates, with a file called "index.content.tmpl"... i.e. /templatee/content/index.content.tmpl. + * SUB SECTIONS: + * For any subsection to be valid, i.e. "/content/members", it must have an associated template, i.e. + * "/templates/content/members.content.tmpl". If a subdirectory with an index.content.tmpl file exists, it will + * be used instead of the file in the sub directory (i.e. "/templates/content/members/index.content.tmpl"). + * SUB SECTION TEMPLATE INHERITANCE: + * All pages load the base set of "shared" templates, which are in the form "<section>.shared.tmpl" in + * the root of the templates directory. + * + * Shared files within each directory, in the form "<section>.shared.tmpl", will be loaded for ANY subsection. + * + * For any subsection, it inherits a previous section's templates in the following manner (any "content" + * templates are ignored for inheritance, as they're require for page load). + * /content ---> /templates/content/index.*.tmpl + * + * /content/members |--> /templates/content/index.*.tmpl + * `--> /templates/content/members.*.tmpl + * + * /content/members/test |--> /templates/content/index.*.tmpl + * |--> /templates/content/members.*.tmpl + * |--> /templates/content/members/index.*.tmpl + * `--> /templates/content/members/test.*.tmpl + * AUTOMATIC INCLUDES: + * Much in the same way templates are included, so are scripts, from the /includes directory, though the logic + * is decidedly simpler: all scripts must have the extension of ".inc", and must have either the section's name + * as the first part of the filename, or "shared". Shared scripts will be loaded for ALL subsections. + * + * INCLUDES INHERITANCE: + * The template inheritance scheme is as laid-out below. The content system will go as far into the + * includes directory as it can for the given section, regardless of if any intermediate files are missing. + * + * It is important to note that the content system will NOT regard a section as valid if there are include + * scripts but no templates. + * + * /content |--> /includes/shared.inc + * `--> /includes/content.inc + * + * /content/members |--> /includes/shared.inc + * |--> /includes/content.inc + * |--> /includes/content/shared.inc + * `--> /includes/content/members.inc + * + * /content/members/test |--> /includes/shared.inc + * |--> /includes/content.inc + * |--> /includes/content/shared.inc + * |--> /includes/content/members.inc + * |--> /includes/content/members/shared.inc + * |--> /includes/content/members/test.inc + */ + +//TODO: remove this terrible little hack. +if(!isset($GLOBALS['SITE_ROOT'])) { + //define where our scripts are located. + $GLOBALS['SITE_ROOT'] = $_SERVER['DOCUMENT_ROOT']; + $GLOBALS['SITE_ROOT'] = str_replace("/public_html", "", $GLOBALS['SITE_ROOT']); +} + +require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); +require_once(dirname(__FILE__) ."/cs_fileSystemClass.php"); +require_once(dirname(__FILE__) ."/cs_sessionClass.php"); +require_once(dirname(__FILE__) ."/cs_genericPageClass.php"); +require_once(dirname(__FILE__) ."/cs_tabsClass.php"); + +class contentSystem extends cs_contentAbstract { + + protected $baseDir = NULL; //base directory for templates & includes. + protected $section = NULL; //section string, derived from the URL. + protected $sectionArr = array(); //array of items, for figuring out where templates & includes are. + protected $fileSystemObj = NULL; //the object used to access the filesystem. + protected $ignoredList = array( //array of files & folders that are implicitely ignored. + 'file' => array('.htaccess'), + 'dir' => array('.svn','CVS' + ) + ); + protected $templateList = array(); + protected $includesList = array(); + public $templateObj = NULL; + protected $gfObj = NULL; + protected $tabs = NULL; + + protected $finalSection; + + private $isValid=FALSE; + private $reason=NULL; + + //------------------------------------------------------------------------ + /** + * The CONSTRUCTOR. Duh. + */ + public function __construct($testOnly=FALSE) { + if($testOnly === 'unit_test') { + //It's just a test, don't do anything we might regret later. + $this->isTest = TRUE; + } + else { + parent::__construct(); + + //setup the section stuff... + $repArr = array($_SERVER['SCRIPT_NAME'], "/"); + $_SERVER['REQUEST_URI'] = ereg_replace('^/', "", $_SERVER['REQUEST_URI']); + + //figure out the section & subsection stuff. + $this->section = $this->clean_url($_SERVER['REQUEST_URI']); + + $this->initialize_locals(); + } + }//end __construct() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Creates internal objects & prepares for later usage. + */ + private function initialize_locals() { + //build the templating engine: this may cause an immediate redirect, if they need to be logged-in. + //TODO: find a way to define this on a per-page basis. Possibly have templateObj->check_login() + // run during the "finish" stage... probably using GenericPage{}->check_login(). + $this->templateObj = new cs_genericPage(FALSE, "main.shared.tmpl"); + + //setup some default template vars. + $this->templateObj->add_template_var('date', date('m-d-Y')); + $this->templateObj->add_template_var('time', date('H:i:s')); + + $myUrl = '/'; + if(strlen($this->section) && $this->section !== 0) { + $myUrl = '/'. $this->section; + } + $this->templateObj->add_template_var('CURRENT_URL', $myUrl); + + //create a fileSystem object. + $this->fileSystemObj = new cs_fileSystemClass(); + + //create a tabs object, in case they want to load tabs on the page. + $this->tabs = new cs_tabs($this->templateObj); + + //check versions, make sure they're all the same. + $myVersion = $this->get_version(); + if($this->templateObj->get_version() !== $myVersion) { + throw new exception(__METHOD__ .": ". get_class($this->templateObj) ." has mismatched version (". $this->templateObj->get_version() ." does not equal ". $myVersion .")"); + } + if($this->fileSystemObj->get_version() !== $myVersion) { + throw new exception(__METHOD__ .": ". get_class($this->fileSystemObj) ." has mismatched version (". $this->fileSystemObj->get_version() ." does not equal ". $myVersion .")"); + } + if($this->gfObj->get_version() !== $myVersion) { + throw new exception(__METHOD__ .": ". get_class($this->gfObj) ." has mismatched version (". $this->gfObj->get_version() ." does not equal ". $myVersion .")"); + } + if($this->tabs->get_version() !== $myVersion) { + throw new exception(__METHOD__ .": ". get_class($this->tabs) ." has mismatched version (". $this->tabs->get_version() ." does not equal ". $myVersion .")"); + } + + //split apart the section so we can do stuff with it later. + $this->parse_section(); + + //get ready for when we have to load templates & such. + $this->prepare(); + }//end initialize_locals() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + private function get_template_dirs() { + if(is_array($this->sectionArr)) { + $this->fileSystemObj->cd("/templates/". $this->baseDir); + $retval = array(); + $retval[] = $this->fileSystemObj->cwd; + foreach($this->sectionArr as $index=>$name) { + if($this->fileSystemObj->cd($name)) { + $retval[] = $this->fileSystemObj->cwd; + } + else { + break; + } + } + } + else { + throw new exception(__METHOD__ .": section array is invalid"); + } + + return($retval); + }//end get_template_dirs() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Call this to require that users accessing the given URL are authenticated; + * if they're not, this will cause them to be redirected to another URL + * (generally, so they can login). + */ + public function force_authentication($redirectToUrl, $destinationArg='loginDestination') { + if(is_object($this->session) && method_exists($this->session, 'is_authenticated')) { + if(strlen($redirectToUrl)) { + $cleanedRedirect = $this->clean_url($redirectToUrl); + if($this->section != $cleanedRedirect) { + if(!$this->session->is_authenticated()) { + //run the redirect. + if(strlen($destinationArg)) { + $redirectToUrl .= '?'. $destinationArg .'=/'. urlencode($_SERVER['REQUEST_URI']); + } + $this->gfObj->conditional_header($redirectToUrl, TRUE); + } + } + else { + throw new exception(__METHOD__ .": redirect url (". $redirectToUrl .") matches current URL"); + } + } + else { + throw new exception(__METHOD__ .": failed to provide proper redirection URL"); + } + } + else { + throw new exception(__METHOD__ .": cannot force authentication (missing method)"); + } + }//end force_authentication() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Used to determine if contentSystem{} should handle creating the session. + */ + public function handle_session(&$sessionObj=NULL) { + if(is_object($sessionObj)) { + //they want us to use a different class... fine. + $this->session = $sessionObj; + } + else { + //use our own session handler. + $this->session = new cs_session; + } + + if(!method_exists($this->session, 'is_authenticated')) { + throw new exception(__METHOD__ .": session class ('". get_class($this->session) ."') is missing method is_authenticated()"); + } + }//end handle_session() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Rips apart the "section" string, setting $this->section and $this->sectionArr. + */ + private function parse_section() { + if($this->section === 0 || is_null($this->section) || !strlen($this->section)) { + $this->section = "content/index"; + } + $myArr = split('/', $this->section); + + //if we've got something in the array, keep going. + if(is_array($myArr) && count($myArr) && ($myArr[0] !== 0)) { + $this->baseDir = array_shift($myArr); + $this->sectionArr = $myArr; + } + }//end parse_section() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Removes all the crap from the url, so we can figure out what section we + * need to load templates & includes for. + */ + private function clean_url($section=NULL) { + if(!strlen($section) && strlen($this->section)) { + //if argument wasn't given, use internal pointer. + $section = $this->section; + } + + //make sure we've still got something valid to work with. + if(!strlen($section)) { + //TODO: remove the extra return statement (should only be one at the bottom of the method). + return(NULL); + } + else { + //check the string to make sure it doesn't begin or end with a "/" + if($section[0] == '/') { + $section = substr($section, 1, strlen($section)); + } + + //check the last char for a "/"... + if($section[strlen($section) -1] == '/') { + //last char is a '/'... kill it. + $section = substr($section, 0, strlen($section) -1); + } + + //if we've been sent a query, kill it off the string... + if(preg_match('/\?/', $section)) { + $section = split('\?', $section); + $section = $section[0]; + } + + if(ereg("\.", $section)) { + //disregard file extensions, but keep everything else... + // i.e. "index.php/yermom.html" becomes "index/yermom" + $tArr = split('/', $section); + foreach($tArr as $tSecName) { + $temp = split("\.", $tSecName); + if(strlen($temp[0]) > 1) { + $tSecName = $temp[0]; + } + $tSection = $this->gfObj->create_list($tSection, $tSecName, '/'); + } + $section = $tSection; + } + } + + return($section); + }//end clean_url() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Retrieves the list of templates & includes in preparation for later work. + */ + private function prepare() { + //attempt to load any includes... + if($this->fileSystemObj->cd('/includes')) { + $this->load_includes(); + } + $foundIncludes = count($this->includesList); + + //cd() in to the templates directory. + $cdResult = $this->fileSystemObj->cd('/templates'); + $validatePageRes = $this->validate_page(); + if($foundIncludes || ($cdResult && $validatePageRes)) { + + //okay, get template directories & start loading + $tmplDirs = $this->get_template_dirs(); + + $this->load_shared_templates(); + foreach($tmplDirs as $myPath) { + //load shared templates. + $this->load_shared_templates($myPath); + } + + //load templates for the main section. + $this->load_main_templates(); + + //load templates for the page. + $this->load_page_templates(); + + //now cd() all the way back. + $this->fileSystemObj->cd('/'); + } + else { + //couldn't find the templates directory, and no includes... it's dead. + $this->die_gracefully(__METHOD__ .": unable to find the templates directory, or non-valid page [". $this->validate_page() ."]"); + } + }//end prepare() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Ensures the page we're on would actually load, so other methods don't have to do + * so much extra checking. + */ + private function validate_page() { + $valid = FALSE; + //if we've got a non-basedir page, (instead of "/whatever", we have "/whatever/x"), see + // if there are templates that make it good... or just check the base template. + if((count($this->sectionArr) > 0) && !((count($this->sectionArr) == 1) && ($this->sectionArr[0] == 'index'))) { + //got more than just a baseDir url... see if the template is good. + $finalLink = $this->gfObj->string_from_array($this->sectionArr, NULL, '/'); + $this->fileSystemObj->cd($this->baseDir); + $mySectionArr = $this->sectionArr; + $finalSection = array_pop($mySectionArr); + $this->finalSection = $finalSection; + if(count($mySectionArr) > 0) { + foreach($mySectionArr as $dir) { + if(!$this->fileSystemObj->cd($dir)) { + break; + } + } + } + + //check for the file & the directory... + $indexFilename = $finalSection ."/index.content.tmpl"; + if(!strlen($finalSection)) { + $indexFilename = 'index.content.tmpl'; + } + + $lsDir = $this->fileSystemObj->ls($indexFilename); + $lsDirVals = array_values($lsDir); + $lsFile = $this->fileSystemObj->ls("$finalSection.content.tmpl"); + + if(is_array(array_values($lsFile)) && is_array($lsFile[$finalSection .".content.tmpl"])) { + //it's the file ("{finalSection}.content.tmpl", like "mySection.content.tmpl") + $myIndex = $finalSection .".content.tmpl"; + } + elseif(is_array(array_values($lsDir)) && (is_array($lsDir[$indexFilename]))) { + $myIndex = $indexFilename; + } + else { + //nothin' doin'. + $myIndex = NULL; + } + + //check the index file for validity... this is kind of a dirty hack... but it works. + $checkMe = $this->fileSystemObj->ls($myIndex); + if(!is_array($checkMe[$myIndex])) { + unset($myIndex); + } + + if(isset($myIndex)) { + $valid = TRUE; + $this->fileSystemObj->cd('/templates'); + } + else { + $this->reason = __METHOD__ .": couldn't find page template for ". $this->section; + } + } + else { + //if the baseDir is "help", this would try to use "/help/index.content.tmpl" + $myFile = $this->baseDir .'/index.content.tmpl'; + $sectionLsData = $this->fileSystemObj->ls($myFile); + + //if the baseDir is "help", this would try to use "/help.content.tmpl" + $sectionFile = $this->baseDir .'.content.tmpl'; + $lsData = $this->fileSystemObj->ls(); + + if(isset($lsData[$sectionFile]) && is_array($lsData[$sectionFile])) { + $valid = TRUE; + $this->finalSection = $this->baseDir; + } + elseif(isset($sectionLsData[$myFile]) && $sectionLsData[$myFile]['type'] == 'file') { + //we're good. + $valid = TRUE; + $this->finalSection = $this->baseDir; + } + else { + $this->reason = __METHOD__ .": couldn't find base template."; + } + } + $this->isValid = $valid; + + return($valid); + }//end validate_page() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Loads the templates for the current page (performs template inheritance, too). + */ + private function load_page_templates() { + //should already be in the proper directory, start looping through sectionArr, + // looking for templates. + $mySectionArr = $this->sectionArr; + + $finalSection = $this->sectionArr[(count($this->sectionArr) -1)]; + foreach($mySectionArr as $index=>$value) { + $tmplList = $this->arrange_directory_contents('name', 'section'); + if(isset($tmplList[$value])) { + foreach($tmplList[$value] as $mySection=>$myTmpl) { + // + $this->templateList[$mySection] = $myTmpl; + } + } + if(!$this->fileSystemObj->cd($value)) { + break; + } + } + + //load the final template(s). + $finalTmplList = $this->arrange_directory_contents('name', 'section'); + if(isset($finalTmplList[$finalSection])) { + foreach($finalTmplList[$finalSection] as $mySection => $myTmpl) { + $this->templateList[$mySection] = $myTmpl; + } + } + elseif(is_array($finalTmplList)) { + foreach($finalTmplList as $mySection => $subArr) { + foreach($subArr as $internalSection => $myTmpl) { + $this->templateList[$mySection] = $myTmpl; + } + } + } + if($this->fileSystemObj->cd($finalSection)) { + //load the index stuff. + $tmplList = $this->arrange_directory_contents('name', 'section'); + if(isset($tmplList['index'])) { + foreach($tmplList['index'] as $mySection => $myTmpl) { + $this->templateList[$mySection] = $myTmpl; + } + } + if(isset($tmplList[$this->baseDir]['content'])) { + //load template for the main page (if $this->baseDir == "help", this would load "/help.content.tmpl" as content) + $this->templateList['content'] = $tmplList[$this->baseDir]['content']; + } + } + }//end load_page_templates() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * loads templates for the main section they're on. + */ + private function load_main_templates() { + $this->fileSystemObj->cd('/templates'); + //check to see if the present section is valid. + $this->fileSystemObj->cd($this->baseDir); + $dirContents = $this->arrange_directory_contents('name', 'section'); + if(is_array($dirContents)) { + foreach($dirContents as $mySection => $subArr) { + foreach($subArr as $subIndex=>$templateFilename) { + $this->templateList[$mySection] = $templateFilename; + } + } + } + }//end load_main_templates() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Loads any shared templates: these can be overwritten later. + */ + private function load_shared_templates($path=NULL) { + + if(!is_null($path)) { + $this->fileSystemObj->cd($path); + } + else { + $this->fileSystemObj->cd('/templates'); + } + + //pull a list of the files. + $dirContents = $this->arrange_directory_contents(); + if(count($dirContents['shared'])) { + + foreach($dirContents['shared'] as $section => $template) { + $this->templateList[$section] = $template; + } + } + }//end load_shared_templates() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Pulls a list of files in the current directory, & arranges them by section & + * name, or vice-versa. + */ + private function arrange_directory_contents($primaryIndex='section', $secondaryIndex='name') { + $directoryInfo = $this->fileSystemObj->ls(); + $arrangedArr = array(); + if(is_array($directoryInfo)) { + foreach($directoryInfo as $index=>$data) { + $myType = $data['type']; + if(($myType == 'file') && !in_array($index, $this->ignoredList[$myType])) { + $filename = $this->gfObj->create_list($this->fileSystemObj->cwd, $index, '/'); + $filename = preg_replace('/^\/templates/', '', $filename); + $filename = preg_replace('/^\/\//', '/', $filename); + //call another method to rip the filename apart properly, then arrange things as needed. + $pieces = $this->parse_filename($index); + $myPriIndex = $pieces[$primaryIndex]; + $mySecIndex = $pieces[$secondaryIndex]; + if(strlen($myPriIndex) && strlen($mySecIndex)) { + //only load if it's got BOTH parts of the filename. + $arrangedArr[$myPriIndex][$mySecIndex] = $filename; + } + } + } + } + + return($arrangedArr); + }//end arrange_directory_contents() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Takes a filename (string) and breaks it down into the "type", "section", and + * "name". I.E. for the filename "test.content.tmpl", type=tmpl, section="content", + * and "name"=test. + * TODO: set a way to define how the filenames are setup, so filenames can be "name.section.type" or "section.name.type". + */ + private function parse_filename($filename) { + //break it into it's various parts. + $myParts = explode('.', $filename); + $retval = array(); + $count = count($myParts); + if($count >= 3) { + //"type" is the last element of the array, and "section" is the second-to-last. + $type = array_pop($myParts); + + //define what types of files that are accepted: if it's not one of them, don't bother. + $acceptedTypes = array("tmpl"); + if(in_array($type, $acceptedTypes)) { + $section = array_pop($myParts); + + //just in case we want to allow templates with "."'s in them, rip off the + // last two parts, and use what's left as the name. + $stripThis = '.'. $section .'\.'. $type .'$'; + $name = preg_replace('/'. $stripThis .'/', '', $filename); + + $retval = array( + 'name' => $name, + 'section' => $section, + 'type' => $type + ); + } + } + + return($retval); + }//end parse_filename() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Finds all scripts in the /inlcudes directory, & adds them to the includesList array. + */ + private function load_includes() { + + //first load includes for the base directory. + $this->load_dir_includes($this->baseDir); + + //okay, now loop through $this->sectionArr & see if we can include anything else. + if(($this->fileSystemObj->cd($this->baseDir)) && is_array($this->sectionArr) && count($this->sectionArr) > 0) { + + foreach($this->sectionArr as $mySection) { + //Run includes. + $this->load_dir_includes($mySection); + + //attempt to cd() into the next directory, or die if we can't. + if(!$this->fileSystemObj->cd($mySection)) { + //no dice. Break the loop. + break; + } + } + } + + }//end load_includes() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Attempts to add a shared include & the given section's include file: used + * solely by load_includes(). + */ + private function load_dir_includes($section) { + $lsData = $this->fileSystemObj->ls(); + + //attempt to load the shared includes file. + if(isset($lsData['shared.inc']) && $lsData['shared.inc']['type'] == 'file') { + $this->includesList[] = $this->fileSystemObj->realcwd .'/shared.inc'; + } + + //attempt to load the section's includes file. + $myFile = $section .'.inc'; + if(isset($lsData[$myFile]) && $lsData[$myFile]['type'] == 'file') { + $this->includesList[] = $this->fileSystemObj->realcwd .'/'. $myFile; + } + + if(isset($lsData[$section]) && !count($this->sectionArr)) { + $this->fileSystemObj->cd($section); + $lsData = $this->fileSystemObj->ls(); + if(isset($lsData['index.inc'])) { + $this->includesList[] = $this->fileSystemObj->realcwd .'/index.inc'; + } + } + }//end load_dir_includes() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Called when something is broken. + */ + private function die_gracefully($details=NULL) { + header('HTTP/1.0 404 Not Found'); + if($this->templateObj->template_file_exists('system/404.shared.tmpl')) { + //Simple "Page Not Found" error... show 'em. + $this->templateObj->add_template_var('main', $this->templateObj->file_to_string('system/404.shared.tmpl')); + $this->templateObj->add_template_var('details', $details); + $this->templateObj->add_template_var('datetime', date('m-d-Y H:i:s')); + $this->templateObj->print_page(); + exit; + } + else { + //TODO: make it *actually* die gracefully... the way it works now looks more like puke than grace. + throw new exception(__METHOD__ .": Couldn't find 404 template, plus additional error... \nDETAILS::: $details" . + "\nREASON::: ". $this->reason); + } + }//end die_gracefully() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * The super-magical method that includes files & finalizes things using + * the given templating engine. + * NOTE: the local variable "$page" is made so that the included scripts + * can make calls to the templating engine, just like they used to. It's + * AWESOME. + */ + function finish() { + //Avoid problems when REGISTER_GLOBALS is on... + $badUrlVars = array('page', 'this'); + foreach($badUrlVars as $badVarName) { + unset($_GET[$badVarName], $_POST[$badVarName]); + } + + $page =& $this->templateObj; + if(is_object($this->session)) { + $page->session =& $this->session; + } + + + //if we loaded an index, but there is no "content", then move 'em around so we have content. + if(isset($this->templateList['index']) && !isset($this->templateList['content'])) { + $this->templateList['content'] = $this->templateList['index']; + unset($this->templateList['index']); + } + + foreach($this->templateList as $mySection => $myTmpl) { + $myTmpl = preg_replace("/\/\//", "/", $myTmpl); + $page->add_template_file($mySection, $myTmpl); + } + unset($mySection); + unset($myTmpl); + + //make the "final section" available to scripts. + $finalSection = $this->finalSection; + $sectionArr = $this->sectionArr; + array_unshift($sectionArr, $this->baseDir); + $finalURL = $this->gfObj->string_from_array($sectionArr, NULL, '/'); + + //now include the includes scripts, if there are any. + if(is_array($this->includesList) && count($this->includesList)) { + try { + foreach($this->includesList as $myInternalIndex=>$myInternalScriptName) { + $this->myLastInclude = $myInternalScriptName; + include_once($this->myLastInclude); + } + } + catch(exception $e) { + $myRoot = preg_replace('/\//', '\\\/', $this->fileSystemObj->root); + $displayableInclude = preg_replace('/^'. $myRoot .'/', '', $this->myLastInclude); + $this->templateObj->set_message_wrapper(array( + 'title' => "Fatal Error", + 'message' => __METHOD__ .": A fatal error occurred while processing <b>". + $displayableInclude ."</b>:<BR>\n<b>ERROR</b>: ". $e->getMessage(), + 'type' => "fatal" + )); + + //try to pass the error on to the user's exception handler, if there is one. + if(function_exists('exception_handler')) { + exception_handler($e); + } + } + unset($myInternalIndex); + unset($myInternalScriptName); + } + + if(is_bool($this->templateObj->allow_invalid_urls() === TRUE) && $this->isValid === FALSE) { + $this->isValid = $this->templateObj->allow_invalid_urls(); + } + + if($this->isValid === TRUE) { + $page->print_page(); + } + else { + $this->die_gracefully($this->reason); + } + }//end finish() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Method for accessing the protected $this->sectionArr array. + */ + public function get_sectionArr() { + //give 'em what they want. + return($this->sectionArr); + }//end get_sectionArr() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Method for accessing the protected member $this->finalSection. + */ + public function get_finalSection() { + //give 'em what they want. + return($this->finalSection); + }//end get_finalSection() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * Method for accessing "baseDir", only referenced as the base section. + */ + public function get_baseSection() { + return($this->baseDir); + }//end get_baseSection() + //------------------------------------------------------------------------ + + + + //------------------------------------------------------------------------ + /** + * The destructor... does nothing, right now. + */ + public function __destruct() { + }//end __destruct() + //------------------------------------------------------------------------ + + +}//end contentSystem{} +?> Property changes on: trunk/1.0/contentSystem.class.php ___________________________________________________________________ Added: svn:keywords + HeadURL Id LastChangedBy LastChangedDate LastChangedRevision Added: svn:mergeinfo + Added: svn:eol-style + native Deleted: trunk/1.0/contentSystemClass.php =================================================================== --- trunk/1.0/contentSystemClass.php 2009-01-29 20:18:41 UTC (rev 331) +++ trunk/1.0/contentSystemClass.php 2009-01-29 20:40:16 UTC (rev 332) @@ -1,854 +0,0 @@ -<?php -/* - * FILE INFORMATION: - * $HeadURL$ - * $Id$ - * $LastChangedDate$ - * $LastChangedRevision$ - * $LastChangedBy$ - * - * HOW THE SYSTEM WORKS::: - * TEMPLATE FILES: - * Automatically loads templates based on the URL, and optionally includes scripts in the includes directory. - * - * MAIN SECTION: - * For the main section, i.e. "/content", it requires a template in a directory of that name beneath - * /templates, with a file called "index.content.tmpl"... i.e. /templatee/content/index.content.tmpl. - * SUB SECTIONS: - * For any subsection to be valid, i.e. "/content/members", it must have an associated template, i.e. - * "/templates/content/members.content.tmpl". If a subdirectory with an index.content.tmpl file exists, it will - * be used instead of the file in the sub directory (i.e. "/templates/content/members/index.content.tmpl"). - * SUB SECTION TEMPLATE INHERITANCE: - * All pages load the base set of "shared" templates, which are in the form "<section>.shared.tmpl" in - * the root of the templates directory. - * - * Shared files within each directory, in the form "<section>.shared.tmpl", will be loaded for ANY subsection. - * - * For any subsection, it inherits a previous section's templates in the following manner (any "content" - * templates are ignored for inheritance, as they're require for page load). - * /content ---> /templates/content/index.*.tmpl - * - * /content/members |--> /templates/content/index.*.tmpl - * `--> /templates/content/members.*.tmpl - * - * /content/members/test |--> /templates/content/index.*.tmpl - * |--> /templates/content/members.*.tmpl - * |--> /templates/content/members/index.*.tmpl - * `--> /templates/content/members/test.*.tmpl - * AUTOMATIC INCLUDES: - * Much in the same way templates are included, so are scripts, from the /includes directory, though the logic - * is decidedly simpler: all scripts must have the extension of ".inc", and must have either the section's name - * as the first part of the filename, or "shared". Shared scripts will be loaded for ALL subsections. - * - * INCLUDES INHERITANCE: - * The template inheritance scheme is as laid-out below. The content system will go as far into the - * includes directory as it can for the given section, regardless of if any intermediate files are missing. - * - * It is important to note that the content system will NOT regard a section as valid if there are include - * scripts but no templates. - * - * /content |--> /includes/shared.inc - * `--> /includes/content.inc - * - * /content/members |--> /includes/shared.inc - * |--> /includes/content.inc - * |--> /includes/content/shared.inc - * `--> /includes/content/members.inc - * - * /content/members/test |--> /includes/shared.inc - * |--> /includes/content.inc - * |--> /includes/content/shared.inc - * |--> /includes/content/members.inc - * |--> /includes/content/members/shared.inc - * |--> /includes/content/members/test.inc - */ - -//TODO: remove this terrible little hack. -if(!isset($GLOBALS['SITE_ROOT'])) { - //define where our scripts are located. - $GLOBALS['SITE_ROOT'] = $_SERVER['DOCUMENT_ROOT']; - $GLOBALS['SITE_ROOT'] = str_replace("/public_html", "", $GLOBALS['SITE_ROOT']); -} - -require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); -require_once(dirname(__FILE__) ."/cs_fileSystemClass.php"); -require_once(dirname(__FILE__) ."/cs_sessionClass.php"); -require_once(dirname(__FILE__) ."/cs_genericPageClass.php"); -require_once(dirname(__FILE__) ."/cs_tabsClass.php"); - -class contentSystem extends cs_contentAbstract { - - protected $baseDir = NULL; //base directory for templates & includes. - protected $section = NULL; //section string, derived from the URL. - protected $sectionArr = array(); //array of items, for figuring out where templates & includes are. - protected $fileSystemObj = NULL; //the object used to access the filesystem. - protected $ignoredList = array( //array of files & folders that are implicitely ignored. - 'file' => array('.htaccess'), - 'dir' => array('.svn','CVS' - ) - ); - protected $templateList = array(); - protected $includesList = array(); - public $templateObj = NULL; - protected $gfObj = NULL; - protected $tabs = NULL; - - protected $finalSection; - - private $isValid=FALSE; - private $reason=NULL; - - //------------------------------------------------------------------------ - /** - * The CONSTRUCTOR. Duh. - */ - public function __construct($testOnly=FALSE) { - if($testOnly === 'unit_test') { - //It's just a test, don't do anything we might regret later. - $this->isTest = TRUE; - } - else { - parent::__construct(); - - //setup the section stuff... - $repArr = array($_SERVER['SCRIPT_NAME'], "/"); - $_SERVER['REQUEST_URI'] = ereg_replace('^/', "", $_SERVER['REQUEST_URI']); - - //figure out the section & subsection stuff. - $this->section = $this->clean_url($_SERVER['REQUEST_URI']); - - $this->initialize_locals(); - } - }//end __construct() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Creates internal objects & prepares for later usage. - */ - private function initialize_locals() { - //build the templating engine: this may cause an immediate redirect, if they need to be logged-in. - //TODO: find a way to define this on a per-page basis. Possibly have templateObj->check_login() - // run during the "finish" stage... probably using GenericPage{}->check_login(). - $this->templateObj = new cs_genericPage(FALSE, "main.shared.tmpl"); - - //setup some default template vars. - $this->templateObj->add_template_var('date', date('m-d-Y')); - $this->templateObj->add_template_var('time', date('H:i:s')); - - $myUrl = '/'; - if(strlen($this->section) && $this->section !== 0) { - $myUrl = '/'. $this->section; - } - $this->templateObj->add_template_var('CURRENT_URL', $myUrl); - - //create a fileSystem object. - $this->fileSystemObj = new cs_fileSystemClass(); - - //create a tabs object, in case they want to load tabs on the page. - $this->tabs = new cs_tabs($this->templateObj); - - //check versions, make sure they're all the same. - $myVersion = $this->get_version(); - if($this->templateObj->get_version() !== $myVersion) { - throw new exception(__METHOD__ .": ". get_class($this->templateObj) ." has mismatched version (". $this->templateObj->get_version() ." does not equal ". $myVersion .")"); - } - if($this->fileSystemObj->get_version() !== $myVersion) { - throw new exception(__METHOD__ .": ". get_class($this->fileSystemObj) ." has mismatched version (". $this->fileSystemObj->get_version() ." does not equal ". $myVersion .")"); - } - if($this->gfObj->get_version() !== $myVersion) { - throw new exception(__METHOD__ .": ". get_class($this->gfObj) ." has mismatched version (". $this->gfObj->get_version() ." does not equal ". $myVersion .")"); - } - if($this->tabs->get_version() !== $myVersion) { - throw new exception(__METHOD__ .": ". get_class($this->tabs) ." has mismatched version (". $this->tabs->get_version() ." does not equal ". $myVersion .")"); - } - - //split apart the section so we can do stuff with it later. - $this->parse_section(); - - //get ready for when we have to load templates & such. - $this->prepare(); - }//end initialize_locals() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - private function get_template_dirs() { - if(is_array($this->sectionArr)) { - $this->fileSystemObj->cd("/templates/". $this->baseDir); - $retval = array(); - $retval[] = $this->fileSystemObj->cwd; - foreach($this->sectionArr as $index=>$name) { - if($this->fileSystemObj->cd($name)) { - $retval[] = $this->fileSystemObj->cwd; - } - else { - break; - } - } - } - else { - throw new exception(__METHOD__ .": section array is invalid"); - } - - return($retval); - }//end get_template_dirs() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Call this to require that users accessing the given URL are authenticated; - * if they're not, this will cause them to be redirected to another URL - * (generally, so they can login). - */ - public function force_authentication($redirectToUrl, $destinationArg='loginDestination') { - if(is_object($this->session) && method_exists($this->session, 'is_authenticated')) { - if(strlen($redirectToUrl)) { - $cleanedRedirect = $this->clean_url($redirectToUrl); - if($this->section != $cleanedRedirect) { - if(!$this->session->is_authenticated()) { - //run the redirect. - if(strlen($destinationArg)) { - $redirectToUrl .= '?'. $destinationArg .'=/'. urlencode($_SERVER['REQUEST_URI']); - } - $this->gfObj->conditional_header($redirectToUrl, TRUE); - } - } - else { - throw new exception(__METHOD__ .": redirect url (". $redirectToUrl .") matches current URL"); - } - } - else { - throw new exception(__METHOD__ .": failed to provide proper redirection URL"); - } - } - else { - throw new exception(__METHOD__ .": cannot force authentication (missing method)"); - } - }//end force_authentication() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Used to determine if contentSystem{} should handle creating the session. - */ - public function handle_session(&$sessionObj=NULL) { - if(is_object($sessionObj)) { - //they want us to use a different class... fine. - $this->session = $sessionObj; - } - else { - //use our own session handler. - $this->session = new cs_session; - } - - if(!method_exists($this->session, 'is_authenticated')) { - throw new exception(__METHOD__ .": session class ('". get_class($this->session) ."') is missing method is_authenticated()"); - } - }//end handle_session() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Rips apart the "section" string, setting $this->section and $this->sectionArr. - */ - private function parse_section() { - if($this->section === 0 || is_null($this->section) || !strlen($this->section)) { - $this->section = "content/index"; - } - $myArr = split('/', $this->section); - - //if we've got something in the array, keep going. - if(is_array($myArr) && count($myArr) && ($myArr[0] !== 0)) { - $this->baseDir = array_shift($myArr); - $this->sectionArr = $myArr; - } - }//end parse_section() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Removes all the crap from the url, so we can figure out what section we - * need to load templates & includes for. - */ - private function clean_url($section=NULL) { - if(!strlen($section) && strlen($this->section)) { - //if argument wasn't given, use internal pointer. - $section = $this->section; - } - - //make sure we've still got something valid to work with. - if(!strlen($section)) { - //TODO: remove the extra return statement (should only be one at the bottom of the method). - return(NULL); - } - else { - //check the string to make sure it doesn't begin or end with a "/" - if($section[0] == '/') { - $section = substr($section, 1, strlen($section)); - } - - //check the last char for a "/"... - if($section[strlen($section) -1] == '/') { - //last char is a '/'... kill it. - $section = substr($section, 0, strlen($section) -1); - } - - //if we've been sent a query, kill it off the string... - if(preg_match('/\?/', $section)) { - $section = split('\?', $section); - $section = $section[0]; - } - - if(ereg("\.", $section)) { - //disregard file extensions, but keep everything else... - // i.e. "index.php/yermom.html" becomes "index/yermom" - $tArr = split('/', $section); - foreach($tArr as $tSecName) { - $temp = split("\.", $tSecName); - if(strlen($temp[0]) > 1) { - $tSecName = $temp[0]; - } - $tSection = $this->gfObj->create_list($tSection, $tSecName, '/'); - } - $section = $tSection; - } - } - - return($section); - }//end clean_url() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Retrieves the list of templates & includes in preparation for later work. - */ - private function prepare() { - //attempt to load any includes... - if($this->fileSystemObj->cd('/includes')) { - $this->load_includes(); - } - $foundIncludes = count($this->includesList); - - //cd() in to the templates directory. - $cdResult = $this->fileSystemObj->cd('/templates'); - $validatePageRes = $this->validate_page(); - if($foundIncludes || ($cdResult && $validatePageRes)) { - - //okay, get template directories & start loading - $tmplDirs = $this->get_template_dirs(); - - $this->load_shared_templates(); - foreach($tmplDirs as $myPath) { - //load shared templates. - $this->load_shared_templates($myPath); - } - - //load templates for the main section. - $this->load_main_templates(); - - //load templates for the page. - $this->load_page_templates(); - - //now cd() all the way back. - $this->fileSystemObj->cd('/'); - } - else { - //couldn't find the templates directory, and no includes... it's dead. - $this->die_gracefully(__METHOD__ .": unable to find the templates directory, or non-valid page [". $this->validate_page() ."]"); - } - }//end prepare() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Ensures the page we're on would actually load, so other methods don't have to do - * so much extra checking. - */ - private function validate_page() { - $valid = FALSE; - //if we've got a non-basedir page, (instead of "/whatever", we have "/whatever/x"), see - // if there are templates that make it good... or just check the base template. - if((count($this->sectionArr) > 0) && !((count($this->sectionArr) == 1) && ($this->sectionArr[0] == 'index'))) { - //got more than just a baseDir url... see if the template is good. - $finalLink = $this->gfObj->string_from_array($this->sectionArr, NULL, '/'); - $this->fileSystemObj->cd($this->baseDir); - $mySectionArr = $this->sectionArr; - $finalSection = array_pop($mySectionArr); - $this->finalSection = $finalSection; - if(count($mySectionArr) > 0) { - foreach($mySectionArr as $dir) { - if(!$this->fileSystemObj->cd($dir)) { - break; - } - } - } - - //check for the file & the directory... - $indexFilename = $finalSection ."/index.content.tmpl"; - if(!strlen($finalSection)) { - $indexFilename = 'index.content.tmpl'; - } - - $lsDir = $this->fileSystemObj->ls($indexFilename); - $lsDirVals = array_values($lsDir); - $lsFile = $this->fileSystemObj->ls("$finalSection.content.tmpl"); - - if(is_array(array_values($lsFile)) && is_array($lsFile[$finalSection .".content.tmpl"])) { - //it's the file ("{finalSection}.content.tmpl", like "mySection.content.tmpl") - $myIndex = $finalSection .".content.tmpl"; - } - elseif(is_array(array_values($lsDir)) && (is_array($lsDir[$indexFilename]))) { - $myIndex = $indexFilename; - } - else { - //nothin' doin'. - $myIndex = NULL; - } - - //check the index file for validity... this is kind of a dirty hack... but it works. - $checkMe = $this->fileSystemObj->ls($myIndex); - if(!is_array($checkMe[$myIndex])) { - unset($myIndex); - } - - if(isset($myIndex)) { - $valid = TRUE; - $this->fileSystemObj->cd('/templates'); - } - else { - $this->reason = __METHOD__ .": couldn't find page template for ". $this->section; - } - } - else { - //if the baseDir is "help", this would try to use "/help/index.content.tmpl" - $myFile = $this->baseDir .'/index.content.tmpl'; - $sectionLsData = $this->fileSystemObj->ls($myFile); - - //if the baseDir is "help", this would try to use "/help.content.tmpl" - $sectionFile = $this->baseDir .'.content.tmpl'; - $lsData = $this->fileSystemObj->ls(); - - if(isset($lsData[$sectionFile]) && is_array($lsData[$sectionFile])) { - $valid = TRUE; - $this->finalSection = $this->baseDir; - } - elseif(isset($sectionLsData[$myFile]) && $sectionLsData[$myFile]['type'] == 'file') { - //we're good. - $valid = TRUE; - $this->finalSection = $this->baseDir; - } - else { - $this->reason = __METHOD__ .": couldn't find base template."; - } - } - $this->isValid = $valid; - - return($valid); - }//end validate_page() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Loads the templates for the current page (performs template inheritance, too). - */ - private function load_page_templates() { - //should already be in the proper directory, start looping through sectionArr, - // looking for templates. - $mySectionArr = $this->sectionArr; - - $finalSection = $this->sectionArr[(count($this->sectionArr) -1)]; - foreach($mySectionArr as $index=>$value) { - $tmplList = $this->arrange_directory_contents('name', 'section'); - if(isset($tmplList[$value])) { - foreach($tmplList[$value] as $mySection=>$myTmpl) { - // - $this->templateList[$mySection] = $myTmpl; - } - } - if(!$this->fileSystemObj->cd($value)) { - break; - } - } - - //load the final template(s). - $finalTmplList = $this->arrange_directory_contents('name', 'section'); - if(isset($finalTmplList[$finalSection])) { - foreach($finalTmplList[$finalSection] as $mySection => $myTmpl) { - $this->templateList[$mySection] = $myTmpl; - } - } - elseif(is_array($finalTmplList)) { - foreach($finalTmplList as $mySection => $subArr) { - foreach($subArr as $internalSection => $myTmpl) { - $this->templateList[$mySection] = $myTmpl; - } - } - } - if($this->fileSystemObj->cd($finalSection)) { - //load the index stuff. - $tmplList = $this->arrange_directory_contents('name', 'section'); - if(isset($tmplList['index'])) { - foreach($tmplList['index'] as $mySection => $myTmpl) { - $this->templateList[$mySection] = $myTmpl; - } - } - if(isset($tmplList[$this->baseDir]['content'])) { - //load template for the main page (if $this->baseDir == "help", this would load "/help.content.tmpl" as content) - $this->templateList['content'] = $tmplList[$this->baseDir]['content']; - } - } - }//end load_page_templates() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * loads templates for the main section they're on. - */ - private function load_main_templates() { - $this->fileSystemObj->cd('/templates'); - //check to see if the present section is valid. - $this->fileSystemObj->cd($this->baseDir); - $dirContents = $this->arrange_directory_contents('name', 'section'); - if(is_array($dirContents)) { - foreach($dirContents as $mySection => $subArr) { - foreach($subArr as $subIndex=>$templateFilename) { - $this->templateList[$mySection] = $templateFilename; - } - } - } - }//end load_main_templates() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Loads any shared templates: these can be overwritten later. - */ - private function load_shared_templates($path=NULL) { - - if(!is_null($path)) { - $this->fileSystemObj->cd($path); - } - else { - $this->fileSystemObj->cd('/templates'); - } - - //pull a list of the files. - $dirContents = $this->arrange_directory_contents(); - if(count($dirContents['shared'])) { - - foreach($dirContents['shared'] as $section => $template) { - $this->templateList[$section] = $template; - } - } - }//end load_shared_templates() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Pulls a list of files in the current directory, & arranges them by section & - * name, or vice-versa. - */ - private function arrange_directory_contents($primaryIndex='section', $secondaryIndex='name') { - $directoryInfo = $this->fileSystemObj->ls(); - $arrangedArr = array(); - if(is_array($directoryInfo)) { - foreach($directoryInfo as $index=>$data) { - $myType = $data['type']; - if(($myType == 'file') && !in_array($index, $this->ignoredList[$myType])) { - $filename = $this->gfObj->create_list($this->fileSystemObj->cwd, $index, '/'); - $filename = preg_replace('/^\/templates/', '', $filename); - $filename = preg_replace('/^\/\//', '/', $filename); - //call another method to rip the filename apart properly, then arrange things as needed. - $pieces = $this->parse_filename($index); - $myPriIndex = $pieces[$primaryIndex]; - $mySecIndex = $pieces[$secondaryIndex]; - if(strlen($myPriIndex) && strlen($mySecIndex)) { - //only load if it's got BOTH parts of the filename. - $arrangedArr[$myPriIndex][$mySecIndex] = $filename; - } - } - } - } - - return($arrangedArr); - }//end arrange_directory_contents() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Takes a filename (string) and breaks it down into the "type", "section", and - * "name". I.E. for the filename "test.content.tmpl", type=tmpl, section="content", - * and "name"=test. - * TODO: set a way to define how the filenames are setup, so filenames can be "name.section.type" or "section.name.type". - */ - private function parse_filename($filename) { - //break it into it's various parts. - $myParts = explode('.', $filename); - $retval = array(); - $count = count($myParts); - if($count >= 3) { - //"type" is the last element of the array, and "section" is the second-to-last. - $type = array_pop($myParts); - - //define what types of files that are accepted: if it's not one of them, don't bother. - $acceptedTypes = array("tmpl"); - if(in_array($type, $acceptedTypes)) { - $section = array_pop($myParts); - - //just in case we want to allow templates with "."'s in them, rip off the - // last two parts, and use what's left as the name. - $stripThis = '.'. $section .'\.'. $type .'$'; - $name = preg_replace('/'. $stripThis .'/', '', $filename); - - $retval = array( - 'name' => $name, - 'section' => $section, - 'type' => $type - ); - } - } - - return($retval); - }//end parse_filename() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Finds all scripts in the /inlcudes directory, & adds them to the includesList array. - */ - private function load_includes() { - - //first load includes for the base directory. - $this->load_dir_includes($this->baseDir); - - //okay, now loop through $this->sectionArr & see if we can include anything else. - if(($this->fileSystemObj->cd($this->baseDir)) && is_array($this->sectionArr) && count($this->sectionArr) > 0) { - - foreach($this->sectionArr as $mySection) { - //Run includes. - $this->load_dir_includes($mySection); - - //attempt to cd() into the next directory, or die if we can't. - if(!$this->fileSystemObj->cd($mySection)) { - //no dice. Break the loop. - break; - } - } - } - - }//end load_includes() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Attempts to add a shared include & the given section's include file: used - * solely by load_includes(). - */ - private function load_dir_includes($section) { - $lsData = $this->fileSystemObj->ls(); - - //attempt to load the shared includes file. - if(isset($lsData['shared.inc']) && $lsData['shared.inc']['type'] == 'file') { - $this->includesList[] = $this->fileSystemObj->realcwd .'/shared.inc'; - } - - //attempt to load the section's includes file. - $myFile = $section .'.inc'; - if(isset($lsData[$myFile]) && $lsData[$myFile]['type'] == 'file') { - $this->includesList[] = $this->fileSystemObj->realcwd .'/'. $myFile; - } - - if(isset($lsData[$section]) && !count($this->sectionArr)) { - $this->fileSystemObj->cd($section); - $lsData = $this->fileSystemObj->ls(); - if(isset($lsData['index.inc'])) { - $this->includesList[] = $this->fileSystemObj->realcwd .'/index.inc'; - } - } - }//end load_dir_includes() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * Called when something is broken. - */ - private function die_gracefully($details=NULL) { - header('HTTP/1.0 404 Not Found'); - if($this->templateObj->template_file_exists('system/404.shared.tmpl')) { - //Simple "Page Not Found" error... show 'em. - $this->templateObj->add_template_var('main', $this->templateObj->file_to_string('system/404.shared.tmpl')); - $this->templateObj->add_template_var('details', $details); - $this->templateObj->add_template_var('datetime', date('m-d-Y H:i:s')); - $this->templateObj->print_page(); - exit; - } - else { - //TODO: make it *actually* die gracefully... the way it works now looks more like puke than grace. - throw new exception(__METHOD__ .": Couldn't find 404 template, plus additional error... \nDETAILS::: $details" . - "\nREASON::: ". $this->reason); - } - }//end die_gracefully() - //------------------------------------------------------------------------ - - - - //------------------------------------------------------------------------ - /** - * The super-magical method that includes files & finalizes things using - * the given templating engine. - * NOTE: the local variable "$page" is made so that the included scripts - * can make calls to the templating engine, just like they used to. It's - * AWESOME. - */ - function finish() { - //Avoid problems when REGISTER_GLOBALS is on... - $badUrlVars = array('page', 'this'); - foreach($badUrlVars as $badVarName) { - unset($_GET[$badVarName], $_POST[$badVarName]); - } - - $page =& $this->templateObj; - if(is_object($this->session)) { - $page->session =& $this->session; - } - - - //if we loaded an index, but there is no "content", then move 'em around so we have content. - if(isset($this->templateList['index']) && !isset($this->templateList['content'])) { - $this->templateList['content'] = $this->templateList['index']; - unset($this->templateList['index']); - } - - foreach($this->templateList as $mySection => $myTmpl) { - $myTmpl = preg_replace("/\/\//", "/", $myTmpl); - $page->add_template_file($mySection, $myTmpl); - } - unset($mySection); - unset($myTmpl); - - //make the "final section" available to scripts. - $finalSection =... [truncated message content] |
From: <cra...@us...> - 2009-01-29 20:18:43
|
Revision: 331 http://cs-content.svn.sourceforge.net/cs-content/?rev=331&view=rev Author: crazedsanity Date: 2009-01-29 20:18:41 +0000 (Thu, 29 Jan 2009) Log Message: ----------- Implementation of cs_contentAbstract{}. NOTE::: to avoid segfaults, cs_globalFunctions does NOT extend cs_contentAbstract. /contentSystemClass.php: * MAIN::: -- requires /abstract/cs_content.abstract.class.php -- extends cs_contentAbstract * __construct(): -- calls parent::__construct() -- removed things involving version & cs_globalFunctions (in parent constructor). /cs_bbCodeParser.class.php: * MAIN::: -- requires /abstract/cs_content.abstract.class.php -- extends cs_contentAbstract * __construct(): -- calls parent::__construct() -- removed things involving version & cs_globalFunctions (in parent constructor). /cs_fileSystemClass.php: * MAIN::: -- requires /abstract/cs_content.abstract.class.php -- extends cs_contentAbstract * __construct(): -- calls parent::__construct() -- removed things involving version & cs_globalFunctions (in parent constructor). * cdup(): -- replaced reference of "this->gf" to "this->gfObj" * cd(): -- replaced reference of "this->gf" to "this->gfObj" * filename2absolute(): -- replaced reference of "this->gf" to "this->gfObj" * rename(): -- replaced reference of "this->gf" to "this->gfObj" * resolve_path_with_dots(): -- replaced reference of "this->gf" to "this->gfObj" * check_chroot(): -- replaced reference of "this->gf" to "this->gfObj" * movefile(): -- replaced reference of "this->gf" to "this->gfObj" /cs_genericPageClass.php: * MAIN::: -- requires /abstract/cs_content.abstract.class.php -- extends cs_contentAbstract * __construct(): -- calls parent::__construct() -- removed things involving version & cs_globalFunctions (in parent constructor). /cs_phpDB.php: * MAIN::: -- requires /abstract/cs_content.abstract.class.php -- extends cs_contentAbstract * __construct(): -- calls parent::__construct() -- removed things involving version & cs_globalFunctions (in parent constructor). /cs_sessionClass.php: * MAIN::: -- requires /abstract/cs_content.abstract.class.php -- extends cs_contentAbstract * __construct(): -- calls parent::__construct() -- removed things involving version & cs_globalFunctions (in parent constructor). /cs_siteConfig.class.php: * MAIN::: -- requires /abstract/cs_content.abstract.class.php -- extends cs_contentAbstract * __construct(): -- calls parent::__construct() -- removed things involving version & cs_globalFunctions (in parent constructor). * parse_config(): -- replaced reference of "this->gf" to "this->gfObj" /cs_tabsClass.php: * MAIN::: -- requires /abstract/cs_content.abstract.class.php -- extends cs_contentAbstract * __construct(): -- calls parent::__construct() -- removed things involving version & cs_globalFunctions (in parent constructor). /abstract/cs_content.abstract.class.php [NEW]: * class that holds all duplicated functionality across libraries. * NOTE::: passing boolean false to the constructor avoids including or creating the cs_globalFunctions{} object. Modified Paths: -------------- trunk/1.0/contentSystemClass.php trunk/1.0/cs_bbCodeParser.class.php trunk/1.0/cs_fileSystemClass.php trunk/1.0/cs_genericPageClass.php trunk/1.0/cs_phpDB.php trunk/1.0/cs_sessionClass.php trunk/1.0/cs_siteConfig.class.php trunk/1.0/cs_tabsClass.php Added Paths: ----------- trunk/1.0/abstract/cs_content.abstract.class.php Added: trunk/1.0/abstract/cs_content.abstract.class.php =================================================================== --- trunk/1.0/abstract/cs_content.abstract.class.php (rev 0) +++ trunk/1.0/abstract/cs_content.abstract.class.php 2009-01-29 20:18:41 UTC (rev 331) @@ -0,0 +1,36 @@ +<?php +/* + * Created on Jan 29, 2009 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +require_once(dirname(__FILE__) ."/../../cs-versionparse/cs_version.abstract.class.php"); + + +abstract class cs_contentAbstract extends cs_versionAbstract { + + //------------------------------------------------------------------------- + function __construct($makeGfObj=true) { + $this->set_version_file_location(dirname(__FILE__) . '/../VERSION'); + $this->get_version(); + $this->get_project(); + + if($makeGfObj === true) { + //make a cs_globalFunctions{} object. + require_once(dirname(__FILE__) ."/../cs_globalFunctions.php"); + $this->gfObj = new cs_globalFunctions(); + } + }//end __construct() + //------------------------------------------------------------------------- + + + +} +?> \ No newline at end of file Property changes on: trunk/1.0/abstract/cs_content.abstract.class.php ___________________________________________________________________ Added: svn:keywords + HeadURL Id LastChangedDate LastChangedBy LastChangedRevision Date Revision Author Modified: trunk/1.0/contentSystemClass.php =================================================================== --- trunk/1.0/contentSystemClass.php 2009-01-29 19:44:01 UTC (rev 330) +++ trunk/1.0/contentSystemClass.php 2009-01-29 20:18:41 UTC (rev 331) @@ -70,14 +70,13 @@ $GLOBALS['SITE_ROOT'] = str_replace("/public_html", "", $GLOBALS['SITE_ROOT']); } -require_once(dirname(__FILE__) ."/cs_globalFunctions.php"); +require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); require_once(dirname(__FILE__) ."/cs_fileSystemClass.php"); require_once(dirname(__FILE__) ."/cs_sessionClass.php"); require_once(dirname(__FILE__) ."/cs_genericPageClass.php"); require_once(dirname(__FILE__) ."/cs_tabsClass.php"); -require_once(dirname(__FILE__) ."/../cs-versionparse/cs_version.abstract.class.php"); -class contentSystem extends cs_versionAbstract { +class contentSystem extends cs_contentAbstract { protected $baseDir = NULL; //base directory for templates & includes. protected $section = NULL; //section string, derived from the URL. @@ -109,11 +108,7 @@ $this->isTest = TRUE; } else { - $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); - $this->get_version(); - $this->get_project(); - //make a cs_globalFunctions{} object. - $this->gfObj = new cs_globalFunctions(); + parent::__construct(); //setup the section stuff... $repArr = array($_SERVER['SCRIPT_NAME'], "/"); Modified: trunk/1.0/cs_bbCodeParser.class.php =================================================================== --- trunk/1.0/cs_bbCodeParser.class.php 2009-01-29 19:44:01 UTC (rev 330) +++ trunk/1.0/cs_bbCodeParser.class.php 2009-01-29 20:18:41 UTC (rev 331) @@ -18,9 +18,9 @@ * been converted. */ -require_once(dirname(__FILE__) ."/../cs-versionparse/cs_version.abstract.class.php"); +require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); -class cs_bbCodeParser extends cs_versionAbstract { +class cs_bbCodeParser extends cs_contentAbstract { /** Array containing all the codes & how to parse them. */ private $bbCodeData = NULL; @@ -30,7 +30,7 @@ * Setup internal structures. */ function __construct() { - $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); + parent::__construct(false); # Which BBCode is accepted here $this->bbCodeData = array( 'bold' => array( Modified: trunk/1.0/cs_fileSystemClass.php =================================================================== --- trunk/1.0/cs_fileSystemClass.php 2009-01-29 19:44:01 UTC (rev 330) +++ trunk/1.0/cs_fileSystemClass.php 2009-01-29 20:18:41 UTC (rev 331) @@ -9,10 +9,9 @@ * $LastChangedRevision$ */ -require_once(dirname(__FILE__) ."/cs_globalFunctions.php"); -require_once(dirname(__FILE__) ."/../cs-versionparse/cs_version.abstract.class.php"); +require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); -class cs_fileSystemClass extends cs_versionAbstract { +class cs_fileSystemClass extends cs_contentAbstract { public $root; //actual root directory. public $cwd; //current directory; relative to $this->root @@ -20,7 +19,6 @@ public $dh; //directory handle. public $fh; //file handle. public $filename; //filename currently being used. - public $gf; //cs_globalFunctions{} object. public $lineNum = NULL; @@ -29,7 +27,6 @@ * The constructor. */ public function __construct($rootDir=NULL, $cwd=NULL, $initialMode=NULL) { - $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); //set the root directory that we'll be using; this is considered just like "/" in // linux. Directories above it are considered non-existent. if(($rootDir) AND (is_dir($rootDir))) { @@ -43,7 +40,8 @@ exit("UNUSEABLE ROOT: $rootDir"); } - $this->gf = new cs_globalFunctions(); + parent::__construct(); + $this->root = $this->resolve_path_with_dots($this->root); //set the CURRENT working directory... this should be a RELATIVE path to $this->root. @@ -84,8 +82,8 @@ } $myParts = explode('/', $myCwd); array_pop($myParts); - $myCwd = $this->gf->string_from_array($myParts, NULL, '/'); - $realCwd = $this->gf->create_list($this->root, $myCwd, '/'); + $myCwd = $this->gfObj->string_from_array($myParts, NULL, '/'); + $realCwd = $this->gfObj->create_list($this->root, $myCwd, '/'); if(file_exists($realCwd)) { $retval = TRUE; $this->realcwd = $realCwd; @@ -119,7 +117,7 @@ $retval = 1; } elseif(is_dir($this->realcwd .'/'. $newDir)) { //relative path... - $this->cwd = $this->gf->create_list($this->cwd, $newDir, '/'); + $this->cwd = $this->gfObj->create_list($this->cwd, $newDir, '/'); $this->realcwd .= '/'. $newDir; $retval = 1; } else { @@ -426,7 +424,7 @@ } if(!$this->check_chroot($retval, FALSE)) { - $this->gf->debug_print(func_get_args()); + $this->gfObj->debug_print(func_get_args()); throw new exception(__METHOD__ .": file is outside of allowed directory (". $retval .")"); } @@ -602,7 +600,7 @@ */ public function rename($currentFilename, $newFilename) { if($newFilename == $currentFilename) { - $this->gf->debug_print(func_get_args()); + $this->gfObj->debug_print(func_get_args()); throw new exception(__METHOD__ .": renaming file to same name"); } @@ -612,7 +610,7 @@ if($this->compare_open_filename($newFilename)) { //renaming a different file to our currently open file... - $this->gf->debug_print(func_get_args()); + $this->gfObj->debug_print(func_get_args()); throw new exception(__METHOD__ .": renaming another file (". $currentFilename .") to the currently open filename (". $newFilename .")"); } else { @@ -805,7 +803,7 @@ } } - $retval = $this->gf->string_from_array($finalPieces, NULL, '/'); + $retval = $this->gfObj->string_from_array($finalPieces, NULL, '/'); if($isAbsolute) { $retval = '/'. $retval; } @@ -844,10 +842,10 @@ $pathDir = $pathPieces[$index]; if($pathDir != $dirName) { $retval = FALSE; - $this->gf->debug_print(__METHOD__ .": failed... tmp=(". $tmp ."), dirName=(". $dirName .")"); + $this->gfObj->debug_print(__METHOD__ .": failed... tmp=(". $tmp ."), dirName=(". $dirName .")"); break; } - $tmp = $this->gf->create_list($tmp, $dirName, '/'); + $tmp = $this->gfObj->create_list($tmp, $dirName, '/'); } return($retval); @@ -884,7 +882,7 @@ $retval = rename($filename, $destination); } else { - $this->gf->debug_print(__METHOD__ .":: ". $this->check_chroot($destination),1); + $this->gfObj->debug_print(__METHOD__ .":: ". $this->check_chroot($destination),1); throw new exception(__METHOD__ .':: destination is not in the directory path (from=['. $filename .'], to=['. $destination .']'); } } Modified: trunk/1.0/cs_genericPageClass.php =================================================================== --- trunk/1.0/cs_genericPageClass.php 2009-01-29 19:44:01 UTC (rev 330) +++ trunk/1.0/cs_genericPageClass.php 2009-01-29 20:18:41 UTC (rev 331) @@ -8,9 +8,9 @@ * $LastChangedRevision$ */ require_once(dirname(__FILE__) ."/template.inc"); -require_once(dirname(__FILE__) ."/../cs-versionparse/cs_version.abstract.class.php"); +require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); -class cs_genericPage extends cs_versionAbstract { +class cs_genericPage extends cs_contentAbstract { var $templateObj; //template object to parse the pages var $templateVars = array(); //our copy of the global templateVars var $mainTemplate; //the default layout of the site @@ -32,13 +32,14 @@ //handle some configuration. $this->allowRedirect = $allowRedirect; + //initialize stuff from our parent... + parent::__construct(); + //initialize some internal stuff. - $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); $this->initialize_locals($mainTemplateFile); //if they need to be logged-in... $this->check_login($restrictedAccess); - $this->gfObj = new cs_globalFunctions; if(!defined('CS-CONTENT_SESSION_NAME')) { define("CS-CONTENT_SESSION_NAME", ini_get('session.name')); Modified: trunk/1.0/cs_phpDB.php =================================================================== --- trunk/1.0/cs_phpDB.php 2009-01-29 19:44:01 UTC (rev 330) +++ trunk/1.0/cs_phpDB.php 2009-01-29 20:18:41 UTC (rev 331) @@ -24,17 +24,16 @@ // /////////////////////// -require_once(dirname(__FILE__) ."/../cs-versionparse/cs_version.abstract.class.php"); +require_once(dirname(__FILE__) ."/abstract/cs_content.abstract.class.php"); require_once(dirname(__FILE__) ."/abstract/cs_phpDB.abstract.class.php"); -class cs_phpDB extends cs_versionAbstract { +class cs_phpDB extends cs_contentAbstract { private $dbLayerObj; private $dbType; //========================================================================= public function __construct($type='pgsql') { - $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); if(strlen($type)) { @@ -43,12 +42,8 @@ $this->dbLayerObj = new $className; $this->dbType = $type; - $this->gfObj = new cs_globalFunctions; + parent::__construct(); - if(defined('DEBUGPRINTOPT')) { - $this->gfObj->debugPrintOpt = DEBUGPRINTOPT; - } - $this->isInitialized = TRUE; } else { Modified: trunk/1.0/cs_sessionClass.php =================================================================== --- trunk/1.0/cs_sessionClass.php 2009-01-29 19:44:01 UTC (rev 330) +++ trunk/1.0/cs_sessionClass.php 2009-01-29 20:18:41 UTC (rev 331) @@ -10,7 +10,7 @@ require_once(dirname(__FILE__) ."/../cs-versionparse/cs_version.abstract.class.php"); -class cs_session extends cs_versionAbstract { +class cs_session extends cs_contentAbstract { protected $db; public $uid; @@ -26,7 +26,7 @@ * used as the session name. */ function __construct($createSession=1) { - $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); + parent::__construct(false); if($createSession) { if(!is_null($createSession) && strlen($createSession) && !is_numeric($createSession)) { session_name($createSession); Modified: trunk/1.0/cs_siteConfig.class.php =================================================================== --- trunk/1.0/cs_siteConfig.class.php 2009-01-29 19:44:01 UTC (rev 330) +++ trunk/1.0/cs_siteConfig.class.php 2009-01-29 20:18:41 UTC (rev 331) @@ -15,12 +15,12 @@ * */ -require_once(dirname(__FILE__) .'/cs_globalFunctions.php'); +require_once(dirname(__FILE__) .'/abstract/cs_content.abstract.class.php'); require_once(dirname(__FILE__) .'/cs_fileSystemClass.php'); require_once(dirname(__FILE__). '/../cs-phpxml/cs_phpxmlParser.class.php'); require_once(dirname(__FILE__) .'/../cs-phpxml/cs_phpxmlBuilder.class.php'); -class cs_siteConfig { +class cs_siteConfig extends cs_contentAbstract { /** XMLParser{} object, for reading XML config file. */ private $xmlReader; @@ -77,8 +77,7 @@ $section = strtoupper($section); $this->setVarPrefix=$setVarPrefix; - $this->gf = new cs_globalFunctions; - $this->gf->debugPrintOpt=1; + parent::__construct(); if(strlen($configFileLocation) && file_exists($configFileLocation)) { @@ -181,8 +180,8 @@ $itemValue = $itemValue['value']; if(preg_match("/{/", $itemValue)) { $origVal = $itemValue; - $itemValue = $this->gf->mini_parser($itemValue, $specialVars, '{', '}'); - $itemValue = $this->gf->mini_parser($itemValue, $parseThis, '{', '}'); + $itemValue = $this->gfObj->mini_parser($itemValue, $specialVars, '{', '}'); + $itemValue = $this->gfObj->mini_parser($itemValue, $parseThis, '{', '}'); $itemValue = preg_replace("/[\/]{2,}/", "/", $itemValue); } Modified: trunk/1.0/cs_tabsClass.php =================================================================== --- trunk/1.0/cs_tabsClass.php 2009-01-29 19:44:01 UTC (rev 330) +++ trunk/1.0/cs_tabsClass.php 2009-01-29 20:18:41 UTC (rev 331) @@ -4,7 +4,10 @@ * */ -class cs_tabs extends cs_versionAbstract { +require_once(dirname(__FILE__) .'/abstract/cs_content.abstract.class.php'); + + +class cs_tabs extends cs_contentAbstract { private $tabsArr; private $selectedTab; @@ -25,7 +28,7 @@ * @param $templateVar (str,optional) What template var to find the tab blockrows in. */ public function __construct(cs_genericPage $csPageObj, $templateVar="tabs") { - $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); + parent::__construct(false); if(is_null($csPageObj) || !is_object($csPageObj) || get_class($csPageObj) !== 'cs_genericPage') { //can't continue without that! throw new exception("cs_tabs::__construct(): cannot load without cs_genericPage{} object (". get_class($csPageObj) .")"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-29 19:44:03
|
Revision: 330 http://cs-content.svn.sourceforge.net/cs-content/?rev=330&view=rev Author: crazedsanity Date: 2009-01-29 19:44:01 +0000 (Thu, 29 Jan 2009) Log Message: ----------- Updated SVN Keywords. Property Changed: ---------------- trunk/1.0/abstract/cs_phpDB.abstract.class.php trunk/1.0/db_types/cs_phpDB__mysql.class.php trunk/1.0/db_types/cs_phpDB__pgsql.class.php trunk/1.0/db_types/cs_phpDB__sqlite.class.php Property changes on: trunk/1.0/abstract/cs_phpDB.abstract.class.php ___________________________________________________________________ Added: svn:keywords + HeadURL Id LastChangedDate LastChangedBy LastChangedRevision Date Revision Author Property changes on: trunk/1.0/db_types/cs_phpDB__mysql.class.php ___________________________________________________________________ Modified: svn:keywords - Id HeadURL Date Revision Author + HeadURL Id LastChangedDate LastChangedBy LastChangedRevision Date Revision Author Property changes on: trunk/1.0/db_types/cs_phpDB__pgsql.class.php ___________________________________________________________________ Modified: svn:keywords - Id HeadURL Date Revision Author + HeadURL Id LastChangedDate LastChangedBy LastChangedRevision Date Revision Author Property changes on: trunk/1.0/db_types/cs_phpDB__sqlite.class.php ___________________________________________________________________ Modified: svn:keywords - Id HeadURL Date Revision Author + HeadURL Id LastChangedDate LastChangedBy LastChangedRevision Date Revision Author This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-29 19:39:59
|
Revision: 329 http://cs-content.svn.sourceforge.net/cs-content/?rev=329&view=rev Author: crazedsanity Date: 2009-01-29 19:39:55 +0000 (Thu, 29 Jan 2009) Log Message: ----------- Add an abstract parent class for all database types. NOTE::: this was tested on the pgsql version (in a roundabout way), but not for mysql or sqlite. /cs_phpDB.php: * MAIN::: -- requires the new abstract parent class. /abstract/cs_phpDB.abstract.class.php [NEW]: * holds a list of methods required to be a proper database layer, along with a few classes and such to help minimize code replication. /db_types/cs_phpDB__mysql.class.php: * MAIN::: -- now extends cs_phpDBAbstract{}. * __construct(): -- calls parent::__construct(). -- removed unnecessary code (now in cs_phpDBAbstract{}) * sanity_check() [DELETED]: -- moved into cs_phpDBAbstract{} * disconnect() [DELETED]: -- moved into cs_phpDBAbstract{} * currRow() [DELETED]: -- moved into cs_phpDBAbstract{} * querySafe() [DELETED]: -- moved into cs_phpDBAbstract{} * sqlSafe() [DELETED]: -- moved into cs_phpDBAbstract{} * get_transaction_status(): -- arbitrarily returns false (previously was using PostgreSQL functions, so any return it might have given would have been invalid at best). * start_copy() [DELETED]: -- removed; it was a PostgreSQL-specific implementation. * put_line() [DELETED]: -- removed; it was a PostgreSQL-specific implementation. * end_copy() [DELETED]: -- removed; it was a PostgreSQL-specific implementation. * get_transaction_level() [DELETED]: -- removed; it was a PostgreSQL-specific implementation. * is_in_transaction(): -- arbitrarily returns 0, as there are no transaction implementations. /db_types/cs_phpDB__pgsql.class.php: * MAIN::: -- slightly modified header comments so Eclipse can shrink the whole thing. -- extends cs_phpDBAbstract{} * __construct(): -- calls parent::__construct() -- removed unnecessary code (now in cs_phpDBAbstract{}) * sanity_check() [DELETED]: -- moved into cs_phpDBAbstract{} * disconnect() [DELETED]: -- moved into cs_phpDBAbstract{} * currRow() [DELETED]: -- moved into cs_phpDBAbstract{} * querySafe() [DELETED]: -- moved into cs_phpDBAbstract{} * sqlSafe() [DELETED]: -- moved into cs_phpDBAbstract{} /db_types/cs_phpDB__sqlite.class.php: * MAIN::: -- now extends cs_phpDBAbstract{}. * __construct(): -- calls parent::__construct(). -- removed unnecessary code (now in cs_phpDBAbstract{}) * sanity_check() [DELETED]: -- moved into cs_phpDBAbstract{} * disconnect() [DELETED]: -- moved into cs_phpDBAbstract{} * querySafe() [DELETED]: -- moved into cs_phpDBAbstract{} * sqlSafe() [DELETED]: -- moved into cs_phpDBAbstract{} Modified Paths: -------------- trunk/1.0/cs_phpDB.php trunk/1.0/db_types/cs_phpDB__mysql.class.php trunk/1.0/db_types/cs_phpDB__pgsql.class.php trunk/1.0/db_types/cs_phpDB__sqlite.class.php Added Paths: ----------- trunk/1.0/abstract/ trunk/1.0/abstract/cs_phpDB.abstract.class.php Added: trunk/1.0/abstract/cs_phpDB.abstract.class.php =================================================================== --- trunk/1.0/abstract/cs_phpDB.abstract.class.php (rev 0) +++ trunk/1.0/abstract/cs_phpDB.abstract.class.php 2009-01-29 19:39:55 UTC (rev 329) @@ -0,0 +1,166 @@ +<?php +/* + * Created on Jan 29, 2009 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_phpDBAbstract { + + /** Internal result set pointer. */ + protected $result = NULL; + + /** Internal error code. */ + protected $errorCode = 0; + + /** Status of the current transaction. */ + protected $transStatus = NULL; + + /** Whether there is a transaction in progress or not. */ + protected $inTrans = FALSE; + + /** Holds the last query performed. */ + protected $lastQuery = NULL; + + /** List of queries that have been run */ + protected $queryList=array(); + + /** How many seconds to wait for a query before cancelling it. */ + protected $timeOutSeconds = NULL; + + /** Internal check to determine if a connection has been established. */ + protected $isConnected=FALSE; + + /** Internal check to determine if the parameters have been set. */ + protected $paramsAreSet=FALSE; + + /** Resource handle. */ + protected $connectionID = -1; + + /** Hostname or IP to connect to */ + protected $host; + + /** Port to connect to (default for Postgres is 5432) */ + protected $port; + + /** Name of the database */ + protected $dbname; + + /** Username to connect to the database */ + protected $user; + + /** password to connect to the database */ + protected $password; + + /** Row counter for looping through records */ + protected $row = -1; + + /** cs_globalFunctions object, for string stuff. */ + protected $gfObj; + + /** Internal check to ensure the object has been properly created. */ + protected $isInitialized=FALSE; + + /** List of prepared statements, indexed off the name, with the sub-array being fieldname=>dataType. */ + protected $preparedStatements = array(); + + /** Set to TRUE to save all queries into an array. */ + protected $useQueryList=FALSE; + + /** array that essentially remembers how many times beginTrans() was called. */ + protected $transactionTree = NULL; + + + + //Define some abstract methods so they MUST be provided in order for things to work. + abstract public function set_db_info(array $params); + abstract public function close(); + abstract public function connect(array $dbParams=NULL, $forceNewConnection=FALSE); + abstract public function exec($query); + abstract public function errorMsg($setMessage=null, $logError=null); + abstract public function fobject(); + abstract public function farray(); + abstract public function farray_fieldnames($index=null, $numbered=null,$unsetIndex=1); + abstract public function farray_nvp($name, $value); + abstract public function farray_numbered(); + abstract public function numAffected(); + abstract public function numRows(); + abstract public function is_connected(); + + + //========================================================================= + public function __construct() { + $this->gfObj = new cs_globalFunctions; + $this->isInitialized = true; + }//end __construct() + //========================================================================= + + + + //========================================================================= + /** + * Make sure the object is sane. + */ + final protected function sanity_check() { + if($this->isInitialized !== TRUE) { + throw new exception(__METHOD__ .": not properly initialized"); + } + }//end sanity_check() + //========================================================================= + + + + //========================================================================= + /** + * Disconnect from the database (calls internal "close()" method). + */ + public function disconnect() { + return($this->close()); + }//end disconnect() + //========================================================================= + + + + //========================================================================= + public function affectedRows() { + return($this->numAffected()); + }//end affectedRows() + //========================================================================= + + + + //========================================================================= + public function currRow() { + return($this->row); + }//end currRow() + //========================================================================= + + + + //========================================================================= + public function querySafe($string) { + return($this->gfObj->cleanString($string,"query")); + }//end querySafe() + //========================================================================= + + + + //========================================================================= + /** + * Make it SQL safe. + */ + public function sqlSafe($string) { + return($this->gfObj->cleanString($string,"sql")); + }//end sqlSafe() + //========================================================================= + + + +} +?> \ No newline at end of file Modified: trunk/1.0/cs_phpDB.php =================================================================== --- trunk/1.0/cs_phpDB.php 2009-01-27 16:25:08 UTC (rev 328) +++ trunk/1.0/cs_phpDB.php 2009-01-29 19:39:55 UTC (rev 329) @@ -25,6 +25,7 @@ /////////////////////// require_once(dirname(__FILE__) ."/../cs-versionparse/cs_version.abstract.class.php"); +require_once(dirname(__FILE__) ."/abstract/cs_phpDB.abstract.class.php"); class cs_phpDB extends cs_versionAbstract { Modified: trunk/1.0/db_types/cs_phpDB__mysql.class.php =================================================================== --- trunk/1.0/db_types/cs_phpDB__mysql.class.php 2009-01-27 16:25:08 UTC (rev 328) +++ trunk/1.0/db_types/cs_phpDB__mysql.class.php 2009-01-29 19:39:55 UTC (rev 329) @@ -11,9 +11,8 @@ */ +class cs_phpDB__mysql extends cs_phpDBAbstract { -class cs_phpDB__mysql { - /** Internal result set pointer. */ protected $result = NULL; @@ -84,13 +83,7 @@ //========================================================================= public function __construct() { - $this->gfObj = new cs_globalFunctions; - - if(defined('DEBUGPRINTOPT')) { - $this->gfObj->debugPrintOpt = DEBUGPRINTOPT; - } - - $this->isInitialized = TRUE; + parent::__construct(); }//end __construct() //========================================================================= @@ -98,19 +91,6 @@ //========================================================================= /** - * Make sure the object is sane. - */ - final protected function sanity_check() { - if($this->isInitialized !== TRUE) { - throw new exception(__METHOD__ .": not properly initialized"); - } - }//end sanity_check() - //========================================================================= - - - - //========================================================================= - /** * Set appropriate parameters for database connection */ public function set_db_info(array $params){ @@ -143,18 +123,6 @@ //========================================================================= /** - * Wrapper for close() - */ - function disconnect() { - //Disconnect from $database - return($this->close()); - }//end disconnect() - //========================================================================= - - - - //========================================================================= - /** * Standard method to close connection. */ function close() { @@ -669,23 +637,11 @@ function affectedRows(){ return($this->numAffected()); }//end affectedRows() - //========================================================================= //========================================================================= /** - * Returns the current row number. - */ - function currRow(){ - return($this->row); - }//end currRow() - //========================================================================= - - - - //========================================================================= - /** * Get the number of fields in a result. */ // get the number of fields in a result @@ -750,28 +706,6 @@ //========================================================================= /** - * Gets rid of evil characters that might lead ot SQL injection attacks. - */ - function querySafe($string) { - return($this->gfObj->cleanString($string,"query")); - }//end querySafe() - //========================================================================= - - - - //========================================================================= - /** - * Make it SQL safe. - */ - function sqlSafe($string) { - return($this->gfObj->cleanString($string,"sql")); - }//end sqlSafe() - //========================================================================= - - - - //========================================================================= - /** * Gives textual explanation of the current status of our database * connection. * @@ -785,61 +719,7 @@ */ function get_transaction_status($goodOrBad=TRUE) { //TODO: implement MySQL version.. - $myStatus = pg_transaction_status($this->connectionID); - $text = 'unknown'; - switch($myStatus) { - case PGSQL_TRANSACTION_IDLE: { - //No query in progress: it's idle. - $goodOrBadValue = 1; - $text = 'idle'; - $this->inTrans = FALSE; - } - break; - - - case PGSQL_TRANSACTION_ACTIVE: { - //there's a command in progress. - $goodOrBadValue = 2; - $text = 'processing'; - } - break; - - - case PGSQL_TRANSACTION_INTRANS: { - //connection idle within a valid transaction block. - $goodOrBadValue = 1; - $text = 'valid transaction'; - $this->inTrans = TRUE; - } - break; - - - case PGSQL_TRANSACTION_INERROR: { - //connection idle within a broken transaction. - $goodOrBadValue = 0; - $text = 'failed transaction'; - $this->inTrans = TRUE; - } - break; - - - case PGSQL_TRANSACTION_UNKNOWN: - default: { - //the connection is bad. - $goodOrBadValue = -1; - $text = 'bad connection'; - } - break; - } - - //do they want text or the good/bad number? - $retval = $text; - $this->transactionStatus = $goodOrBadValue; - if($goodOrBad) { - //they want the number. - $retval = $goodOrBadValue; - } - + $retval = false; return($retval); }//end get_transaction_status() //========================================================================= @@ -861,105 +741,11 @@ //========================================================================= /** - * Starts a copy command. - * - * TODO: implement safeguards so they can only put a line until the copy is ended. - */ - public function start_copy($tableName, array $fields) { - //TODO: implement MySQL version.. - $retval = FALSE; - $copyStmt = "COPY ". $tableName ." (". $this->gfObj->string_from_array($fields, NULL, ", ") . ") FROM stdin;"; - $this->exec($copyStmt); - if(!strlen($this->errorMsg())) { - //TODO: set something here so that NOTHING ELSE can be done except put_line() and end_copy(). - $this->copyInProgress = TRUE; - $retval = TRUE; - } - else { - $this->end_copy(); - $retval = FALSE; - } - - return($retval); - }//end start_copy() - //========================================================================= - - - - //========================================================================= - /** - * Used to send a line to the COPY in progress (only if it was initiated by - * the internal start_copy() method). - * - * NOTE: the "end-of-copy" line, '\.', should NEVER be sent here. - */ - public function put_line($line) { - //TODO: implement MySQL version.. - $retval = FALSE; - if($this->copyInProgress === TRUE) { - $myLine = trim($line); - $myLine .= "\n"; - - $retval = pg_put_line($this->connectionID, $myLine); - } - else { - throw new exception(__METHOD__ .": cannot send line if no copy is in progress"); - } - - return($retval); - }//end put_line() - //========================================================================= - - - - //========================================================================= - public function end_copy() { - if($this->copyInProgress === TRUE) { - //send the end-of-copy line... - $this->put_line("\\.\n"); - } - - //TODO: implement MySQL version.. - $retval = pg_end_copy($this->connectionID); - - return($retval); - }//end end_copy() - //========================================================================= - - - - //========================================================================= - /** - * Determines how many times a transaction has been started. Starting - * multiple transactions does NOT protect the outer transaction from - * problems that occur in the inner transaction. In fact, it does the - * opposite: it protects the code from committing too early (which might - * destroy something that depending on the transaction). - */ - public function get_transaction_level() { - if(is_array($this->transactionTree)) { - $retval = count($this->transactionTree); - } - else { - $retval = 0; - } - - return($retval); - }//end get_transaction_level() - //========================================================================= - - - - //========================================================================= - /** * Simple way to determine if the current connection is inside a * transaction or not. */ public function is_in_transaction() { - $retval = 0; - if($this->inTrans || $this->get_transaction_level() != 0) { - $retval = TRUE; - } + $retval=0; return($retval); }//end is_in_transaction() //========================================================================= Modified: trunk/1.0/db_types/cs_phpDB__pgsql.class.php =================================================================== --- trunk/1.0/db_types/cs_phpDB__pgsql.class.php 2009-01-27 16:25:08 UTC (rev 328) +++ trunk/1.0/db_types/cs_phpDB__pgsql.class.php 2009-01-29 19:39:55 UTC (rev 329) @@ -8,29 +8,29 @@ * Last Committted Date: $Date$ * Last Committed Path:: $HeadURL$ * + * ////////////////////// + * ORIGINATION INFO: + * Author: Trevin Chow (with contributions from Lee Pang, wle...@ho...) + * Email: t1...@ma... + * Date: February 21, 2000 + * Last Updated: August 14, 2001 + * + * Description: + * Abstracts both the php function calls and the server information to POSTGRES + * databases. Utilizes class variables to maintain connection information such + * as number of rows, result id of last operation, etc. + * + * ///////////////////// + * + * TODO: option to not use layered transactions + * TODO: rollbackTrans() in layered transaction causes abort when final layer is committed/aborted + * TODO: stop sending queries to backend when transction is bad/aborted. + * TODO: commit/abort specific layer requests (i.e. if there's 8 layers & the first is named "x", calling commitTrans("x") will cause the whole transaction to commit & all layers to be destroyed. */ -/////////////////////// -// ORIGINATION INFO: -// Author: Trevin Chow (with contributions from Lee Pang, wle...@ho...) -// Email: t1...@ma... -// Date: February 21, 2000 -// Last Updated: August 14, 2001 -// -// Description: -// Abstracts both the php function calls and the server information to POSTGRES -// databases. Utilizes class variables to maintain connection information such -// as number of rows, result id of last operation, etc. -// -/////////////////////// -//TODO: option to not use layered transactions -//TODO: rollbackTrans() in layered transaction causes abort when final layer is committed/aborted -//TODO: stop sending queries to backend when transction is bad/aborted. -//TODO: commit/abort specific layer requests (i.e. if there's 8 layers & the first is named "x", calling commitTrans("x") will cause the whole transaction to commit & all layers to be destroyed. +class cs_phpDB__pgsql extends cs_phpDBAbstract { -class cs_phpDB__pgsql { - /** Internal result set pointer. */ protected $result = NULL; @@ -101,13 +101,7 @@ //========================================================================= public function __construct() { - $this->gfObj = new cs_globalFunctions; - - if(defined('DEBUGPRINTOPT')) { - $this->gfObj->debugPrintOpt = DEBUGPRINTOPT; - } - - $this->isInitialized = TRUE; + parent::__construct(); }//end __construct() //========================================================================= @@ -115,19 +109,6 @@ //========================================================================= /** - * Make sure the object is sane. - */ - final protected function sanity_check() { - if($this->isInitialized !== TRUE) { - throw new exception(__METHOD__ .": not properly initialized"); - } - }//end sanity_check() - //========================================================================= - - - - //========================================================================= - /** * Set appropriate parameters for database connection */ public function set_db_info(array $params){ @@ -160,18 +141,6 @@ //========================================================================= /** - * Wrapper for close() - */ - function disconnect() { - //Disconnect from $database - return($this->close()); - }//end disconnect() - //========================================================================= - - - - //========================================================================= - /** * Standard method to close connection. */ function close() { @@ -702,17 +671,6 @@ //========================================================================= /** - * Returns the current row number. - */ - function currRow(){ - return($this->row); - }//end currRow() - //========================================================================= - - - - //========================================================================= - /** * Get the number of fields in a result. */ // get the number of fields in a result @@ -882,28 +840,6 @@ //========================================================================= /** - * Gets rid of evil characters that might lead ot SQL injection attacks. - */ - function querySafe($string) { - return($this->gfObj->cleanString($string,"query")); - }//end querySafe() - //========================================================================= - - - - //========================================================================= - /** - * Make it SQL safe. - */ - function sqlSafe($string) { - return($this->gfObj->cleanString($string,"sql")); - }//end sqlSafe() - //========================================================================= - - - - //========================================================================= - /** * Gives textual explanation of the current status of our database * connection. * Modified: trunk/1.0/db_types/cs_phpDB__sqlite.class.php =================================================================== --- trunk/1.0/db_types/cs_phpDB__sqlite.class.php 2009-01-27 16:25:08 UTC (rev 328) +++ trunk/1.0/db_types/cs_phpDB__sqlite.class.php 2009-01-29 19:39:55 UTC (rev 329) @@ -11,7 +11,7 @@ */ -class cs_phpDB__sqlite { +class cs_phpDB__sqlite extends cs_phpDBAbstract { /** Internal result set pointer. */ protected $result = NULL; @@ -71,13 +71,7 @@ //========================================================================= public function __construct() { - $this->gfObj = new cs_globalFunctions; - - if(defined('DEBUGPRINTOPT')) { - $this->gfObj->debugPrintOpt = DEBUGPRINTOPT; - } - - $this->isInitialized = TRUE; + parent::__construct(); }//end __construct() //========================================================================= @@ -85,19 +79,6 @@ //========================================================================= /** - * Make sure the object is sane. - */ - final protected function sanity_check() { - if($this->isInitialized !== TRUE) { - throw new exception(__METHOD__ .": not properly initialized"); - } - }//end sanity_check() - //========================================================================= - - - - //========================================================================= - /** * Set appropriate parameters for database connection */ public function set_db_info(array $params){ @@ -130,18 +111,6 @@ //========================================================================= /** - * Wrapper for close() - */ - function disconnect() { - //Disconnect from $database - return($this->close()); - }//end disconnect() - //========================================================================= - - - - //========================================================================= - /** * Standard method to close connection. */ function close() { @@ -599,28 +568,6 @@ //========================================================================= - /** - * Gets rid of evil characters that might lead ot SQL injection attacks. - */ - function querySafe($string) { - return($this->gfObj->cleanString($string,"query")); - }//end querySafe() - //========================================================================= - - - - //========================================================================= - /** - * Make it SQL safe. - */ - function sqlSafe($string) { - return($this->gfObj->cleanString($string,"sql")); - }//end sqlSafe() - //========================================================================= - - - - //========================================================================= public function is_connected() { $retval = FALSE; if(is_resource($this->connectionID) && $this->isConnected === TRUE) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-27 16:25:19
|
Revision: 328 http://cs-content.svn.sourceforge.net/cs-content/?rev=328&view=rev Author: crazedsanity Date: 2009-01-27 16:25:08 +0000 (Tue, 27 Jan 2009) Log Message: ----------- Release 0.9.x no longer supported, as 1.0 is soon to be released. Added Paths: ----------- unsupported/0.9/ Removed Paths: ------------- releases/0.9/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-27 16:24:06
|
Revision: 327 http://cs-content.svn.sourceforge.net/cs-content/?rev=327&view=rev Author: crazedsanity Date: 2009-01-27 16:24:01 +0000 (Tue, 27 Jan 2009) Log Message: ----------- *** RELEASE 1.0-ALPHA1 *** SUMMARY OF CHANGES::: * cs_globalFunctions::debug_print uses constants then globals for printing * cs_globalFunctions::cleanString now allows "bool/boolean" type * cs_globalFunctions::interpret_bool now available * unit tests to ensure things work as expected (and documents behaviour/changes). * new cs_siteConfig system, for consolidating configuration into one XML file. * Some unit testing, to help make sure code works as it is intended. * better exception handling for database layers. * Updated to handle the (forth-coming) 1.0 release of cs-phpxml (for cs_siteConfig) Added Paths: ----------- releases/1.0/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-26 18:47:54
|
Revision: 326 http://cs-content.svn.sourceforge.net/cs-content/?rev=326&view=rev Author: crazedsanity Date: 2009-01-26 18:47:51 +0000 (Mon, 26 Jan 2009) Log Message: ----------- Updated VERSION file, preparing to move into trunk (1.0-ALPHA1) Modified Paths: -------------- trunk/1.0/VERSION Property Changed: ---------------- trunk/1.0/VERSION Modified: trunk/1.0/VERSION =================================================================== --- trunk/1.0/VERSION 2009-01-26 01:33:48 UTC (rev 325) +++ trunk/1.0/VERSION 2009-01-26 18:47:51 UTC (rev 326) @@ -1,5 +1,5 @@ ## Stores the current version of the cs-content system, and it's source. Please do NOT modify this file. -VERSION: 0.10.14 +VERSION: 1.0-ALPHA1 PROJECT: cs-content -$HeadURL:https://cs-content.svn.sourceforge.net/svnroot/cs-content/trunk/VERSION $ \ No newline at end of file +$HeadURL$ \ No newline at end of file Property changes on: trunk/1.0/VERSION ___________________________________________________________________ Modified: svn:keywords - HeadURL + HeadURL Id This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-26 02:20:14
|
Revision: 325 http://cs-content.svn.sourceforge.net/cs-content/?rev=325&view=rev Author: crazedsanity Date: 2009-01-26 01:33:48 +0000 (Mon, 26 Jan 2009) Log Message: ----------- Reverse merge (HEAD:311) to match /releases/0.10 Modified Paths: -------------- trunk/0.10/cs_globalFunctions.php trunk/0.10/db_types/cs_phpDB__pgsql.class.php Removed Paths: ------------- trunk/0.10/cs_siteConfig.class.php trunk/0.10/tests/ Modified: trunk/0.10/cs_globalFunctions.php =================================================================== --- trunk/0.10/cs_globalFunctions.php 2009-01-26 01:29:21 UTC (rev 324) +++ trunk/0.10/cs_globalFunctions.php 2009-01-26 01:33:48 UTC (rev 325) @@ -17,17 +17,10 @@ public function __construct() { //These checks have been implemented for pseudo backwards-compatibility // (internal vars won't change if GLOBAL vars changed). - if(defined('DEBUGREMOVEHR')) { - $this->debugRemoveHr = constant('DEBUGREMOVEHR'); - } - elseif(isset($GLOBALS['DEBUGREMOVEHR'])) { + if(isset($GLOBALS['DEBUGREMOVEHR'])) { $this->debugRemoveHr = $GLOBALS['DEBUGREMOVEHR']; } - - if(defined('DEBUGPRINTOPT')) { - $this->debugPrintOpt = constant('DEBUGPRINTOPT'); - } - elseif(isset($GLOBALS['DEBUGPRINTOPT'])) { + if(isset($GLOBALS['DEBUGPRINTOPT'])) { $this->debugPrintOpt = $GLOBALS['DEBUGPRINTOPT']; } $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); @@ -62,13 +55,15 @@ $this->oldForceSqlQuotes = $this->forceSqlQuotes; $this->forceSqlQuotes = $newSetting; $retval = true; + $this->debug_print(__METHOD__ .": swapped (OLD=". $this->oldForceSqlQuotes .", CUR=". $this->forceSqlQuotes .")"); } else { $retval = false; + $this->debug_print(__METHOD__ .": no swap (OLD=". $this->oldForceSqlQuotes .", CUR=". $this->forceSqlQuotes .")"); } return($retval); - }//end switch_force_sql_quotes() + }//end force_sql_quotes() //========================================================================= @@ -380,7 +375,6 @@ */ $evilChars = array("\$", "%", "~", "*",">", "<", "-", "{", "}", "[", "]", ")", "(", "&", "#", "?", ".", "\,","\/","\\","\"","\|","!","^","+","`","\n","\r"); $cleanThis = preg_replace("/\|/","",$cleanThis); - $cleanThis = preg_replace("/\'/", "", $cleanThis); $cleanThis = str_replace($evilChars,"", $cleanThis); $cleanThis = stripslashes(addslashes($cleanThis)); break; @@ -519,7 +513,7 @@ case "name": case "names": - //allows only things in the "alpha" case and single quotes. + //removes everything in the "alpha" case, but allows "'". $cleanThis = preg_replace("/[^a-zA-Z']/", "", $cleanThis); break; @@ -531,7 +525,7 @@ case "bool": case "boolean": //makes it either T or F (gotta lower the string & only check the first char to ensure accurate results). - $cleanThis = $this->interpret_bool($cleanThis, array('f', 't')); + $cleanThis = interpret_bool($cleanThis, array('f', 't')); break; case "varchar": @@ -777,67 +771,6 @@ return($retval); }//end array_as_option_list() //########################################################################## - - - - //########################################################################## - public function interpret_bool($interpretThis, array $trueFalseMapper=null) { - $interpretThis = preg_replace('/ /', '', $interpretThis); - if(is_array($trueFalseMapper)) { - if(count($trueFalseMapper) == 2 && isset($trueFalseMapper[0]) && isset($trueFalseMapper[1])) { - $realVals = $trueFalseMapper; - } - else { - throw new exception(__METHOD__ .": invalid true/false map"); - } - } - else { - //set an array that defines what "0" and "1" return. - $realVals = array( - 0 => false, - 1 => true - ); - } - - //now figure out the value to return. - if(is_numeric($interpretThis)) { - settype($interpretThis, 'integer'); - if($interpretThis == '0') { - $index=0; - } - else { - $index=1; - } - } - elseif(is_bool($interpretThis)) { - if($interpretThis == true) { - $index=1; - } - else { - $index=0; - } - } - elseif(preg_match('/^true$/i', $interpretThis) || preg_match('/^false$/', $interpretThis) || preg_match("/^[tf]$/", $interpretThis)) { - if(preg_match('/^true$/i', $interpretThis) || preg_match('/^t$/', $interpretThis)) { - $index=1; - } - else { - $index=0; - } - } - else { - //straight-up PHP if/else evaluation. - if($interpretThis) { - $index=1; - } - else { - $index=0; - } - } - - return($realVals[$index]); - }//end interpret_bool() - //########################################################################## }//end cs_globalFunctions{} Deleted: trunk/0.10/cs_siteConfig.class.php =================================================================== --- trunk/0.10/cs_siteConfig.class.php 2009-01-26 01:29:21 UTC (rev 324) +++ trunk/0.10/cs_siteConfig.class.php 2009-01-26 01:33:48 UTC (rev 325) @@ -1,307 +0,0 @@ -<?php - -/* - * A class for handling configuration of database-driven web applications. - * - * NOTICE::: this class requires that cs-phpxml and cs-arraytopath are both available - * at the same directory level as cs-content; all projects are SourceForge.net projects, - * using their unix names ("cs-phpxml" and "cs-arrayToPath"). The cs-phpxml project - * requires cs-arrayToPath for parsing XML paths. - * - * SVN INFORMATION::: - * SVN Signature:::::::: $Id$ - * Last Committted Date: $Date$ - * Last Committed Path:: $HeadURL$ - * - */ - -require_once(dirname(__FILE__) .'/cs_globalFunctions.php'); -require_once(dirname(__FILE__) .'/cs_fileSystemClass.php'); -require_once(dirname(__FILE__). '/../cs-phpxml/cs_phpxmlParser.class.php'); -require_once(dirname(__FILE__) .'/../cs-phpxml/cs_phpxmlBuilder.class.php'); - -class cs_siteConfig { - - /** XMLParser{} object, for reading XML config file. */ - private $xmlReader; - - /** cs_fileSystemClass{} object, for writing/updating XML config file - * (only available if file is writable) - */ - private $xmlWriter; - - /** XMLBuilder{} object, for updating XML. */ - private $xmlBuilder; - - /** cs_fileSystemClass{} object, for handling generic file operations (i.e. reading) */ - private $fs; - - /** boolean flag indicating if the given config file is readOnly (false=read/write) */ - private $readOnly; - - /** Directory for the config file. */ - private $configDirname; - - /** Active section of the full site configuration. */ - private $activeSection; - - /** The FULL configuration file, instead of just the active section. */ - private $fullConfig=array(); - - /** cs_arrayToPath{} object. */ - private $a2p; - - /** Prefix to add to every index in GLOBALS and CONSTANTS. */ - private $setVarPrefix; - - /** Sections available within the config */ - private $configSections=array(); - - /** Boolean flag to determine if the object has been properly initialized or not. */ - private $isInitialized=false; - - - //------------------------------------------------------------------------- - /** - * Constructor. - * - * @param $configFileLocation (str) URI for config file. - * @param $section (str,optional) set active section (default=MAIN) - * @param $setVarPrefix (str,optional) prefix to add to all global & constant names. - * - * @return NULL (PASS) object successfully created - * @return exception (FAIL) failed to create object (see exception message) - */ - public function __construct($configFileLocation, $section='MAIN', $setVarPrefix=null) { - - $section = strtoupper($section); - $this->setVarPrefix=$setVarPrefix; - - $this->gf = new cs_globalFunctions; - $this->gf->debugPrintOpt=1; - - if(strlen($configFileLocation) && file_exists($configFileLocation)) { - - $this->configDirname = dirname($configFileLocation); - $this->fs = new cs_fileSystemClass($this->configDirname); - - $this->xmlReader = new cs_phpxmlParser($this->fs->read($configFileLocation)); - - if($this->fs->is_writable($configFileLocation)) { - $this->readOnly = false; - $this->xmlWriter = new cs_fileSystemClass($this->configDirname); - - } - else { - $this->readOnly = true; - } - } - else { - throw new exception(__METHOD__ .": invalid configuration file (". $configFileLocation .")"); - } - - if(strlen($section)) { - try { - $this->parse_config(); - $this->set_active_section($section); - $this->config = $this->get_section($section); - } - catch(exception $e) { - throw new exception(__METHOD__ .": invalid section (". $section ."), DETAILS::: ". $e->getMessage()); - } - } - else { - throw new exception(__METHOD__ .": no section given (". $section .")"); - } - - }//end __construct() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - /** - * Sets the active section. - * - * @param $section (str) section to be set as active. - * - * @return VOID (PASS) section was set successfully. - * @return exception (FAIL) problem encountred setting section. - */ - public function set_active_section($section) { - if($this->isInitialized === true) { - $section = strtoupper($section); - if(in_array($section, $this->configSections)) { - $this->activeSection = $section; - } - else { - throw new exception(__METHOD__ .": invalid section (". $section .")"); - } - } - else { - throw new exception(__METHOD__ .": not initialized"); - } - }//end set_active_section($section) - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - /** - * Parse the configuration file. Handles replacing {VARIABLES} in values, - * sets items as global or as constants, and creates array indicating the - * available sections from the config file. - * - * @param VOID (void) no arguments accepted. - * - * @return NULL (PASS) successfully parsed configuration - * @return exception (FAIL) exception indicates problem encountered. - */ - private function parse_config() { - if(is_object($this->xmlReader)) { - $data = $this->xmlReader->get_path($this->xmlReader->get_root_element()); - - $specialVars = array( - '_DIRNAMEOFFILE_' => $this->configDirname - ); - $parseThis = array(); - - - $this->configSections = array(); - - foreach($data as $section=>$secData) { - //only handle UPPERCASE index names; lowercase indexes are special entries (i.e. "type" or "attributes" - if($section == strtoupper($section)) { - $this->configSections[] = $section; - foreach($secData as $itemName=>$itemValue) { - $attribs = array(); - if(is_array($itemValue['attributes'])) { - $attribs = $itemValue['attributes']; - } - $itemValue = $itemValue['value']; - if(preg_match("/{/", $itemValue)) { - $origVal = $itemValue; - $itemValue = $this->gf->mini_parser($itemValue, $specialVars, '{', '}'); - $itemValue = $this->gf->mini_parser($itemValue, $parseThis, '{', '}'); - $itemValue = preg_replace("/[\/]{2,}/", "/", $itemValue); - } - - if($attribs['CLEANPATH']) { - $itemValue = $this->fs->resolve_path_with_dots($itemValue); - } - - $parseThis[$itemName] = $itemValue; - $parseThis[$section ."/". $itemName] = $itemValue; - $data[$section][$itemName]['value'] = $itemValue; - - $setVarIndex = $this->setVarPrefix . $itemName; - if($attribs['SETGLOBAL']) { - $GLOBALS[$setVarIndex] = $itemValue; - } - if($attribs['SETCONSTANT']) { - define($setVarIndex, $itemValue); - } - } - } - } - $this->a2p = new cs_arrayToPath($data); - $this->isInitialized=true; - } - else { - throw new exception(__METHOD__ .": xmlReader not created, object probably not initialized"); - } - }//end parse_config() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - /** - * Retrieve all data about the given section. - * - * @param $section (str) section to retrieve. - * - * @return array (PASS) array contains section data. - * @return exception (FAIL) exception indicates problem. - */ - public function get_section($section) { - if($this->isInitialized === true) { - $data = $this->a2p->get_data($section); - - if(is_array($data) && count($data) && $data['type'] == 'open') { - unset($data['type']); - $retval = $data; - } - else { - throw new exception(__METHOD__ .": invalid section or no data (". $data['type'] .")"); - } - } - else { - throw new exception(__METHOD__ .": not initialized"); - } - - return($retval); - }//end get_section() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - /** - * Retrieves value from the active section, or from another (other sections - * specified like "SECTION/INDEX"). - * - * @param $index (str) index name of value to retrieve. - * - * @return mixed (PASS) returns value of given index. - * - * NOTE::: this will return NULL if the given index or section/index does - * not exist. - */ - public function get_value($index) { - if($this->isInitialized === true) { - if(preg_match("/\//", $index)) { - //section NOT given, assume they're looking for something in the active section. - $index = $this->activeSection ."/". $index; - } - $retval = $this->a2p->get_data($index .'/value'); - } - else { - throw new exception(__METHOD__ .": not initialized"); - } - return($retval); - }//end get_value() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - /** - * Retrieves list of valid configuration sections, as defined by - * parse_config(). - * - * @param VOID (void) no parameters accepted. - * - * @return array (PASS) array holds list of valid sections. - * @return exception (FAIL) exception gives error. - */ - public function get_valid_sections() { - if($this->isInitialized === true) { - if(is_array($this->configSections) && count($this->configSections)) { - $retval = $this->configSections; - } - else { - throw new exception(__METHOD__ .": no sections defined, probably invalid configuration"); - } - } - else { - throw new exception(__METHOD__ .": not initialized"); - } - - return($retval); - }//end get_valid_sections() - //------------------------------------------------------------------------- - -}//end cs_siteConfig - -?> Modified: trunk/0.10/db_types/cs_phpDB__pgsql.class.php =================================================================== --- trunk/0.10/db_types/cs_phpDB__pgsql.class.php 2009-01-26 01:29:21 UTC (rev 324) +++ trunk/0.10/db_types/cs_phpDB__pgsql.class.php 2009-01-26 01:33:48 UTC (rev 325) @@ -136,7 +136,7 @@ $requiredCount = 0; foreach($required as $index) { - if(isset($params[$index]) || $index == 'password') { + if(isset($params[$index])) { $this->$index = $params[$index]; $requiredCount++; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-26 01:29:25
|
Revision: 324 http://cs-content.svn.sourceforge.net/cs-content/?rev=324&view=rev Author: crazedsanity Date: 2009-01-26 01:29:21 +0000 (Mon, 26 Jan 2009) Log Message: ----------- Working on a full 1.0 release... (copied from /trunk/0.10) Added Paths: ----------- trunk/1.0/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-26 00:35:17
|
Revision: 323 http://cs-content.svn.sourceforge.net/cs-content/?rev=323&view=rev Author: crazedsanity Date: 2009-01-26 00:35:14 +0000 (Mon, 26 Jan 2009) Log Message: ----------- Fix includes to point to new phpxml libraries. /cs_siteConfig.class.php: * MAIN::: -- fix path to cs_phpxmlParser{} and cs_phpxmlBuilder{} Modified Paths: -------------- trunk/0.10/cs_siteConfig.class.php Modified: trunk/0.10/cs_siteConfig.class.php =================================================================== --- trunk/0.10/cs_siteConfig.class.php 2009-01-22 20:07:22 UTC (rev 322) +++ trunk/0.10/cs_siteConfig.class.php 2009-01-26 00:35:14 UTC (rev 323) @@ -17,8 +17,8 @@ require_once(dirname(__FILE__) .'/cs_globalFunctions.php'); require_once(dirname(__FILE__) .'/cs_fileSystemClass.php'); -require_once(dirname(__FILE__). '/../cs-phpxml/xmlParserClass.php'); -require_once(dirname(__FILE__) .'/../cs-phpxml/xmlBuilderClass.php'); +require_once(dirname(__FILE__). '/../cs-phpxml/cs_phpxmlParser.class.php'); +require_once(dirname(__FILE__) .'/../cs-phpxml/cs_phpxmlBuilder.class.php'); class cs_siteConfig { @@ -48,7 +48,7 @@ /** The FULL configuration file, instead of just the active section. */ private $fullConfig=array(); - /** arrayToPath{} object. */ + /** cs_arrayToPath{} object. */ private $a2p; /** Prefix to add to every index in GLOBALS and CONSTANTS. */ @@ -85,7 +85,7 @@ $this->configDirname = dirname($configFileLocation); $this->fs = new cs_fileSystemClass($this->configDirname); - $this->xmlReader = new XMLParser($this->fs->read($configFileLocation)); + $this->xmlReader = new cs_phpxmlParser($this->fs->read($configFileLocation)); if($this->fs->is_writable($configFileLocation)) { $this->readOnly = false; @@ -204,7 +204,7 @@ } } } - $this->a2p = new arrayToPath($data); + $this->a2p = new cs_arrayToPath($data); $this->isInitialized=true; } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-22 20:07:31
|
Revision: 322 http://cs-content.svn.sourceforge.net/cs-content/?rev=322&view=rev Author: crazedsanity Date: 2009-01-22 20:07:22 +0000 (Thu, 22 Jan 2009) Log Message: ----------- Don't throw an exception if the password field is blank. /db_types/cs_phpDB__pgsql.class.php: * set_db_info(): -- allow "password" to be blank (for trusted/local connections). Modified Paths: -------------- trunk/0.10/db_types/cs_phpDB__pgsql.class.php Modified: trunk/0.10/db_types/cs_phpDB__pgsql.class.php =================================================================== --- trunk/0.10/db_types/cs_phpDB__pgsql.class.php 2009-01-20 05:18:20 UTC (rev 321) +++ trunk/0.10/db_types/cs_phpDB__pgsql.class.php 2009-01-22 20:07:22 UTC (rev 322) @@ -136,7 +136,7 @@ $requiredCount = 0; foreach($required as $index) { - if(isset($params[$index])) { + if(isset($params[$index]) || $index == 'password') { $this->$index = $params[$index]; $requiredCount++; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-20 05:18:26
|
Revision: 321 http://cs-content.svn.sourceforge.net/cs-content/?rev=321&view=rev Author: crazedsanity Date: 2009-01-20 05:18:20 +0000 (Tue, 20 Jan 2009) Log Message: ----------- Minor requirement additions, better errors, and removed unneeded methods. /cs_siteConfig.class.php: * MAIN::: -- require cs_globalFunctions and cs_fileSystemClass. * parse_config(): -- throw an exception if xmlReader isn't an object; this is basically a check to make debugging easier. * create_site_config() [DELETED]: -- it is easier for a person to copy the sample configuration file than to attempt to create a generic one. /tests/testOfCSContent.php: * remove unneeded debug_print() statement. Modified Paths: -------------- trunk/0.10/cs_siteConfig.class.php trunk/0.10/tests/testOfCSContent.php Modified: trunk/0.10/cs_siteConfig.class.php =================================================================== --- trunk/0.10/cs_siteConfig.class.php 2009-01-19 19:27:21 UTC (rev 320) +++ trunk/0.10/cs_siteConfig.class.php 2009-01-20 05:18:20 UTC (rev 321) @@ -15,6 +15,8 @@ * */ +require_once(dirname(__FILE__) .'/cs_globalFunctions.php'); +require_once(dirname(__FILE__) .'/cs_fileSystemClass.php'); require_once(dirname(__FILE__). '/../cs-phpxml/xmlParserClass.php'); require_once(dirname(__FILE__) .'/../cs-phpxml/xmlBuilderClass.php'); @@ -156,47 +158,58 @@ * @return exception (FAIL) exception indicates problem encountered. */ private function parse_config() { - $data = $this->xmlReader->get_path($this->xmlReader->get_root_element()); - - $specialVars = array( - '_DIRNAMEOFFILE_' => $this->configDirname - ); - $parseThis = array(); - - - $this->configSections = array(); - - foreach($data as $section=>$secData) { - //only handle UPPERCASE index names; lowercase indexes are special entries (i.e. "type" or "attributes" - if($section == strtoupper($section)) { - $this->configSections[] = $section; - foreach($secData as $itemName=>$itemValue) { - $attribs = array(); - if(is_array($itemValue['attributes'])) { - $attribs = $itemValue['attributes']; + if(is_object($this->xmlReader)) { + $data = $this->xmlReader->get_path($this->xmlReader->get_root_element()); + + $specialVars = array( + '_DIRNAMEOFFILE_' => $this->configDirname + ); + $parseThis = array(); + + + $this->configSections = array(); + + foreach($data as $section=>$secData) { + //only handle UPPERCASE index names; lowercase indexes are special entries (i.e. "type" or "attributes" + if($section == strtoupper($section)) { + $this->configSections[] = $section; + foreach($secData as $itemName=>$itemValue) { + $attribs = array(); + if(is_array($itemValue['attributes'])) { + $attribs = $itemValue['attributes']; + } + $itemValue = $itemValue['value']; + if(preg_match("/{/", $itemValue)) { + $origVal = $itemValue; + $itemValue = $this->gf->mini_parser($itemValue, $specialVars, '{', '}'); + $itemValue = $this->gf->mini_parser($itemValue, $parseThis, '{', '}'); + $itemValue = preg_replace("/[\/]{2,}/", "/", $itemValue); + } + + if($attribs['CLEANPATH']) { + $itemValue = $this->fs->resolve_path_with_dots($itemValue); + } + + $parseThis[$itemName] = $itemValue; + $parseThis[$section ."/". $itemName] = $itemValue; + $data[$section][$itemName]['value'] = $itemValue; + + $setVarIndex = $this->setVarPrefix . $itemName; + if($attribs['SETGLOBAL']) { + $GLOBALS[$setVarIndex] = $itemValue; + } + if($attribs['SETCONSTANT']) { + define($setVarIndex, $itemValue); + } } - $itemValue = $itemValue['value']; - if(preg_match("/{/", $itemValue)) { - $origVal = $itemValue; - $itemValue = $this->gf->mini_parser($itemValue, $specialVars, '{', '}'); - $itemValue = $this->gf->mini_parser($itemValue, $parseThis, '{', '}'); - $itemValue = preg_replace("/[\/]{2,}/", "/", $itemValue); - } - $parseThis[$itemName] = $itemValue; - $parseThis[$section ."/". $itemName] = $itemValue; - $data[$section][$itemName]['value'] = $itemValue; - - if($attribs['SETGLOBAL']) { - $GLOBALS[$this->setVarPrefix . $itemName] = $itemValue; - } - if($attribs['SETCONSTANT']) { - define($this->setVarPrefix . $itemName, $itemValue); - } } } + $this->a2p = new arrayToPath($data); + $this->isInitialized=true; } - $this->a2p = new arrayToPath($data); - $this->isInitialized=true; + else { + throw new exception(__METHOD__ .": xmlReader not created, object probably not initialized"); + } }//end parse_config() //------------------------------------------------------------------------- @@ -289,13 +302,6 @@ }//end get_valid_sections() //------------------------------------------------------------------------- - - - //------------------------------------------------------------------------- - public function create_site_config() { - }//end create_site_config() - //------------------------------------------------------------------------- - }//end cs_siteConfig ?> Modified: trunk/0.10/tests/testOfCSContent.php =================================================================== --- trunk/0.10/tests/testOfCSContent.php 2009-01-19 19:27:21 UTC (rev 320) +++ trunk/0.10/tests/testOfCSContent.php 2009-01-20 05:18:20 UTC (rev 321) @@ -213,7 +213,6 @@ $setAsGlobals = array(); $setAsConstants = array(); foreach($sc->get_valid_sections() as $section) { - $this->gf->debug_print(__METHOD__ .": evaluating section (". $section .")"); $sectionData = $sc->get_section($section); foreach($sectionData as $name=>$value) { if(is_array($value['attributes'])) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-19 19:27:27
|
Revision: 320 http://cs-content.svn.sourceforge.net/cs-content/?rev=320&view=rev Author: crazedsanity Date: 2009-01-19 19:27:21 +0000 (Mon, 19 Jan 2009) Log Message: ----------- Everything checks to ensure the object has been initialized (isInitialized===true) Modified Paths: -------------- trunk/0.10/cs_siteConfig.class.php Modified: trunk/0.10/cs_siteConfig.class.php =================================================================== --- trunk/0.10/cs_siteConfig.class.php 2009-01-19 19:19:06 UTC (rev 319) +++ trunk/0.10/cs_siteConfig.class.php 2009-01-19 19:27:21 UTC (rev 320) @@ -55,7 +55,10 @@ /** Sections available within the config */ private $configSections=array(); + /** Boolean flag to determine if the object has been properly initialized or not. */ + private $isInitialized=false; + //------------------------------------------------------------------------- /** * Constructor. @@ -108,6 +111,7 @@ else { throw new exception(__METHOD__ .": no section given (". $section .")"); } + }//end __construct() //------------------------------------------------------------------------- @@ -123,12 +127,17 @@ * @return exception (FAIL) problem encountred setting section. */ public function set_active_section($section) { - $section = strtoupper($section); - if(in_array($section, $this->configSections)) { - $this->activeSection = $section; + if($this->isInitialized === true) { + $section = strtoupper($section); + if(in_array($section, $this->configSections)) { + $this->activeSection = $section; + } + else { + throw new exception(__METHOD__ .": invalid section (". $section .")"); + } } else { - throw new exception(__METHOD__ .": invalid section (". $section .")"); + throw new exception(__METHOD__ .": not initialized"); } }//end set_active_section($section) //------------------------------------------------------------------------- @@ -187,6 +196,7 @@ } } $this->a2p = new arrayToPath($data); + $this->isInitialized=true; }//end parse_config() //------------------------------------------------------------------------- @@ -202,14 +212,19 @@ * @return exception (FAIL) exception indicates problem. */ public function get_section($section) { - $data = $this->a2p->get_data($section); - - if(is_array($data) && count($data) && $data['type'] == 'open') { - unset($data['type']); - $retval = $data; + if($this->isInitialized === true) { + $data = $this->a2p->get_data($section); + + if(is_array($data) && count($data) && $data['type'] == 'open') { + unset($data['type']); + $retval = $data; + } + else { + throw new exception(__METHOD__ .": invalid section or no data (". $data['type'] .")"); + } } else { - throw new exception(__METHOD__ .": invalid section or no data (". $data['type'] .")"); + throw new exception(__METHOD__ .": not initialized"); } return($retval); @@ -231,11 +246,16 @@ * not exist. */ public function get_value($index) { - if(preg_match("/\//", $index)) { - //section NOT given, assume they're looking for something in the active section. - $index = $this->activeSection ."/". $index; + if($this->isInitialized === true) { + if(preg_match("/\//", $index)) { + //section NOT given, assume they're looking for something in the active section. + $index = $this->activeSection ."/". $index; + } + $retval = $this->a2p->get_data($index .'/value'); } - $retval = $this->a2p->get_data($index .'/value'); + else { + throw new exception(__METHOD__ .": not initialized"); + } return($retval); }//end get_value() //------------------------------------------------------------------------- @@ -253,17 +273,29 @@ * @return exception (FAIL) exception gives error. */ public function get_valid_sections() { - if(is_array($this->configSections) && count($this->configSections)) { - $retval = $this->configSections; + if($this->isInitialized === true) { + if(is_array($this->configSections) && count($this->configSections)) { + $retval = $this->configSections; + } + else { + throw new exception(__METHOD__ .": no sections defined, probably invalid configuration"); + } } else { - throw new exception(__METHOD__ .": no sections defined, probably invalid configuration"); + throw new exception(__METHOD__ .": not initialized"); } return($retval); }//end get_valid_sections() //------------------------------------------------------------------------- + + + //------------------------------------------------------------------------- + public function create_site_config() { + }//end create_site_config() + //------------------------------------------------------------------------- + }//end cs_siteConfig ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-19 19:19:13
|
Revision: 319 http://cs-content.svn.sourceforge.net/cs-content/?rev=319&view=rev Author: crazedsanity Date: 2009-01-19 19:19:06 +0000 (Mon, 19 Jan 2009) Log Message: ----------- Headers for internal vars & methods, minor logic changes. /cs_siteConfig.class.php: * __construct(): -- call set_active_section() after calling parse_config() * set_active_section(): -- upper-case the section name. -- throw exception if the given section isn't valid. * get_valid_sections(): -- check that configSections is a valid array with data; if it's not, throw an exception indicating as such. Modified Paths: -------------- trunk/0.10/cs_siteConfig.class.php Modified: trunk/0.10/cs_siteConfig.class.php =================================================================== --- trunk/0.10/cs_siteConfig.class.php 2009-01-19 18:33:34 UTC (rev 318) +++ trunk/0.10/cs_siteConfig.class.php 2009-01-19 19:19:06 UTC (rev 319) @@ -20,11 +20,24 @@ class cs_siteConfig { + /** XMLParser{} object, for reading XML config file. */ private $xmlReader; + + /** cs_fileSystemClass{} object, for writing/updating XML config file + * (only available if file is writable) + */ private $xmlWriter; + + /** XMLBuilder{} object, for updating XML. */ private $xmlBuilder; + + /** cs_fileSystemClass{} object, for handling generic file operations (i.e. reading) */ private $fs; + + /** boolean flag indicating if the given config file is readOnly (false=read/write) */ private $readOnly; + + /** Directory for the config file. */ private $configDirname; /** Active section of the full site configuration. */ @@ -47,7 +60,12 @@ /** * Constructor. * - * @$configFileLocation (str) URI for config file. + * @param $configFileLocation (str) URI for config file. + * @param $section (str,optional) set active section (default=MAIN) + * @param $setVarPrefix (str,optional) prefix to add to all global & constant names. + * + * @return NULL (PASS) object successfully created + * @return exception (FAIL) failed to create object (see exception message) */ public function __construct($configFileLocation, $section='MAIN', $setVarPrefix=null) { @@ -57,8 +75,6 @@ $this->gf = new cs_globalFunctions; $this->gf->debugPrintOpt=1; - $this->set_active_section($section); - if(strlen($configFileLocation) && file_exists($configFileLocation)) { $this->configDirname = dirname($configFileLocation); @@ -68,6 +84,8 @@ if($this->fs->is_writable($configFileLocation)) { $this->readOnly = false; + $this->xmlWriter = new cs_fileSystemClass($this->configDirname); + } else { $this->readOnly = true; @@ -80,6 +98,7 @@ if(strlen($section)) { try { $this->parse_config(); + $this->set_active_section($section); $this->config = $this->get_section($section); } catch(exception $e) { @@ -95,14 +114,38 @@ //------------------------------------------------------------------------- + /** + * Sets the active section. + * + * @param $section (str) section to be set as active. + * + * @return VOID (PASS) section was set successfully. + * @return exception (FAIL) problem encountred setting section. + */ public function set_active_section($section) { - $this->activeSection = strtoupper($section); + $section = strtoupper($section); + if(in_array($section, $this->configSections)) { + $this->activeSection = $section; + } + else { + throw new exception(__METHOD__ .": invalid section (". $section .")"); + } }//end set_active_section($section) //------------------------------------------------------------------------- //------------------------------------------------------------------------- + /** + * Parse the configuration file. Handles replacing {VARIABLES} in values, + * sets items as global or as constants, and creates array indicating the + * available sections from the config file. + * + * @param VOID (void) no arguments accepted. + * + * @return NULL (PASS) successfully parsed configuration + * @return exception (FAIL) exception indicates problem encountered. + */ private function parse_config() { $data = $this->xmlReader->get_path($this->xmlReader->get_root_element()); @@ -150,6 +193,14 @@ //------------------------------------------------------------------------- + /** + * Retrieve all data about the given section. + * + * @param $section (str) section to retrieve. + * + * @return array (PASS) array contains section data. + * @return exception (FAIL) exception indicates problem. + */ public function get_section($section) { $data = $this->a2p->get_data($section); @@ -168,6 +219,17 @@ //------------------------------------------------------------------------- + /** + * Retrieves value from the active section, or from another (other sections + * specified like "SECTION/INDEX"). + * + * @param $index (str) index name of value to retrieve. + * + * @return mixed (PASS) returns value of given index. + * + * NOTE::: this will return NULL if the given index or section/index does + * not exist. + */ public function get_value($index) { if(preg_match("/\//", $index)) { //section NOT given, assume they're looking for something in the active section. @@ -181,12 +243,27 @@ //------------------------------------------------------------------------- + /** + * Retrieves list of valid configuration sections, as defined by + * parse_config(). + * + * @param VOID (void) no parameters accepted. + * + * @return array (PASS) array holds list of valid sections. + * @return exception (FAIL) exception gives error. + */ public function get_valid_sections() { - return($this->configSections); + if(is_array($this->configSections) && count($this->configSections)) { + $retval = $this->configSections; + } + else { + throw new exception(__METHOD__ .": no sections defined, probably invalid configuration"); + } + + return($retval); }//end get_valid_sections() //------------------------------------------------------------------------- - }//end cs_siteConfig ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-19 18:33:40
|
Revision: 318 http://cs-content.svn.sourceforge.net/cs-content/?rev=318&view=rev Author: crazedsanity Date: 2009-01-19 18:33:34 +0000 (Mon, 19 Jan 2009) Log Message: ----------- Code for setting globals & constants along with associated tests. Modified Paths: -------------- trunk/0.10/cs_siteConfig.class.php trunk/0.10/tests/testOfCSContent.php Modified: trunk/0.10/cs_siteConfig.class.php =================================================================== --- trunk/0.10/cs_siteConfig.class.php 2009-01-19 17:38:36 UTC (rev 317) +++ trunk/0.10/cs_siteConfig.class.php 2009-01-19 18:33:34 UTC (rev 318) @@ -36,7 +36,13 @@ /** arrayToPath{} object. */ private $a2p; + /** Prefix to add to every index in GLOBALS and CONSTANTS. */ + private $setVarPrefix; + /** Sections available within the config */ + private $configSections=array(); + + //------------------------------------------------------------------------- /** * Constructor. @@ -45,7 +51,9 @@ */ public function __construct($configFileLocation, $section='MAIN', $setVarPrefix=null) { - //TODO: don't use cs_globalFunctions{} if unneeded. + $section = strtoupper($section); + $this->setVarPrefix=$setVarPrefix; + $this->gf = new cs_globalFunctions; $this->gf->debugPrintOpt=1; @@ -103,11 +111,18 @@ ); $parseThis = array(); + + $this->configSections = array(); + foreach($data as $section=>$secData) { //only handle UPPERCASE index names; lowercase indexes are special entries (i.e. "type" or "attributes" if($section == strtoupper($section)) { - $this->gf->debug_print(__METHOD__ .": handling (". $section .")"); + $this->configSections[] = $section; foreach($secData as $itemName=>$itemValue) { + $attribs = array(); + if(is_array($itemValue['attributes'])) { + $attribs = $itemValue['attributes']; + } $itemValue = $itemValue['value']; if(preg_match("/{/", $itemValue)) { $origVal = $itemValue; @@ -118,6 +133,13 @@ $parseThis[$itemName] = $itemValue; $parseThis[$section ."/". $itemName] = $itemValue; $data[$section][$itemName]['value'] = $itemValue; + + if($attribs['SETGLOBAL']) { + $GLOBALS[$this->setVarPrefix . $itemName] = $itemValue; + } + if($attribs['SETCONSTANT']) { + define($this->setVarPrefix . $itemName, $itemValue); + } } } } @@ -129,7 +151,6 @@ //------------------------------------------------------------------------- public function get_section($section) { - $this->gf->debug_print(__METHOD__ .": section=(". $section .")"); $data = $this->a2p->get_data($section); if(is_array($data) && count($data) && $data['type'] == 'open') { @@ -158,6 +179,14 @@ //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + public function get_valid_sections() { + return($this->configSections); + }//end get_valid_sections() + //------------------------------------------------------------------------- + + }//end cs_siteConfig ?> Modified: trunk/0.10/tests/testOfCSContent.php =================================================================== --- trunk/0.10/tests/testOfCSContent.php 2009-01-19 17:38:36 UTC (rev 317) +++ trunk/0.10/tests/testOfCSContent.php 2009-01-19 18:33:34 UTC (rev 318) @@ -21,6 +21,9 @@ function __construct() { require_once(dirname(__FILE__) .'/../cs_globalFunctions.php'); require_once(dirname(__FILE__) .'/../cs_siteConfig.class.php'); + + $this->gf = new cs_globalFunctions; + $this->gf->debugPrintOpt=1; }//end __construct() //------------------------------------------------------------------------- @@ -177,7 +180,8 @@ //------------------------------------------------------------------------- public function test_siteConfig() { $configFile = dirname(__FILE__) .'/files/sampleConfig.xml'; - $sc = new cs_siteConfig($configFile); + $varPrefix = preg_replace("/:/", "_", __METHOD__ ."-"); + $sc = new cs_siteConfig($configFile, 'main', $varPrefix); //make sure that specifying the section "main" section works just like NOT specifying it. $this->assertEqual($sc->get_value('SITEROOT'), $sc->get_value('MAIN/SITEROOT')); @@ -198,6 +202,45 @@ $sc->get_value('cs-content/tmpldir'), "path replacement for cs-content/tmpldir (". $sc->get_value('cs-content/tmpldir') .") didn't match main/tmpldir (". $sc->get_value('main/tmpldir') .")" ); + + //make sure all of the items that are supposed to be set as globals & constants actually were. + + //Do some testing of sections.... + $this->assertTrue(is_array($sc->get_valid_sections())); + $this->assertEqual($sc->get_valid_sections(), array('MAIN', 'CS-CONTENT')); + + //now let's make sure we got all of the proper globals & constants set.... first, get the list of things that should be globals/constants. + $setAsGlobals = array(); + $setAsConstants = array(); + foreach($sc->get_valid_sections() as $section) { + $this->gf->debug_print(__METHOD__ .": evaluating section (". $section .")"); + $sectionData = $sc->get_section($section); + foreach($sectionData as $name=>$value) { + if(is_array($value['attributes'])) { + if(isset($value['attributes']['SETGLOBAL'])) { + $setAsGlobals[$name] = $value['value']; + } + if(isset($value['attributes']['SETCONSTANT'])) { + $setAsConstants[$name] = $value['value']; + } + } + } + } + + foreach($setAsGlobals as $name=>$val) { + $index = $varPrefix . $name; + $this->assertNotEqual($name, $index); + $this->assertTrue(isset($GLOBALS[$index])); + $this->assertEqual($GLOBALS[$index], $val); + } + + foreach($setAsConstants as $name=>$val) { + $index = $varPrefix . $name; + $this->assertNotEqual($name, $index); + $this->assertTrue(defined($index)); + $this->assertEqual(constant($index), $val); + } + }//end test_siteConfig() //------------------------------------------------------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-19 17:38:47
|
Revision: 317 http://cs-content.svn.sourceforge.net/cs-content/?rev=317&view=rev Author: crazedsanity Date: 2009-01-19 17:38:36 +0000 (Mon, 19 Jan 2009) Log Message: ----------- New cs_siteConfig{} class with unit tests. Modified Paths: -------------- trunk/0.10/tests/testOfCSContent.php Added Paths: ----------- trunk/0.10/cs_siteConfig.class.php Copied: trunk/0.10/cs_siteConfig.class.php (from rev 315, trunk/0.10/cs_phpDB.php) =================================================================== --- trunk/0.10/cs_siteConfig.class.php (rev 0) +++ trunk/0.10/cs_siteConfig.class.php 2009-01-19 17:38:36 UTC (rev 317) @@ -0,0 +1,163 @@ +<?php + +/* + * A class for handling configuration of database-driven web applications. + * + * NOTICE::: this class requires that cs-phpxml and cs-arraytopath are both available + * at the same directory level as cs-content; all projects are SourceForge.net projects, + * using their unix names ("cs-phpxml" and "cs-arrayToPath"). The cs-phpxml project + * requires cs-arrayToPath for parsing XML paths. + * + * SVN INFORMATION::: + * SVN Signature:::::::: $Id$ + * Last Committted Date: $Date$ + * Last Committed Path:: $HeadURL$ + * + */ + +require_once(dirname(__FILE__). '/../cs-phpxml/xmlParserClass.php'); +require_once(dirname(__FILE__) .'/../cs-phpxml/xmlBuilderClass.php'); + +class cs_siteConfig { + + private $xmlReader; + private $xmlWriter; + private $xmlBuilder; + private $fs; + private $readOnly; + private $configDirname; + + /** Active section of the full site configuration. */ + private $activeSection; + + /** The FULL configuration file, instead of just the active section. */ + private $fullConfig=array(); + + /** arrayToPath{} object. */ + private $a2p; + + + //------------------------------------------------------------------------- + /** + * Constructor. + * + * @$configFileLocation (str) URI for config file. + */ + public function __construct($configFileLocation, $section='MAIN', $setVarPrefix=null) { + + //TODO: don't use cs_globalFunctions{} if unneeded. + $this->gf = new cs_globalFunctions; + $this->gf->debugPrintOpt=1; + + $this->set_active_section($section); + + if(strlen($configFileLocation) && file_exists($configFileLocation)) { + + $this->configDirname = dirname($configFileLocation); + $this->fs = new cs_fileSystemClass($this->configDirname); + + $this->xmlReader = new XMLParser($this->fs->read($configFileLocation)); + + if($this->fs->is_writable($configFileLocation)) { + $this->readOnly = false; + } + else { + $this->readOnly = true; + } + } + else { + throw new exception(__METHOD__ .": invalid configuration file (". $configFileLocation .")"); + } + + if(strlen($section)) { + try { + $this->parse_config(); + $this->config = $this->get_section($section); + } + catch(exception $e) { + throw new exception(__METHOD__ .": invalid section (". $section ."), DETAILS::: ". $e->getMessage()); + } + } + else { + throw new exception(__METHOD__ .": no section given (". $section .")"); + } + }//end __construct() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function set_active_section($section) { + $this->activeSection = strtoupper($section); + }//end set_active_section($section) + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + private function parse_config() { + $data = $this->xmlReader->get_path($this->xmlReader->get_root_element()); + + $specialVars = array( + '_DIRNAMEOFFILE_' => $this->configDirname + ); + $parseThis = array(); + + foreach($data as $section=>$secData) { + //only handle UPPERCASE index names; lowercase indexes are special entries (i.e. "type" or "attributes" + if($section == strtoupper($section)) { + $this->gf->debug_print(__METHOD__ .": handling (". $section .")"); + foreach($secData as $itemName=>$itemValue) { + $itemValue = $itemValue['value']; + if(preg_match("/{/", $itemValue)) { + $origVal = $itemValue; + $itemValue = $this->gf->mini_parser($itemValue, $specialVars, '{', '}'); + $itemValue = $this->gf->mini_parser($itemValue, $parseThis, '{', '}'); + $itemValue = preg_replace("/[\/]{2,}/", "/", $itemValue); + } + $parseThis[$itemName] = $itemValue; + $parseThis[$section ."/". $itemName] = $itemValue; + $data[$section][$itemName]['value'] = $itemValue; + } + } + } + $this->a2p = new arrayToPath($data); + }//end parse_config() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function get_section($section) { + $this->gf->debug_print(__METHOD__ .": section=(". $section .")"); + $data = $this->a2p->get_data($section); + + if(is_array($data) && count($data) && $data['type'] == 'open') { + unset($data['type']); + $retval = $data; + } + else { + throw new exception(__METHOD__ .": invalid section or no data (". $data['type'] .")"); + } + + return($retval); + }//end get_section() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function get_value($index) { + if(preg_match("/\//", $index)) { + //section NOT given, assume they're looking for something in the active section. + $index = $this->activeSection ."/". $index; + } + $retval = $this->a2p->get_data($index .'/value'); + return($retval); + }//end get_value() + //------------------------------------------------------------------------- + + +}//end cs_siteConfig + +?> Property changes on: trunk/0.10/cs_siteConfig.class.php ___________________________________________________________________ Added: svn:eol + native Added: svn:keywords + Id HeadURL Date Revision Author Added: svn:mergeinfo + Added: svn:eol-style + native Modified: trunk/0.10/tests/testOfCSContent.php =================================================================== --- trunk/0.10/tests/testOfCSContent.php 2009-01-19 16:43:10 UTC (rev 316) +++ trunk/0.10/tests/testOfCSContent.php 2009-01-19 17:38:36 UTC (rev 317) @@ -14,15 +14,13 @@ - - - //============================================================================= class TestOfCSContent extends UnitTestCase { //------------------------------------------------------------------------- function __construct() { require_once(dirname(__FILE__) .'/../cs_globalFunctions.php'); + require_once(dirname(__FILE__) .'/../cs_siteConfig.class.php'); }//end __construct() //------------------------------------------------------------------------- @@ -176,6 +174,35 @@ + //------------------------------------------------------------------------- + public function test_siteConfig() { + $configFile = dirname(__FILE__) .'/files/sampleConfig.xml'; + $sc = new cs_siteConfig($configFile); + + //make sure that specifying the section "main" section works just like NOT specifying it. + $this->assertEqual($sc->get_value('SITEROOT'), $sc->get_value('MAIN/SITEROOT')); + $this->assertEqual($sc->get_value('SITEROOT'), $sc->get_value('siteroot')); + $this->assertEqual($sc->get_value('SITEROOT'), $sc->get_value('siteRoot')); + + //make sure if we request an index that doesn't exist, it is returned as null + $this->assertTrue(is_null($sc->get_value('NONExISTENT___'))); + + //make sure some values have been replaced. + $this->assertTrue(!preg_match("/{/", $sc->get_value('libdir'))); + $this->assertTrue( + preg_match("/^". preg_replace("/\//", "\/", $sc->get_value('siteroot')) ."/", $sc->get_value('libdir')), + "LIBDIR (". $sc->get_value('libdir') .") doesn't contain SITEROOT (". $sc->get_value('siteroot') .")" + ); + $this->assertEqual( + $sc->get_value('main/tmpldir'), + $sc->get_value('cs-content/tmpldir'), + "path replacement for cs-content/tmpldir (". $sc->get_value('cs-content/tmpldir') .") didn't match main/tmpldir (". $sc->get_value('main/tmpldir') .")" + ); + }//end test_siteConfig() + //------------------------------------------------------------------------- + + + }//end TestOfCSContent //============================================================================= ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-19 16:43:15
|
Revision: 316 http://cs-content.svn.sourceforge.net/cs-content/?rev=316&view=rev Author: crazedsanity Date: 2009-01-19 16:43:10 +0000 (Mon, 19 Jan 2009) Log Message: ----------- Fix broken require statement in the example_test.php file, add a sampleConfig XML file (in new subfolder). Modified Paths: -------------- trunk/0.10/tests/example_test.php Added Paths: ----------- trunk/0.10/tests/files/ trunk/0.10/tests/files/sampleConfig.xml Modified: trunk/0.10/tests/example_test.php =================================================================== --- trunk/0.10/tests/example_test.php 2009-01-14 03:12:57 UTC (rev 315) +++ trunk/0.10/tests/example_test.php 2009-01-19 16:43:10 UTC (rev 316) @@ -11,12 +11,6 @@ * $LastChangedRevision$ */ -if (! defined('SIMPLE_TEST')) { - define('SIMPLE_TEST', 'simpletest/'); -} -require_once(SIMPLE_TEST . 'unit_tester.php'); -require_once(SIMPLE_TEST . 'reporter.php'); - require_once(dirname(__FILE__) .'/testOfCSContent.php'); Added: trunk/0.10/tests/files/sampleConfig.xml =================================================================== --- trunk/0.10/tests/files/sampleConfig.xml (rev 0) +++ trunk/0.10/tests/files/sampleConfig.xml 2009-01-19 16:43:10 UTC (rev 316) @@ -0,0 +1,22 @@ +<config> + <main> + <debugprintopt setconstant="1" setglobal="1">0</debugprintopt> + <siteroot setconstant="1" setglobal="1">{_DIRNAMEOFFILE_}</siteroot> + <pg_host setglobal="1">crazedsanity.com</pg_host> + <pg_dbname setglobal="1">cs</pg_dbname> + <pg_port setglobal="1">5432</pg_port> + <pg_dbuser setglobal="1">postgres</pg_dbuser> + <max_idle setglobal="1">8 hours</max_idle> + <max_time setglobal="1">24 hours</max_time> + <workingonit setconstant="1" setglobal="1">0</workingonit> + <libdir>{SITEROOT}/lib</libdir> + <tmpldir>{SITEROOT}/templates</tmpldir> + <cs_blogrwdir>{SITEROOT}/rw/blogger</cs_blogrwdir> + <cs_blogimgurl>/images/blog/</cs_blogimgurl> + <cs_blogimgdir>{SITEROOT}/public_html/{CS_BLOGIMGURL}</cs_blogimgdir> + </main> + + <cs-content> + <tmpldir>{MAIN/TMPLDIR}</tmpldir> + </cs-content> +</config> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-14 03:13:07
|
Revision: 315 http://cs-content.svn.sourceforge.net/cs-content/?rev=315&view=rev Author: crazedsanity Date: 2009-01-14 03:12:57 +0000 (Wed, 14 Jan 2009) Log Message: ----------- Add a few things to ensure unit tests work. Modified Paths: -------------- trunk/0.10/tests/example_test.php Modified: trunk/0.10/tests/example_test.php =================================================================== --- trunk/0.10/tests/example_test.php 2009-01-14 03:04:15 UTC (rev 314) +++ trunk/0.10/tests/example_test.php 2009-01-14 03:12:57 UTC (rev 315) @@ -11,6 +11,12 @@ * $LastChangedRevision$ */ +if (! defined('SIMPLE_TEST')) { + define('SIMPLE_TEST', 'simpletest/'); +} +require_once(SIMPLE_TEST . 'unit_tester.php'); +require_once(SIMPLE_TEST . 'reporter.php'); + require_once(dirname(__FILE__) .'/testOfCSContent.php'); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-14 03:04:26
|
Revision: 314 http://cs-content.svn.sourceforge.net/cs-content/?rev=314&view=rev Author: crazedsanity Date: 2009-01-14 03:04:15 +0000 (Wed, 14 Jan 2009) Log Message: ----------- Unit tests (using Simple Test). Added Paths: ----------- trunk/0.10/tests/ trunk/0.10/tests/example_test.php trunk/0.10/tests/testOfCSContent.php Added: trunk/0.10/tests/example_test.php =================================================================== --- trunk/0.10/tests/example_test.php (rev 0) +++ trunk/0.10/tests/example_test.php 2009-01-14 03:04:15 UTC (rev 314) @@ -0,0 +1,20 @@ +<?php +/* + * Created on Jan 13, 2009 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +require_once(dirname(__FILE__) .'/testOfCSContent.php'); + + +$test = &new TestOfCSContent(); +$test->run(new HtmlReporter()); + +?> Property changes on: trunk/0.10/tests/example_test.php ___________________________________________________________________ Added: svn:keywords + HeadURL Id LastChangedBy LastChangedDate LastChangedRevision Added: trunk/0.10/tests/testOfCSContent.php =================================================================== --- trunk/0.10/tests/testOfCSContent.php (rev 0) +++ trunk/0.10/tests/testOfCSContent.php 2009-01-14 03:04:15 UTC (rev 314) @@ -0,0 +1,181 @@ +<?php +/* + * Created on Jan 13, 2009 + * + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + + + + + + +//============================================================================= +class TestOfCSContent extends UnitTestCase { + + //------------------------------------------------------------------------- + function __construct() { + require_once(dirname(__FILE__) .'/../cs_globalFunctions.php'); + }//end __construct() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function test_cleanString() { + + $gf = new cs_globalFunctions(); + + $cleanThis = '~`!@#$^&*()_+-=[]\{}|;34:\\\'\<>?,.//\".JuST THIS'; + $testSQL = array( + 'none' => $cleanThis, + 'query' => '@_=;34:/JuST THIS', + 'theDefault' => '34JuSTTHIS', + 'alphanumeric' => '34JuSTTHIS', + 'sql' => '~`!@#$^&*()_+-=[]{}|;34:\\\'<>?,.//\".JuST THIS', + 'sql_insert' => '~`!@#$^&*()_+-=[]{}|;34:\\\\\'<>?,.//".JuST THIS', + 'sql92_insert' => '~`!@#$^&*()_+-=[]{}|;34:\'\'<>?,.//".JuST THIS', + 'double_quote' => '~`!@#$^&*()_+-=[]\{}|;34:\\\'\<>?,.//\.JuST THIS', + 'htmlspecial' => '~`!@#$^&*()_+-=[]\{}|;34:\\\'\<>?,.//\".JuST THIS', + 'htmlspecial_q' => '~`!@#$^&*()_+-=[]\{}|;34:\\'\<>?,.//\".JuST THIS', + 'htmlspecial_nq' => '~`!@#$^&*()_+-=[]\{}|;34:\\\'\<>?,.//\".JuST THIS', + 'htmlentity' => '~`!@#$^&*()_+-=[]\{}|;34:\\\'\<>?,.//\".JuST THIS', + 'htmlentity_plus_brackets' => '~`!@#$^&*()_+-=[]\{}|;34:\\\'\<>?,.//\".JuST THIS', + 'double_entity' => '~`!@#$^&*()_+-=[]\{}|;34:\\\'\<>?,.//\.JuST THIS', + 'meta' => '~`!@#\$\^&\*\(\)_\+-=\[\]\\\\{}|;34:\\\\\'\\\<>\?,\.//\\\\"\.JuST THIS', + 'email' => '@_-34..JuSTTHIS', + 'email_plus_spaces' => '@_-34..JuST THIS', + 'phone_fax' => '()+-34 ', + 'integer' => '34', + 'numeric' => '34', + 'decimal' => '34..', + 'float' => '34..', + 'name' => '\'JuSTTHIS', + 'names' => '\'JuSTTHIS', + 'alpha' => 'JuSTTHIS', + 'bool' => 't', + 'varchar' => '\'@_=;34:/JuST THIS\'', + 'date' => '-34', + 'datetime' => '-34:\'.//.JuST THIS', + 'all' => '34JuSTTHIS' + ); + + foreach($testSQL as $name=>$expected) { + $cleanedData = $gf->cleanString($cleanThis, $name); + + //NOTE::: passing "%" in the message data causes an exception with the simpletest framework. + $this->assertEqual($expected, $cleanedData); + } + + + //test quoting (with a few exceptions). + $testQuotes = $testSQL; + unset($testQuotes['none'], $testQuotes['sql92_insert']); + foreach($testQuotes as $name=>$expected) { + $gf->switch_force_sql_quotes(1); + $cleanedDataPlusQuotes = $gf->cleanString($cleanThis, $name, 1); + $this->assertEqual("'". $expected ."'", $cleanedDataPlusQuotes, "Failed quoting with style=(". $name .")"); + + $gf->switch_force_sql_quotes(0); + $this->assertEqual("'". $expected ."'", $cleanedDataPlusQuotes, "Failed quoting with style=(". $name .")"); + } + + + //TEST NULLS + { + + $this->assertEqual($gf->cleanString("", "numeric",0), ""); + $this->assertEqual($gf->cleanString("", "numeric",1), "''"); + $this->assertEqual($gf->cleanString("", "integer",0), ""); + $this->assertEqual($gf->cleanString("", "integer",1), "''"); + $this->assertEqual($gf->cleanString(null, "numeric",0), "NULL"); + $this->assertEqual($gf->cleanString(null, "numeric",1), "NULL"); + $this->assertEqual($gf->cleanString(null, "integer",0), "NULL"); + $this->assertEqual($gf->cleanString(null, "integer",1), "NULL"); + + $this->assertEqual($gf->cleanString(null, "varchar",0), "NULL"); + $this->assertEqual($gf->cleanString(null, "varchar",1), "'NULL'"); + $this->assertEqual($gf->cleanString("", "varchar",0), "NULL"); + $this->assertEqual($gf->cleanString("", "varchar",1), "'NULL'"); + } + + }//end test_cleanString() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + function test_string_from_array() { + $gf = new cs_globalFunctions; + $gf->switch_force_sql_quotes(0); + + //Test some SQL-Specific stuff. + $testSQL = array( + 'column1' => "'my value ' OR 'x'='x'", + 'column two' => "Stuff" + ); + + //Test INSERT style. + { + $expected = "(column1, column two) VALUES ('my value ' OR 'x'='x','Stuff')"; + $this->assertEqual($gf->string_from_array($testSQL, 'insert'), $expected); + + $expected = "(column1, column two) VALUES ('\'my value \' OR \'x\'=\'x\'','Stuff')"; + $this->assertEqual($gf->string_from_array($testSQL, 'insert', null, 'sql'), $expected); + + $expected = "(column1, column two) VALUES ('\'my value \' OR \'x\'=\'x\'','Stuff')"; + $this->assertEqual($gf->string_from_array($testSQL, 'insert', null, 'sql_insert'), $expected); + + $expected = "(column1, column two) VALUES ('\'my value \' OR \'x\'=\'x\'','Stuff')"; + $this->assertEqual($gf->string_from_array($testSQL, 'insert', null, 'sql92_insert'), $expected); + + //now let's see what happens if we pass an array signifying how it should be cleaned. + $expected = "(column1, column two) VALUES ('\'my value \' OR \'x\'=\'x\'','Stuff')"; + $this->assertEqual($gf->string_from_array($testSQL, 'insert', null, array('column1'=>'sql', 'column two'=>'sql')), $expected); + $expected = "(column1, column two) VALUES ('\\\\\'my value \\\\\' OR \\\\\'x\\\\\'=\\\\\'x\\\\\'','Stuff')"; + $this->assertEqual($gf->string_from_array($testSQL, 'insert', null, array('column1'=>'sql_insert', 'column two'=>'sql_insert')), $expected); + $expected = "(column1, column two) VALUES ('\'\'my value \'\' OR \'\'x\'\'=\'\'x\'\'','Stuff')"; + $this->assertEqual($gf->string_from_array($testSQL, 'insert', null, array('column1'=>'sql92_insert', 'column two'=>'sql92_insert')), $expected); + + } + + }//end test_string_from_array() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + function test_interpret_bool() { + $gf=new cs_globalFunctions; + + $this->assertEqual($gf->interpret_bool('true'), true); + $this->assertEqual($gf->interpret_bool('false'), false); + $this->assertEqual($gf->interpret_bool('0'), false); + $this->assertEqual($gf->interpret_bool('1'), true); + $this->assertEqual($gf->interpret_bool(0), false); + $this->assertEqual($gf->interpret_bool(1), true); + $this->assertEqual($gf->interpret_bool('f'), false); + $this->assertEqual($gf->interpret_bool('t'), true); + $this->assertEqual($gf->interpret_bool("1stuff"), true); + $this->assertEqual($gf->interpret_bool(""), false); + $this->assertEqual($gf->interpret_bool(" true "), true); + $this->assertEqual($gf->interpret_bool(" false "), false); + + //now go through the same thing, but this time tell it to give back a specific value for true and false. + $this->assertEqual($gf->interpret_bool(false, array(0=>'FaLSe',1=>"crap")), 'FaLSe'); + $this->assertEqual($gf->interpret_bool(false, array(0=>"crap",1=>'FaLSe')), 'crap'); + }//end test_interpret_bool() + //------------------------------------------------------------------------- + + + +}//end TestOfCSContent +//============================================================================= +?> Property changes on: trunk/0.10/tests/testOfCSContent.php ___________________________________________________________________ Added: svn:keywords + HeadURL Id LastChangedBy LastChangedDate LastChangedRevision This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-14 02:43:53
|
Revision: 313 http://cs-content.svn.sourceforge.net/cs-content/?rev=313&view=rev Author: crazedsanity Date: 2009-01-14 02:43:38 +0000 (Wed, 14 Jan 2009) Log Message: ----------- Fix cleanString() and some minor tweaks & comment updates. /cs_globalFunctions.php: * switch_force_sql_quotes(): -- remove some debug_print statements -- fix ending comment so it indicates the actual name of the method * cleanString(): -- fixed "query" case so it strips single quotes. -- fixed comment in "name/names" case -- fixed "bool/boolean" case to use internal interpret_bool() method * interpret_bool() [NEW]: -- interprets data as boolean, and can specify return values for true or false -- NOTE: this has always been required for the "bool/boolean" cleaning style from cleanString(), but no tests were performed to ensure that it actually worked (until now, though they're not included yet). Modified Paths: -------------- trunk/0.10/cs_globalFunctions.php Modified: trunk/0.10/cs_globalFunctions.php =================================================================== --- trunk/0.10/cs_globalFunctions.php 2009-01-08 18:48:49 UTC (rev 312) +++ trunk/0.10/cs_globalFunctions.php 2009-01-14 02:43:38 UTC (rev 313) @@ -62,15 +62,13 @@ $this->oldForceSqlQuotes = $this->forceSqlQuotes; $this->forceSqlQuotes = $newSetting; $retval = true; - $this->debug_print(__METHOD__ .": swapped (OLD=". $this->oldForceSqlQuotes .", CUR=". $this->forceSqlQuotes .")"); } else { $retval = false; - $this->debug_print(__METHOD__ .": no swap (OLD=". $this->oldForceSqlQuotes .", CUR=". $this->forceSqlQuotes .")"); } return($retval); - }//end force_sql_quotes() + }//end switch_force_sql_quotes() //========================================================================= @@ -382,6 +380,7 @@ */ $evilChars = array("\$", "%", "~", "*",">", "<", "-", "{", "}", "[", "]", ")", "(", "&", "#", "?", ".", "\,","\/","\\","\"","\|","!","^","+","`","\n","\r"); $cleanThis = preg_replace("/\|/","",$cleanThis); + $cleanThis = preg_replace("/\'/", "", $cleanThis); $cleanThis = str_replace($evilChars,"", $cleanThis); $cleanThis = stripslashes(addslashes($cleanThis)); break; @@ -520,7 +519,7 @@ case "name": case "names": - //removes everything in the "alpha" case, but allows "'". + //allows only things in the "alpha" case and single quotes. $cleanThis = preg_replace("/[^a-zA-Z']/", "", $cleanThis); break; @@ -532,7 +531,7 @@ case "bool": case "boolean": //makes it either T or F (gotta lower the string & only check the first char to ensure accurate results). - $cleanThis = interpret_bool($cleanThis, array('f', 't')); + $cleanThis = $this->interpret_bool($cleanThis, array('f', 't')); break; case "varchar": @@ -778,6 +777,67 @@ return($retval); }//end array_as_option_list() //########################################################################## + + + + //########################################################################## + public function interpret_bool($interpretThis, array $trueFalseMapper=null) { + $interpretThis = preg_replace('/ /', '', $interpretThis); + if(is_array($trueFalseMapper)) { + if(count($trueFalseMapper) == 2 && isset($trueFalseMapper[0]) && isset($trueFalseMapper[1])) { + $realVals = $trueFalseMapper; + } + else { + throw new exception(__METHOD__ .": invalid true/false map"); + } + } + else { + //set an array that defines what "0" and "1" return. + $realVals = array( + 0 => false, + 1 => true + ); + } + + //now figure out the value to return. + if(is_numeric($interpretThis)) { + settype($interpretThis, 'integer'); + if($interpretThis == '0') { + $index=0; + } + else { + $index=1; + } + } + elseif(is_bool($interpretThis)) { + if($interpretThis == true) { + $index=1; + } + else { + $index=0; + } + } + elseif(preg_match('/^true$/i', $interpretThis) || preg_match('/^false$/', $interpretThis) || preg_match("/^[tf]$/", $interpretThis)) { + if(preg_match('/^true$/i', $interpretThis) || preg_match('/^t$/', $interpretThis)) { + $index=1; + } + else { + $index=0; + } + } + else { + //straight-up PHP if/else evaluation. + if($interpretThis) { + $index=1; + } + else { + $index=0; + } + } + + return($realVals[$index]); + }//end interpret_bool() + //########################################################################## }//end cs_globalFunctions{} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-01-08 18:48:54
|
Revision: 312 http://cs-content.svn.sourceforge.net/cs-content/?rev=312&view=rev Author: crazedsanity Date: 2009-01-08 18:48:49 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Set debugPrintOpt to value of constant DEBUGPRINTOPT before trying GLOBALS. /cs_globalFunctions.php: * __construct(): -- check constants DEBUGPRINTOPT and DEBUGREMOVEHR prior to checking GLOBALS; set to that value if available. -- NOTE: DEBUGPRINTOPT is set but DEBUGREMOVEHR isn't, then debugRemoveHr will use the value in GLOBALS (if present); the inverse is also true. This might cause some consistency issues in certain situations... Modified Paths: -------------- trunk/0.10/cs_globalFunctions.php Modified: trunk/0.10/cs_globalFunctions.php =================================================================== --- trunk/0.10/cs_globalFunctions.php 2009-01-08 05:28:35 UTC (rev 311) +++ trunk/0.10/cs_globalFunctions.php 2009-01-08 18:48:49 UTC (rev 312) @@ -17,10 +17,17 @@ public function __construct() { //These checks have been implemented for pseudo backwards-compatibility // (internal vars won't change if GLOBAL vars changed). - if(isset($GLOBALS['DEBUGREMOVEHR'])) { + if(defined('DEBUGREMOVEHR')) { + $this->debugRemoveHr = constant('DEBUGREMOVEHR'); + } + elseif(isset($GLOBALS['DEBUGREMOVEHR'])) { $this->debugRemoveHr = $GLOBALS['DEBUGREMOVEHR']; } - if(isset($GLOBALS['DEBUGPRINTOPT'])) { + + if(defined('DEBUGPRINTOPT')) { + $this->debugPrintOpt = constant('DEBUGPRINTOPT'); + } + elseif(isset($GLOBALS['DEBUGPRINTOPT'])) { $this->debugPrintOpt = $GLOBALS['DEBUGPRINTOPT']; } $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |