Thread: [Cs-webapplibs-commits] SF.net SVN: cs-webapplibs:[103] trunk/0.3
Status: Beta
Brought to you by:
crazedsanity
From: <cra...@us...> - 2009-08-19 15:27:47
|
Revision: 103 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=103&view=rev Author: crazedsanity Date: 2009-08-19 15:27:38 +0000 (Wed, 19 Aug 2009) Log Message: ----------- Import of cs-versionparse. Added Paths: ----------- trunk/0.3/CREDITS trunk/0.3/LICENSE trunk/0.3/VERSION trunk/0.3/cs_version.abstract.class.php Copied: trunk/0.3/CREDITS (from rev 101, import/cs-versionparse/trunk/0.1/CREDITS) =================================================================== --- trunk/0.3/CREDITS (rev 0) +++ trunk/0.3/CREDITS 2009-08-19 15:27:38 UTC (rev 103) @@ -0,0 +1,3 @@ + +Lead Developer: Dan Falconer (cra...@us...) + Copied: trunk/0.3/LICENSE (from rev 101, import/cs-versionparse/trunk/0.1/LICENSE) =================================================================== --- trunk/0.3/LICENSE (rev 0) +++ trunk/0.3/LICENSE 2009-08-19 15:27:38 UTC (rev 103) @@ -0,0 +1,291 @@ +NOTE: a full HTML version of this license can be found at: +http://www.opensource.org/licenses/gpl-license.php + +It has been reproduced below without any HTML. +========================================================================== + +The GNU General Public License (GPL) + +Version 2, June 1991 + + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS Copied: trunk/0.3/VERSION (from rev 101, import/cs-versionparse/trunk/0.1/VERSION) =================================================================== --- trunk/0.3/VERSION (rev 0) +++ trunk/0.3/VERSION 2009-08-19 15:27:38 UTC (rev 103) @@ -0,0 +1,6 @@ +## Stores the current version of the cs-versionparse system, and it's source. +## Please do NOT modify this file. + +VERSION: 0.3.0 +PROJECT: cs-webapplibs +$HeadURL$ \ No newline at end of file Copied: trunk/0.3/cs_version.abstract.class.php (from rev 101, import/cs-versionparse/trunk/0.1/cs_version.abstract.class.php) =================================================================== --- trunk/0.3/cs_version.abstract.class.php (rev 0) +++ trunk/0.3/cs_version.abstract.class.php 2009-08-19 15:27:38 UTC (rev 103) @@ -0,0 +1,398 @@ +<?php +/* + * Created on January 01, 2009 by Dan Falconer + * + * SVN INFORMATION::: + * ------------------- + * Last Author::::::::: $Author$ + * Current Revision:::: $Revision$ + * Repository Location: $HeadURL$ + * Last Updated:::::::: $Date$ + */ + +abstract class cs_versionAbstract { + + public $isTest = FALSE; + + + + private $versionFileLocation=null; + private $fullVersionString; + private $suffixList = array( + 'ALPHA', //very unstable + 'BETA', //kinda unstable, but probably useable + 'RC' //all known bugs fixed, searching for unknown ones + ); + + + + abstract public function __construct(); + + + + //========================================================================= + /** + * Retrieve our version string from the VERSION file. + */ + final public function get_version($asArray=false) { + $retval = NULL; + + $this->auto_set_version_file(); + + if(file_exists($this->versionFileLocation)) { + $myMatches = array(); + $findIt = preg_match('/VERSION: (.+)/', file_get_contents($this->versionFileLocation), $matches); + + if($findIt == 1 && count($matches) == 2) { + $fullVersionString = $matches[1]; + $versionInfo = $this->parse_version_string($fullVersionString); + $this->fullVersionString = $this->build_full_version_string($versionInfo); + + + if($asArray) { + $retval = $versionInfo; + $retval['version_string'] = $this->fullVersionString; + } + else { + $retval = $this->build_full_version_string($versionInfo); + } + } + else { + throw new exception(__METHOD__ .": failed to retrieve version string in file " . + "(". $this->versionFileLocation .")"); + } + } + else { + throw new exception(__METHOD__ .": failed to retrieve version information, file " . + "(". $this->versionFileLocation .") does not exist or was not set"); + } + + return($retval); + }//end get_version() + //========================================================================= + + + + //========================================================================= + public function __get($var) { + return($this->$var); + }//end __get() + //========================================================================= + + + + //========================================================================= + final public function get_project() { + $retval = NULL; + $this->auto_set_version_file(); + if(file_exists($this->versionFileLocation)) { + $myMatches = array(); + $findIt = preg_match('/PROJECT: (.+)/', file_get_contents($this->versionFileLocation), $matches); + + if($findIt == 1 && count($matches) == 2 && strlen($matches[1])) { + $retval = $matches[1]; + } + else { + throw new exception(__METHOD__ .": failed to retrieve project string"); + } + } + else { + throw new exception(__METHOD__ .": failed to retrieve project information"); + } + + return($retval); + }//end get_project() + //========================================================================= + + + + //========================================================================= + public function set_version_file_location($location) { + if(file_exists($location)) { + $this->versionFileLocation = $location; + } + else { + throw new exception(__METHOD__ .": invalid location of VERSION file (". $location .")"); + } + }//end set_version_file_location() + //========================================================================= + + + + //========================================================================= + protected function auto_set_version_file() { + if(!strlen($this->versionFileLocation)) { + $bt = debug_backtrace(); + foreach($bt as $callNum=>$data) { + if(strlen($data['class'])) { + if($data['class'] != __CLASS__) { + $dir = dirname($data['file']); + if(preg_match('/tests$/', $dir)) { + $dir = preg_replace('/\/tests$/', '', $dir); + } + elseif(preg_match('/test$/', $dir)) { + $dir = preg_replace('/\/test$/', '', $dir); + } + break; + } + } + else { + throw new exception(__METHOD__ .": failed to locate the calling class in backtrace"); + } + } + + if(file_exists($dir .'/VERSION')) { + $this->set_version_file_location($dir .'/VERSION'); + } + else { + throw new exception(__METHOD__ .": failed to automatically set version file (tried ". $dir ."/VERSION)"); + } + } + }//end auto_set_version_file() + //========================================================================= + + + + //========================================================================= + /** + * + * TODO: add logic to split apart the suffix (i.e. "-ALPHA5" broken into "ALPHA" and "5"). + */ + public function parse_version_string($version) { + if(is_string($version) && strlen($version) && preg_match('/\./', $version)) { + $version = preg_replace('/ /', '', $version); + + $pieces = explode('.', $version); + $retval = array( + 'version_major' => $pieces[0], + 'version_minor' => $pieces[1] + ); + if(isset($pieces[2]) && strlen($pieces[2])) { + $retval['version_maintenance'] = $pieces[2]; + } + else { + $retval['version_maintenance'] = 0; + } + + if(preg_match('/-/', $retval['version_maintenance'])) { + $bits = explode('-', $retval['version_maintenance']); + $retval['version_maintenance'] = $bits[0]; + $suffix = $bits[1]; + } + elseif(preg_match('/-/', $retval['version_minor'])) { + $bits = explode('-', $retval['version_minor']); + $retval['version_minor'] = $bits[0]; + $suffix = $bits[1]; + } + else { + $suffix = ""; + } + $retval['version_suffix'] = $suffix; + } + else { + throw new exception(__METHOD__ .": invalid version string passed (". $version .")"); + } + + return($retval); + }//end parse_version_string() + //========================================================================= + + + + //========================================================================= + public function build_full_version_string(array $versionInfo) { + $requiredIndexes = array( + 'version_major', 'version_minor', 'version_maintenance', 'version_suffix' + ); + + $missing=""; + $count=0; + foreach($requiredIndexes as $indexName) { + if(isset($versionInfo[$indexName])) { + $count++; + } + else { + if(strlen($missing)) { + $missing .= ", ". $indexName; + } + else { + $missing = $indexName; + } + } + } + + if($count == count($requiredIndexes) && !strlen($missing)) { + $suffix = $versionInfo['version_suffix']; + unset($versionInfo['version_suffix']); + + $retval = ""; + foreach($versionInfo as $name=>$value) { + if(strlen($retval)) { + $retval .= ".". $value; + } + else { + $retval = $value; + } + } + if(strlen($suffix)) { + $retval .= "-". $suffix; + } + } + else { + throw new exception(__METHOD__ .": missing indexes in given array (". $missing .")"); + } + + return($retval); + + }//end build_full_version_string() + //========================================================================= + + + + //========================================================================= + public function is_higher_version($version, $checkIfHigher) { + $retval = FALSE; + $this->gfObj = new cs_globalFunctions; + if(!is_string($version) || !is_string($checkIfHigher)) { + throw new exception(__METHOD__ .": no valid version strings, version=(". $version ."), checkIfHigher=(". $checkIfHigher .")"); + } + elseif($version == $checkIfHigher) { + $retval = FALSE; + } + else { + $curVersionArr = $this->parse_version_string($version); + $checkVersionArr = $this->parse_version_string($checkIfHigher); + + unset($curVersionArr['version_string'], $checkVersionArr['version_string']); + + + $curVersionSuffix = $curVersionArr['version_suffix']; + $checkVersionSuffix = $checkVersionArr['version_suffix']; + + + unset($curVersionArr['version_suffix']); + + foreach($curVersionArr as $index=>$versionNumber) { + $checkThis = $checkVersionArr[$index]; + + if(is_numeric($checkThis) && is_numeric($versionNumber)) { + //set them as integers. + settype($versionNumber, 'int'); + settype($checkThis, 'int'); + + if($checkThis > $versionNumber) { + $retval = TRUE; + break; + } + elseif($checkThis == $versionNumber) { + //they're equal... + } + else { + //TODO: should there maybe be an option to throw an exception (freak out) here? + } + } + else { + throw new exception(__METHOD__ .": ". $index ." is not numeric in one of the strings " . + "(versionNumber=". $versionNumber .", checkThis=". $checkThis .")"); + } + } + + //now deal with those damnable suffixes, but only if the versions are so far identical: if + // the "$checkIfHigher" is actually higher, don't bother (i.e. suffixes don't matter when + // we already know there's a major, minor, or maintenance version that's also higher. + if($retval === FALSE) { + //EXAMPLE: $version="1.0.0-BETA3", $checkIfHigher="1.1.0" + // Moving from a non-suffixed version to a suffixed version isn't supported, but the inverse is: + // i.e. (1.0.0-BETA3 to 1.0.0) is okay, but (1.0.0 to 1.0.0-BETA3) is NOT. + // Also: (1.0.0-BETA3 to 1.0.0-BETA4) is okay, but (1.0.0-BETA4 to 1.0.0-BETA3) is NOT. + if(strlen($curVersionSuffix) && strlen($checkVersionSuffix) && $curVersionSuffix == $checkVersionSuffix) { + //matching suffixes. + } + elseif(strlen($curVersionSuffix) || strlen($checkVersionSuffix)) { + //we know the suffixes are there and DO match. + if(strlen($curVersionSuffix) && strlen($checkVersionSuffix)) { + //okay, here's where we do some crazy things... + $curVersionData = $this->parse_suffix($curVersionSuffix); + $checkVersionData = $this->parse_suffix($checkVersionSuffix); + + if($curVersionData['type'] == $checkVersionData['type']) { + //got the same suffix type (like "BETA"), check the number. + if($checkVersionData['number'] > $curVersionData['number']) { + //new version's suffix number higher than current... + $retval = TRUE; + } + elseif($checkVersionData['number'] == $curVersionData['number']) { + //new version's suffix number is EQUAL TO current... + $retval = FALSE; + } + else { + //new version's suffix number is LESS THAN current... + $retval = FALSE; + } + } + else { + //not the same suffix... see if the new one is higher. + $suffixValues = array_flip($this->suffixList); + if($suffixValues[$checkVersionData['type']] > $suffixValues[$curVersionData['type']]) { + $retval = TRUE; + } + else { + //current suffix type is higher... + } + } + + } + elseif(strlen($curVersionSuffix) && !strlen($checkVersionSuffix)) { + //i.e. "1.0.0-BETA1" to "1.0.0" --->>> OKAY! + $retval = TRUE; + } + elseif(!strlen($curVersionSuffix) && strlen($checkVersionSuffix)) { + //i.e. "1.0.0" to "1.0.0-BETA1" --->>> NOT ACCEPTABLE! + } + } + else { + //no suffix to care about + } + } + } + + return($retval); + + }//end is_higher_version() + //========================================================================= + + + + //========================================================================= + protected function parse_suffix($suffix) { + $retval = NULL; + if(strlen($suffix)) { + //determine what kind it is. + foreach($this->suffixList as $type) { + if(preg_match('/^'. $type .'/', $suffix)) { + $checkThis = preg_replace('/^'. $type .'/', '', $suffix); + if(strlen($checkThis) && is_numeric($checkThis)) { + //oooh... it's something like "BETA3" + $retval = array( + 'type' => $type, + 'number' => $checkThis + ); + } + else { + throw new exception(__METHOD__ .": invalid suffix (". $suffix .")"); + } + break; + } + } + } + else { + throw new exception(__METHOD__ .": invalid suffix (". $suffix .")"); + } + + return($retval); + }//end parse_suffix() + //========================================================================= + + +} +?> \ 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-08-19 15:28:47
|
Revision: 104 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=104&view=rev Author: crazedsanity Date: 2009-08-19 15:28:38 +0000 (Wed, 19 Aug 2009) Log Message: ----------- Copied folders from cs-webdblogger... Added Paths: ----------- trunk/0.3/README.txt trunk/0.3/cs_webdblogger.class.php trunk/0.3/setup/ trunk/0.3/upgrades/ Copied: trunk/0.3/README.txt (from rev 101, import/cs-webdblogger/trunk/0.2/README.txt) =================================================================== --- trunk/0.3/README.txt (rev 0) +++ trunk/0.3/README.txt 2009-08-19 15:28:38 UTC (rev 104) @@ -0,0 +1,29 @@ + +Once the appropriate schema has been built, code can be updated easily to start logging: + +//Create the class... +$this->log = new cs_webdblogger($dbObj, 'Generic Activity'); + +//Now call the logger. +$this->log->log_by_class('User viewed page', 'info', $this->userId); + + + +UNDERSTANDING THE DATABASE SCHEMA::: +I understand things best from real data, so here goes:::: + +live_cs_project=# select rca.name as category, rcl.name as class, le.description from log_event_table AS le INNER JOIN log_class_table AS rcl USING (log_class_id) INNER JOIN log_category_table AS rca USING (log_category_id) limit 5; + category | class | description +----------+--------+-------------------------- + Project | Create | Project: created record + Project | Delete | Project: deleted record + Project | Update | Project: updated record + Project | Error | Project: ERROR + Helpdesk | Create | Helpdesk: Created record +(5 rows) + +The category indicates what system it is attached to, and class is a more +generic way of indicating what type of action it is. + + +$Id$ \ No newline at end of file Copied: trunk/0.3/cs_webdblogger.class.php (from rev 101, import/cs-webdblogger/trunk/0.2/cs_webdblogger.class.php) =================================================================== --- trunk/0.3/cs_webdblogger.class.php (rev 0) +++ trunk/0.3/cs_webdblogger.class.php 2009-08-19 15:28:38 UTC (rev 104) @@ -0,0 +1,864 @@ +<?php +/* + * Created on Mar 8, 2007 + * + * NOTICE::: this class was derived from the logsClass.php found in cs-projet v1.2, found + * at URL: https://cs-project.svn.sourceforge.net/svnroot/cs-project/trunk/1.2/lib/logsClass.php + * Last SVN Signature (from cs-project v1.2): "logsClass.php 819 2008-02-09 10:01:10Z crazedsanity" + * + * SVN INFORMATION::: + * ------------------ + * SVN Signature::::::: $Id$ + * Last Author::::::::: $Author$ + * Current Revision:::: $Revision$ + * Repository Location: $HeadURL$ + * Last Updated:::::::: $Date$ + * + * + * Each class that's trying to log should have an internal var statically set to indicates what category + * it is: this allows them to call a method within this and tell it ONLY what "class" the log should be + * under, so this class can determine the appropriate log_event_id. This avoids having to hard-code + * too many id's that might need to be changed later. Yay, dynamic code! + * + * QUERY TO GET LAST COUPLE OF LOGS:::: + SELECT l.log_id as id, l.creation, l.event_id as lid, le.description AS event, l.details + FROM cswdbl_log_table AS l INNER JOIN cswdbl_event_table AS le USING (event_id) ORDER BY log_id DESC LIMIT 25; + */ + +//NOTE::: this class **REQUIRES** cs-content for its "cs_phpDB" class. + +require_once(constant('LIBDIR') .'/cs-versionparse/cs_version.abstract.class.php'); + +class cs_webdblogger extends cs_versionAbstract { + /** Database handle */ + public $db; + + /** Cache of all records in the class table */ + private $logClassCache = array(); + + /** Cache of all records in the attribute table */ + private $attributeCache=array(); + + /** The category_id value to use, set on class creation. */ + private $logCategoryId = null; + + /** Default uid (users.id) to log under when no uid is available */ + private $defaultUid = 0; + + /** Category to use when logging a database error */ + //TODO: make SURE this category is correct... + private $databaseCategory = 1; + + /** Check to see if setup has been performed (avoids running it multiple times) **/ + private $setupComplete=false; + + /** Last SQL file handled */ + protected $lastSQLFile=null; + + /** Global functions class from cs-content */ + protected $gfObj; + + protected $pendingLogs; + private $suspendLogging=false; + + /** List of tables keyed off an internal reference name. */ + protected $tables = array( + 'category' => 'cswdbl_category_table', + 'class' => 'cswdbl_class_table', + 'event' => 'cswdbl_event_table', + 'log' => 'cswdbl_log_table', + 'attrib' => 'cswdbl_attribute_table', + 'logAttrib' => 'cswdbl_log_attribute_table' + ); + + /** List of sequences keyed off an internal reference name (MUST match references above) */ + protected $seqs = array( + 'category' => "cswdbl_category_table_category_id_seq", + 'class' => "cswdbl_class_table_class_id_seq", + 'event' => "cswdbl_event_table_event_id_seq", + 'log' => "cswdbl_log_table_log_id_seq", + 'attrib' => "cswdbl_attribute_table_attribute_id_seq", + 'logAttrib' => "cswdbl_log_attribute_table_log_attribute_id_seq" + ); + + //========================================================================= + /** + * The constructor. + */ + public function __construct(cs_phpDB &$db, $logCategory=null, $checkForUpgrades=true) { + //assign the database object. + $this->db = $db; + + $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); + + //Make sure the version of cs_phpDB is HIGHER THAN (not equal to) 1.0.0-ALPHA8, + // which added some methods that are required. + $mustBeHigherThan = '1.2-ALPHA8'; + if(!$this->is_higher_version($mustBeHigherThan, $this->db->get_version())) { + throw new exception(__METHOD__ .": requires cs_phpDB of higher than v". $mustBeHigherThan,1); + } + + $this->gfObj = new cs_globalFunctions; + + //see if there's an upgrade to perform... + if($checkForUpgrades === true) { + $this->suspendLogging = true; + $upgObj = new cs_webdbupgrade(dirname(__FILE__) . '/VERSION', dirname(__FILE__) .'/upgrades/upgrade.xml'); + $upgObj->check_versions(true); + $this->suspendLogging = false; + $this->handle_suspended_logs(); + } + + //assign the category_id. + if(strlen($logCategory)) { + if(!is_numeric($logCategory)) { + //attempt to retreive the logCategoryId (assuming they passed a name) + $this->logCategoryId = $this->get_category_id($logCategory); + } + else { + //it was numeric: set it! + $this->logCategoryId = $logCategory; + } + } + + //check for a uid in the session. + $this->defaultUid = $this->get_uid(); + + + //build our cache. + $this->build_cache(); + }//end __construct() + //========================================================================= + + + + //========================================================================= + /** + * Execute the entire contents of the given file (with absolute path) as SQL. + */ + final public function run_sql_file($filename) { + if(!is_object($this->fsObj)) { + if(class_exists('cs_fileSystem')) { + $fsObj = new cs_fileSystem; + } + else { + throw new exception(__METHOD__ .": required library (cs_fileSystem) not found"); + } + } + + $this->lastSQLFile = $filename; + + $fileContents = $fsObj->read($filename); + try { + $this->db->run_update($fileContents, true); + $this->build_cache(); + $retval = TRUE; + } + catch(exception $e) { + $retval = FALSE; + } + + return($retval); + }//end run_sql_file() + //========================================================================= + + + + //========================================================================= + /** + * Build internal cache to avoid extra queries. + */ + private function build_cache() { + //build query, run it, check for errors. + $sql = "SELECT class_id, lower(class_name) as name FROM ". $this->tables['class']; + + try { + $data = $this->db->run_query($sql, 'name', 'class_id'); + + if(is_array($data)) { + $this->logClassCache = $data; + } + elseif($data == false) { + $this->logClassCache = array(); + } + else { + throw new exception(__METHOD__ .": unknown data returned: ". $this->gfObj->debug_var_dump($data,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to build internal class cache::: ". $e->getMessage()); + } + + //now build cache for attributes. + $sql = "SELECT attribute_id, lower(attribute_name) AS attribute_name FROM ". $this->tables['attrib']; + + try { + $data = $this->db->run_query($sql, 'attribute_name', 'attribute_id'); + + if(is_array($data)) { + $this->attributeCache = $data; + } + elseif($data == false) { + $this->attributeCache = array(); + } + else { + throw new exception(__METHOD__ .": unknown data returned: ". $this->gfObj->debug_var_dump($data,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": error occurred while retrieving attribute cache::: ". $e->getMessage()); + } + }//end build_cache() + //========================================================================= + + + + //========================================================================= + /** + * Retrieve log_class_id value from the given name, or insert a new one. + */ + private function get_class_id($name) { + $name = strtolower($name); + + //get the id. + if(isset($this->logClassCache[$name])) { + //set the id. + $retval = $this->logClassCache[$name]; + } + else { + //create the class & then rebuild cache. + $retval = $this->create_class($name); + $this->build_cache(); + } + + return($retval); + }//end get_class_id() + //========================================================================= + + + + //========================================================================= + /** + * Retrieve log_event_id based on the given class name & the internal + * logCategoryId value. + */ + function get_event_id($logClassName) { + $sqlArr = array( + 'class_id' => $this->get_class_id($logClassName), + 'category_id' => $this->logCategoryId + ); + $sql = "SELECT event_id FROM ". $this->tables['event'] ." WHERE " . + $this->gfObj->string_from_array($sqlArr, 'select', NULL, 'numeric'); + + try { + $data = $this->db->run_query($sql); + + + if($data === false) { + //no records & no error: create one. + $retval = $this->auto_insert_record($sqlArr['class_id']); + } + elseif(is_array($data) && isset($data['event_id'])) { + $retval = $data['event_id']; + } + else { + throw new exception(__METHOD__ .": invalid data returned::: ". $this->gfObj->debug_var_dump($data,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to retrieve event_id::: ". $e->getMessage()); + } + + return($retval); + }//end get_event_id() + //========================================================================= + + + + //========================================================================= + /** + * The primary means of building log entries: use log_dberror() to log an + * error with a bit more capabilities; throws the details of the error as + * an exception. + */ + public function log_by_class($details, $className="error", $uid=NULL, array $logAttribs=NULL) { + + if($this->suspendLogging === true) { + $this->pendingLogs[] = func_get_args(); + $retval = count($this->pendingLogs) -1; + } + else { + if(count($this->pendingLogs)) { + $this->handle_suspended_logs(); + } + + //make sure there's a valid class name. + if(!strlen($className) || is_null($className)) { + $className = 'error'; + } + + //make sure we've got a uid to log under. + if(is_null($uid) || !is_numeric($uid)) { + //set it. + $uid = $this->defaultUid; + } + + //determine the log_event_id. + try { + $logEventId = $this->get_event_id($className); + } + catch(Exception $e) { + throw new exception(__METHOD__ .": while attempting to retrieve logEventId, encountered an " . + "exception:::\n". $e->getMessage() ."\n\nCLASS: $className\nDETAILS: $details"); + } + + //check to see what uid to use. + $myUid = $this->get_uid(); + + //okay, setup an array of all the data we need. + $cleanStringArr = array( + 'event_id' => 'numeric', + 'uid' => 'numeric', + 'affected_uid' => 'numeric', + 'details' => 'sql' + ); + $sqlArr = array ( + 'event_id' => $this->gfObj->cleanString($logEventId, 'numeric'), + 'uid' => $myUid, + 'affected_uid' => $uid, + 'details' => $details + ); + + //build, run, error-checking. + $sql = "INSERT INTO ". $this->tables['log'] ." ". $this->gfObj->string_from_array($sqlArr, 'insert', NULL, $cleanStringArr, TRUE); + + try { + $newId = $this->db->run_insert($sql, $this->seqs['log']); + + if(is_numeric($newId) && $newId > 0) { + $retval = $newId; + + if(is_array($logAttribs) && count($logAttribs)) { + $this->create_log_attributes($newId, $logAttribs); + } + } + else { + throw new exception(__METHOD__ .": failed to insert id or invalid return (". $this->gfObj->debug_var_dump($newId,0) .")"); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": error while creating log::: ". $e->getMessage()); + } + } + + return($retval); + }//end log_by_class() + //========================================================================= + + + + //========================================================================= + /** + * Logs an error like log_by_class(), but also throws an exception. + */ + public function log_dberror($details, $uid=NULL, $skipCurrentCatLog=FALSE) { + //set the error for the current category. + if(!$skipCurrentCatLog && ($this->logCategoryId !== $this->databaseCategory)) { + //yep, log it! + $this->log_by_class($details, 'error', $uid); + } + + //now log the database error. + $originalCategoryId = $this->logCategoryId; + $this->logCategoryId = $this->databaseCategory; + $retval = $this->log_by_class($details, 'error', $uid); + $this->logCategoryId = $originalCategoryId; + + throw new exception(__METHOD__ .": encountered error::: $details"); + }//end log_dberror() + //========================================================================= + + + + //========================================================================= + /** + * Attempts to auto-recover if a class was requested that doesn't exist. + */ + private function auto_insert_record($logClassId) { + //generate a default name + + $className = $this->get_class_name($logClassId); + $categoryName = $this->get_category_name($this->logCategoryId); + + $details = ucwords($categoryName) .": ". ucwords($className); + + if(strlen($details) <= 4) { + //something bad happened (i.e. details="0: 0") + throw new exception(__METHOD__ .": failed to recover with class_id=(". $logClassId .") " . + "AND category_id=(". $this->logCategoryId ."), details=(". $details .")"); + } + else { + //create the sql array. + $sqlArr = array ( + 'class_id' => $logClassId, + 'category_id' => $this->logCategoryId, + 'description' => "'". $this->gfObj->cleanString($details, 'sql') ."'" + ); + + //now run the insert. + $sql = 'INSERT INTO '. $this->tables['event'] .' '. $this->gfObj->string_from_array($sqlArr, 'insert'); + + try { + $newId = $this->db->run_insert($sql, $this->seqs['event']); + + if(is_numeric($newId) && $newId > 0) { + $retval = $newId; + } + else { + throw new exception(__METHOD__ .": unable to insert id or bad return::: ". $this->gfObj->debug_var_dump($newId,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to create record::: ". $e->getMessage()); + } + } + + return($retval); + }//end auto_insert_record() + //========================================================================= + + + + //========================================================================= + /** + * Retrieves logs with the given criteria. + */ + public function get_logs(array $criteria, array $orderBy=NULL, $limit=20) { + //set a default for the limit. + if(!is_numeric($limit) || $limit < 1) { + //set it again. + $limit = 20; + } + + if(is_null($orderBy) || count($orderBy) < 1) { + //set it. + $orderBy = array( + 'log_id DESC' + ); + } + + //set the fields that can be used, along with what alias for the table & cleaning type to use on the data. + $allowedCritFields = array( + 'class_id' => array('cl', 'numeric'), + 'category_id' => array('ca', 'numeric'), + 'uid' => array('l', 'numeric'), + 'affected_uid' => array('l', 'numeric'), + 'creation' => array('l', 'sql') + ); + + //loop through the data to create our cleaned, prefixed array of criteria. + $sqlArr = array(); + foreach($criteria AS $field => $value) { + //is this field in the allowed list? + if(isset($allowedCritFields[$field])) { + //grab data for this field. + $myFieldData = $allowedCritFields[$field]; + $cleanStringArg = $myFieldData[1]; + + //clean the data. + if($field == 'creation' && is_numeric($value)) { + $value = $this->gfObj->cleanString($value, 'numeric'); + $cleanedData = ">= (NOW() - interval '". $value ." hours')"; + } + else { + $cleanedData = $this->gfObj->cleanString($value, $cleanStringArg); + } + + //set the prefixed column name. + $prefixedName = $myFieldData[0] .'.'. $field; + + //now add it to our array. + $sqlArr[$prefixedName] = $cleanedData; + } + } + + + //build the criteria. + $sqlArr['ca.category_id'] = '>0'; + $critString = $this->gfObj->string_from_array($sqlArr, 'select'); + + //check if "timeperiod" is in there (it's special) + if(isset($criteria['timeperiod']) && isset($criteria['timeperiod']['start']) && isset($criteria['timeperiod']['end'])) { + //add it in! + $myTime = $criteria['timeperiod']; + $addThis = "(l.creation >= '". $myTime['start'] ."'::date AND l.creation <= '". $myTime['end'] ."'::date + interval '1 day')"; + $critString = create_list($critString, $addThis, ' AND '); + } + + $orderString = $this->gfObj->string_from_array($orderBy, 'limit'); + $sql = "select " . + "l.creation, " . + "l.log_id, " . + "l.uid, " . + "cl.class_name, " . + "ca.category_name, " . + "ev.description, " . + "l.details " . + "FROM ". $this->tables['log'] ." AS l " . + "INNER JOIN ". $this->tables['event'] ." AS ev ON (l.event_id=ev.event_id) " . + "INNER JOIN ". $this->tables['class'] ." AS cl ON (cl.class_id=ev.class_id) " . + "INNER JOIN ". $this->tables['category'] ." AS ca ON (ca.category_id=ev.category_id) " . + "WHERE " . $critString . " " . + "ORDER BY " . + "log_id DESC " . + "LIMIT ". $limit; + + try { + //run it. + $data = $this->db->run_query($sql, 'log_id'); + + $retval = array(); + if(is_array($data)) { + $retval = $data; + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to retrieve logs::: ". $e->getMessage()); + } + + return($retval); + }//end get_logs() + //========================================================================= + + + + //========================================================================= + /** + * Uses arbitrary criteria to retrieve the last X log entries. + */ + public function get_recent_logs($numEntries=null) { + if(!is_numeric($numEntries) || $numEntries < 1) { + $numEntries = 20; + } + + //set the criteria so we only get the last few entries. + $retval = $this->get_logs(array(), NULL, $numEntries); + return($retval); + }//end get_recent_logs() + //========================================================================= + + + + //========================================================================= + /** + * Retrieve category_id from the given name. + */ + private function get_category_id($catName) { + if(strlen($catName) && is_string($catName)) { + $catName = trim($catName); + $sql = "SELECT category_id FROM ". $this->tables['category'] ." WHERE lower(category_name) = '". strtolower($catName) ."'"; + + try { + + $data = $this->db->run_query($sql); + + $numrows = $this->db->numRows(); + if($numrows == 1 && is_array($data) && isset($data['category_id']) && is_numeric($data['category_id'])) { + $retval = $data['category_id']; + } + elseif($data === false) { + $retval = $this->create_log_category($catName); + } + elseif($numrows > 1) { + throw new exception(__METHOD__ .": found too many records (". $numrows .")"); + } + else { + throw new exception(__METHOD__ .": unknown error (bad data in array?)"); + } + } + catch(exception $e) { + if($this->setupComplete === true) { + throw new exception(__METHOD__ .": encountered error::: ". $e->getMessage()); + } + else { + $mySchemaFile = dirname(__FILE__) .'/setup/schema.'. $this->db->get_dbtype() .'.sql'; + if(file_exists($mySchemaFile)) { + $this->setupComplete = true; + $this->run_sql_file($mySchemaFile); + + //Create the default category. + $this->create_log_category('Database'); + + $retval = $this->create_log_category($catName); + } + else { + throw new exception(__METHOD__ .": missing schema file (". $mySchemaFile ."), can't run setup"); + } + } + } + } + else { + throw new exception(__METHOD__ .": category name (". $catName .") is invalid"); + } + + return($retval); + }//end get_category_id() + //========================================================================= + + + + //========================================================================= + /** + * Create a category_id based on the given name. + */ + private function create_log_category($catName) { + $sql = "INSERT INTO ". $this->tables['category'] ." (category_name) VALUES ('". + $this->gfObj->cleanString($catName, 'sql') ."')"; + + try { + $newId = $this->db->run_insert($sql, $this->seqs['category']); + + if(is_numeric($newId) && $newId > 0) { + $retval = $newId; + } + else { + throw new exception(__METHOD__ .": invalid data returned for " . + "category::: ". $this->gfObj->debug_var_dump($newId,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": error encountered while trying to " . + "create category::: ". $e->getMessage()); + } + + return($retval); + }//end create_log_category() + //========================================================================= + + + + //========================================================================= + /** + * Create a log_class_id based on the given name. + */ + private function create_class($className) { + $sql = "INSERT INTO ". $this->tables['class'] ." (class_name) VALUES ('". + $this->gfObj->cleanString($className, 'sql') ."')"; + + + try { + $newId = $this->db->run_insert($sql, $this->seqs['class']); + + if(is_numeric($newId) && $newId > 0) { + $retval = $newId; + } + else { + throw new exception(__METHOD__ .": failed to insert class or invalid " . + "id::: ". $this->gfObj->debug_var_dump($newId,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": error encountered while creating log " . + "class::: ". $e->getMessage()); + } + + return($retval); + }//end create_class() + //========================================================================= + + + + //========================================================================= + /** + * Retrieve class name from the given id. + */ + private function get_class_name($classId) { + if(is_numeric($classId)) { + $sql = "SELECT class_name FROM ". $this->tables['class'] ." WHERE class_id=". $classId; + + try { + $data = $this->db->run_query($sql); + + if(is_array($data) && isset($data['class_name']) && $this->db->numRows() == 1) { + $className = $data['class_name']; + } + else { + throw new exception(__METHOD__ .": failed to retrieve class " . + "name, or invalid return data::: ". $this->gfObj->debug_print($data,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": error encountered while " . + "retrieving class name::: ". $e->getMessage()); + } + + } + else { + throw new exception(__METHOD__ .": invalid class ID (". $classId .")"); + } + + return($className); + }//end get_class_name() + //========================================================================= + + + + //========================================================================= + /** + * Retrieve category name from the given ID. + */ + private function get_category_name($categoryId) { + if(is_numeric($categoryId)) { + $sql = "SELECT category_name FROM ". $this->tables['category'] ." WHERE category_id=". $categoryId; + + try { + $data = $this->db->run_query($sql); + + if(is_array($data) && isset($data['category_name']) && $this->db->numRows() == 1) { + $categoryName = $data['category_name']; + } + else { + throw new exception(__METHOD__ .": failed to retrieve " . + "category name::: ". $this->gfObj->debug_var_dump($data,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": error encountered while " . + "retrieving category name::: ". $e->getMessage()); + } + } + else { + throw new exception(__METHOD__ .": invalid category ID (". $categoryId .")"); + } + + return($categoryName); + }//end get_category_name() + //========================================================================= + + + + //========================================================================= + public function __get($var) { + return($this->$var); + }//end __get() + //========================================================================= + + + + //========================================================================= + public function __set($var, $newVal) { + $res = false; + switch($var) { + case 'suspendLogging': + $this->$var = $newVal; + if($newVal === false) { + #$this->handle_suspended_logs(); + } + $res = true; + break; + + case 'logCategory': + case 'logCategoryId': + $this->logCategoryId = $this->get_category_id($newVal); + $res = true; + break; + } + return($res); + }//end __set() + //========================================================================= + + + + //========================================================================= + public function handle_suspended_logs() { + $retval = 0; + $debugThis = array(); + if($this->suspendLogging === false && count($this->pendingLogs)) { + $myLogs = $this->pendingLogs; + $this->build_cache(); + $this->pendingLogs = array(); + foreach($myLogs as $i=>$args) { + //this is potentially deadly: call self recursively to log the items prevously suspended. + $newId = call_user_func_array(array($this, 'log_by_class'), $args); + + $debugThis[$newId] = $args; + $retval++; + } + } + return($retval); + }//end handle_suspended_logs() + //========================================================================= + + + + //========================================================================= + public function get_uid() { + $myUid = $this->defaultUid; + //check for a uid in the session. + if(is_array($_SESSION) && isset($_SESSION['uid']) && is_numeric($_SESSION['uid'])) { + //got an ID in the session. + $myUid = $_SESSION['uid']; + } + return($myUid); + }//end get_uid() + //========================================================================= + + + + //========================================================================= + private function create_attribute($attribName, $buildCache=true) { + + $myId = null; + if(isset($this->attributeCache[strtolower($attribName)])) { + $myId = $this->attributeCache[strtolower($attribName)]; + } + else { + $sql = "INSERT INTO ". $this->tables['attrib'] ." (attribute_name) " . + "VALUES ('". $this->gfObj->cleanString($attribName, 'sql_insert') ."')"; + + try { + $myId = $this->db->run_insert($sql, $this->seqs['attrib']); + } + catch(exception $e) { + throw new exception(__METHOD__ .": fatal error while creating attribute (". $attribName .")::: ". $e->getMessage()); + } + } + + if($buildCache) { + $this->build_cache(); + } + + return($myId); + }//end create_attribute() + //========================================================================= + + + + //========================================================================= + private function create_log_attributes($logId, array $attribs) { + $myIds = array(); + foreach($attribs as $name=>$val) { + $insertData = array( + 'log_id' => $logId, + 'attribute_id' => $this->create_attribute($name, false), + 'value_text' => $val + ); + $sql = "INSERT INTO ". $this->tables['logAttrib'] ." ". + $this->gfObj->string_from_array($insertData, 'insert'); + + try { + $myIds[$name][] = $this->db->run_insert($sql, $this->seqs['logAttrib']); + } + catch(exception $e) { + throw new exception(__METHOD__ .": fatal error while creating log attribute " . + "(". $name .")::: ". $e->getMessage()); + } + } + $this->build_cache(); + + }//end create_log_attributes() + //========================================================================= + + +}//end logsClass{} +?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-19 15:35:48
|
Revision: 105 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=105&view=rev Author: crazedsanity Date: 2009-08-19 15:35:35 +0000 (Wed, 19 Aug 2009) Log Message: ----------- Copied stuff from cs-webdbupgrade... Modified Paths: -------------- trunk/0.3/README.txt Added Paths: ----------- trunk/0.3/cs_webdbupgrade.class.php trunk/0.3/docs/ trunk/0.3/schema/ Modified: trunk/0.3/README.txt =================================================================== --- trunk/0.3/README.txt 2009-08-19 15:28:38 UTC (rev 104) +++ trunk/0.3/README.txt 2009-08-19 15:35:35 UTC (rev 105) @@ -1,4 +1,5 @@ +=== CS Web DB Logger === Once the appropriate schema has been built, code can be updated easily to start logging: //Create the class... Copied: trunk/0.3/cs_webdbupgrade.class.php (from rev 101, import/cs-webdbupgrade/trunk/0.2/cs_webdbupgrade.class.php) =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php (rev 0) +++ trunk/0.3/cs_webdbupgrade.class.php 2009-08-19 15:35:35 UTC (rev 105) @@ -0,0 +1,1096 @@ +<?php +/* + * Created on Jul 2, 2007 + * + * SVN INFORMATION::: + * ------------------ + * SVN Signature::::::: $Id$ + * Last Author::::::::: $Author$ + * Current Revision:::: $Revision$ + * Repository Location: $HeadURL$ + * Last Updated:::::::: $Date$ + * + */ + +require_once(constant('LIBDIR') .'/cs-versionparse/cs_version.abstract.class.php'); +require_once(constant('LIBDIR') .'/cs_debug.php'); + +class cs_webdbupgrade extends cs_versionAbstract { + + /** cs_fileSystem{} object: for filesystem read/write operations. */ + private $fsObj; + + /** cs_globalFunctions{} object: debugging, array, and string operations. */ + protected $gfObj; + + /** Array of configuration parameters. */ + private $config = NULL; + + /** Name of primary key sequence of main table (for handling inserts with PostgreSQL) */ + private $sequenceName; + + /** Database object. */ + protected $db; + + /** Object used to log activity. */ + protected $logsObj; + + /** Name of the project as referenced in the database. */ + protected $projectName; + + /** Internal cache of the version string from the VERSION file. */ + private $versionFileVersion = NULL; + + /** Stored database version. */ + private $databaseVersion = NULL; + + /** Name (absolute location) of *.lock file that indicates an upgrade is running. */ + private $lockfile; + + /** Determines if an internal upgrade is happening (avoids some infinite loops) */ + private $internalUpgradeInProgress = false; + + /** */ + private $allowNoDBVersion=true; + + /** Log messages to store during an internal upgrade (to avoid problems) */ + private $storedLogs = array(); + private $debugLogs=array(); + + /** List of acceptable suffixes; example "1.0.0-BETA3" -- NOTE: these MUST be in + * an order that reflects newest -> oldest; "ALPHA happens before BETA, etc. */ + private $suffixList = array( + 'ALPHA', //very unstable + 'BETA', //kinda unstable, but probably useable + 'RC' //all known bugs fixed, searching for unknown ones + ); + + //========================================================================= + public function __construct($versionFileLocation, $upgradeConfigFile, $lockFile='upgrade.lock') { + + //setup configuration parameters for database connectivity. + $dbParams = array( + 'host' => constant(__CLASS__ .'-DB_CONNECT_HOST'), + 'port' => constant(__CLASS__ .'-DB_CONNECT_PORT'), + 'dbname' => constant(__CLASS__ .'-DB_CONNECT_DBNAME'), + 'user' => constant(__CLASS__ .'-DB_CONNECT_USER'), + 'password' => constant(__CLASS__ .'-DB_CONNECT_PASSWORD') + ); + $this->config['DBPARAMS'] = $dbParams; + //Check for some required constants. + $requisiteConstants = array('LIBDIR'); + if(!defined('LIBDIR')) { + throw new exception(__METHOD__ .": required constant 'LIBDIR' not set"); + } + if(!defined('SITE_ROOT')) { + throw new exception(__METHOD__ .": required constant 'SITE_ROOT' not set"); + } + + require_once(constant('LIBDIR') .'/cs-content/cs_globalFunctions.class.php'); + require_once(constant('LIBDIR') .'/cs-content/cs_fileSystem.class.php'); + require_once(constant('LIBDIR') .'/cs-content/cs_phpDB.class.php'); + require_once(constant('LIBDIR') .'/cs-webdblogger/cs_webdblogger.class.php'); + require_once(constant('LIBDIR') .'/cs-phpxml/cs_phpxmlParser.class.php'); + require_once(constant('LIBDIR') .'/cs-phpxml/cs_phpxmlCreator.class.php'); + require_once(constant('LIBDIR') .'/cs-phpxml/cs_arrayToPath.class.php'); + + $this->fsObj = new cs_fileSystem(constant('SITE_ROOT')); + $this->gfObj = new cs_globalFunctions; + if(defined('DEBUGPRINTOPT')) { + $this->gfObj->debugPrintOpt = constant('DEBUGPRINTOPT'); + } + + if(!defined(__CLASS__ .'-DB_PRIMARYKEY') || !defined(__CLASS__ .'-DB_TABLE')) { + throw new exception(__METHOD__ .": no setting for DB_TABLE or DB_PRIMARYKEY, cannot continue"); + } + else { + $this->config['DB_TABLE'] = constant(__CLASS__ .'-DB_TABLE'); + $this->config['DB_PRIMARYKEY'] = constant(__CLASS__ .'-DB_PRIMARYKEY'); + } + $this->sequenceName = $this->config['DB_TABLE'] .'_'. $this->config['DB_PRIMARYKEY'] .'_seq'; + + if(!defined('DBTYPE')) { + throw new exception(__METHOD__ .": required constant 'DBTYPE' not set"); + } + + if(!file_exists($upgradeConfigFile) || !is_readable($upgradeConfigFile)) { + throw new exception(__METHOD__ .": required upgrade config file location (". $upgradeConfigFile .") not set or unreadable"); + } + else { + $this->config['UPGRADE_CONFIG_FILE'] = $upgradeConfigFile; + } + if(!strlen($versionFileLocation) || !file_exists($versionFileLocation)) { + throw new exception(__METHOD__ .": unable to locate version file (". $versionFileLocation .")"); + } + $this->set_version_file_location($versionFileLocation); + + if(!defined(__CLASS__ .'-RWDIR') || !is_dir(constant(__CLASS__ .'-RWDIR')) || !is_readable(constant(__CLASS__ .'-RWDIR')) || !is_writable(constant(__CLASS__ .'-RWDIR'))) { + throw new exception(__METHOD__ .": missing RWDIR (". constant(__CLASS__ .'-RWDIR') .") or isn't readable/writable"); + } + else { + $this->config['RWDIR'] = constant(__CLASS__ .'-RWDIR'); + } + if(is_null($lockFile) || !strlen($lockFile)) { + $lockFile = 'upgrade.lock'; + } + $this->lockfile = $this->config['RWDIR'] .'/'. $lockFile; + + $this->db = new cs_phpDB(constant('DBTYPE')); + try { + $this->db->connect($this->config['DBPARAMS']); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to connect to database or logger error: ". $e->getMessage()); + } + + if($this->check_lockfile()) { + //there is an existing lockfile... + throw new exception(__METHOD__ .": upgrade in progress: ". $this->fsObj->read($this->lockfile)); + } + + $this->check_internal_upgrades(); + + try { + $loggerDb = new cs_phpDB(constant('DBTYPE')); + $loggerDb->connect($this->config['DBPARAMS'], true); + $this->logsObj = new cs_webdblogger($loggerDb, "Upgrade ". $this->projectName, false); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to create logger::: ". $e->getMessage()); + } + + $this->check_versions(false); + }//end __construct() + //========================================================================= + + + + //========================================================================= + /** + * Determine if there are any upgrades that need to be performed... + */ + private function check_internal_upgrades() { + $oldVersionFileLocation = $this->versionFileLocation; + $oldUpgradeConfigFile = $this->config['UPGRADE_CONFIG_FILE']; + $this->config['UPGRADE_CONFIG_FILE'] = dirname(__FILE__) .'/upgrades/upgrade.xml'; + + + //set a status flag so we can store log messages (for now). + $this->internalUpgradeInProgress = true; + + + //do stuff here... + $this->set_version_file_location(dirname(__FILE__) .'/VERSION'); + $this->read_version_file(); + + //if there is an error, then... uh... yeah. + try { + $this->get_database_version(); + } + catch(exception $e) { + throw new exception(__METHOD__ .": error while retrieving database version: ". $e->getMessage()); + + //try creating the version. + $this->load_initial_version(); + } + + //do upgrades here... + $this->check_versions(true); + $this->internalUpgradeInProgress = false; + + + + + //reset internal vars. + $this->set_version_file_location($oldVersionFileLocation); + $this->config['UPGRADE_CONFIG_FILE'] = $oldUpgradeConfigFile; + $this->read_version_file(); + + }//end check_internal_upgrades() + //========================================================================= + + + + //========================================================================= + /** + * Where everything begins: checks if the version held in config.xml lines-up + * with the one in the VERSION file; if it does, then it checks the version + * listed in the database. + */ + public function check_versions($performUpgrade=TRUE) { + if(!is_bool($performUpgrade) || is_null($performUpgrade)) { + $performUpgrade = true; + } + + //first, check that all files exist. + $retval = NULL; + + //check to see if the lock files for upgrading exist. + if($this->upgrade_in_progress()) { + $this->do_log("Upgrade in progress", 'notice'); + throw new exception(__METHOD__ .": upgrade in progress"); + } + else { + //okay, all files present: check the version in the VERSION file. + $versionFileVersion = $this->read_version_file(); + $dbVersion = $this->get_database_version(); + if(!is_array($dbVersion)) { + $this->load_initial_version(); + } + + $versionsDiffer = TRUE; + $retval = FALSE; + + if($this->check_for_version_conflict() == false) { + $versionsDiffer = false; + $performUpgrade = false; + } + else { + $versionsDiffer = true; + } + + if($versionsDiffer == TRUE && $performUpgrade === TRUE) { + //reset the return value, so it'll default to failure until we say otherwise. + $retval = NULL; + + //Perform the upgrade! + $this->perform_upgrade(); + } + } + + return($retval); + }//end check_versions() + //========================================================================= + + + + //========================================================================= + protected function read_version_file() { + $retval = NULL; + + //okay, all files present: check the version in the VERSION file. + $versionFileContents = $this->fsObj->read($this->versionFileLocation); + + + $versionMatches = array(); + preg_match_all('/\nVERSION: (.*)\n/', $versionFileContents, $versionMatches); + if(count($versionMatches) == 2 && count($versionMatches[1]) == 1) { + $retval = trim($versionMatches[1][0]); + $this->versionFileVersion = $this->get_full_version_string($retval); + + //now retrieve the PROJECT name. + $projectMatches = array(); + preg_match_all('/\nPROJECT: (.*)\n/', $versionFileContents, $projectMatches); + if(count($projectMatches) == 2 && count($projectMatches[1]) == 1) { + $this->projectName = trim($projectMatches[1][0]); + } + else { + $this->error_handler(__METHOD__ .": failed to find PROJECT name"); + } + } + else { + $this->error_handler(__METHOD__ .": could not find VERSION data"); + } + + return($retval); + }//end read_version_file() + //========================================================================= + + + + //========================================================================= + /** + * Read information from our config file, so we know what to expect. + */ + private function read_upgrade_config_file() { + try { + $xmlString = $this->fsObj->read($this->config['UPGRADE_CONFIG_FILE']); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to read upgrade config file::: ". $e->getMessage()); + } + + //parse the file. + $xmlParser = new cs_phpxmlParser($xmlString); + + $config = $xmlParser->get_tree(TRUE); + + if(is_array($config['UPGRADE']) && count($config['UPGRADE'])) { + $this->config['UPGRADELIST'] = $config['UPGRADE']; + } + else { + $this->error_handler(__METHOD__ .": failed to retrieve 'UPGRADE' section; " . + "make sure upgrade.xml's ROOT element is 'UPGRADE'"); + } + }//end read_upgrade_config_file() + //========================================================================= + + + + //========================================================================= + private function perform_upgrade() { + $this->logsObj->suspendLogging=true; + //make sure there's not already a lockfile. + if($this->upgrade_in_progress()) { + //ew. Can't upgrade. + $this->error_handler(__METHOD__ .": upgrade already in progress...????"); + } + else { + $lockConfig = $this->upgrade_in_progress(TRUE); + $this->fsObj->cd("/"); + + $this->do_log("Starting upgrade process...", 'begin'); + + //TODO: not only should the "create_file()" method be run, but also do a sanity check by calling lock_file_exists(). + if($lockConfig === 0) { + //can't create the lockfile. Die. + $this->error_handler(__METHOD__ .": failed to set 'upgrade in progress'"); + } + else { + $this->do_log(__METHOD__ .": result of creating lockfile: (". $lockConfig .")", 'debug'); + + //push data into our internal "config" array. + $this->read_upgrade_config_file(); + $this->get_database_version(); + + //check for version conflicts. + $versionConflictInfo = $this->check_for_version_conflict(); + + + if($versionConflictInfo !== false) { + $this->do_log("Upgrading ". $versionConflictInfo ." versions, from " . + "(". $this->databaseVersion .") to (". $this->versionFileVersion .")", 'info'); + } + + $upgradeList = $this->get_upgrade_list(); + try { + $i=0; + $this->do_log(__METHOD__ .": starting to run through the upgrade list, starting at (". $this->databaseVersion ."), " . + "total number of upgrades to perform: ". count($upgradeList), 'debug'); + $this->db->beginTrans(__METHOD__); + foreach($upgradeList as $fromVersion=>$toVersion) { + + $details = __METHOD__ .": upgrading from ". $fromVersion ." to ". $toVersion ."... "; + $this->do_log($details, 'system'); + $this->do_single_upgrade($fromVersion, $toVersion); + $this->get_database_version(); + $i++; + + $details = __METHOD__ .": finished upgrade #". $i .", now at version (". $this->databaseVersion .")"; + $this->do_log($details, 'system'); + } + + if($i < count($upgradeList)) { + $this->do_log(__METHOD__ .": completed upgrade ". $i ." of ". count($upgradeList), 'debug'); + } + else { + if($this->databaseVersion == $this->versionFileVersion) { + $this->do_log(__METHOD__ .": finished upgrading after performing (". $i .") upgrades", 'debug'); + $this->newVersion = $this->databaseVersion; + } + else { + $this->do_log(__METHOD__ .": upgradeList::: ". $this->gfObj->debug_print($upgradeList,0), 'debug'); + $this->error_handler(__METHOD__ .": finished upgrade, but version wasn't updated (expecting '". $this->versionFileVersion ."', got '". $this->databaseVersion ."')!!!"); + } + } + $this->remove_lockfile(); + + $this->db->commitTrans(); + } + catch(exception $e) { + $transactionStatus = $this->db->get_transaction_status(false); + $this->error_handler(__METHOD__ .": transaction status=(". $transactionStatus ."), upgrade aborted:::". $e->getMessage()); + $this->db->rollbackTrans(); + } + $this->logsObj->suspendLogging=false; + $this->do_log("Upgrade process complete", 'end'); + } + } + $this->logsObj->suspendLogging=false; + $logsHandled = $this->logsObj->handle_suspended_logs(); + }//end perform_upgrade() + //========================================================================= + + + + //========================================================================= + public function upgrade_in_progress($makeItSo=FALSE) { + if($makeItSo === TRUE) { + if(strlen($this->databaseVersion)) { + $details = $this->projectName .': Upgrade from '. $this->databaseVersion .' started at '. date('Y-m-d H:i:s'); + $this->create_lockfile($details); + $retval = TRUE; + } + else { + $this->error_handler(__METHOD__ .": missing internal databaseVersion (". $this->databaseVersion .")"); + } + } + $retval = $this->check_lockfile(); + + return($retval); + }//end upgrade_in_progress() + //========================================================================= + + + + //========================================================================= + public function parse_version_string($versionString) { + if(is_null($versionString) || !strlen($versionString)) { + $this->error_handler(__METHOD__ .": invalid version string ($versionString)"); + } + + $suffix = ""; + $explodeThis = $versionString; + if(preg_match('/-[A-Z]{2,5}[0-9]{1,}/', $versionString)) { + $bits = explode('-', $versionString); + $suffix = $bits[1]; + $explodeThis = $bits[0]; + } + $tmp = explode('.', $explodeThis); + + + if(is_numeric($tmp[0]) && is_numeric($tmp[1])) { + $retval = array( + 'version_string' => $versionString, + 'version_major' => $tmp[0], + 'version_minor' => $tmp[1], + ); + if(isset($tmp[2])) { + $retval['version_maintenance'] = $tmp[2]; + } + else { + $retval['version_maintenance'] = 0; + } + + $retval['version_suffix'] = $suffix; + } + else { + $this->error_handler(__METHOD__ .": invalid version string format, requires MAJOR.MINOR syntax (". $versionString .")"); + } + + return($retval); + }//end parse_version_string() + //========================================================================= + + + + //========================================================================= + /** + * Checks for issues with versions. + * 0 == No problems. + * (string) == upgrade applicable (indicates "major"/"minor"/"maintenance"). + * NULL == encountered error + */ + private function check_for_version_conflict() { + //set a default return... + $retval = NULL; + + $this->read_version_file(); + + //parse the version strings. + $dbVersion = $this->get_database_version(); + $versionFileData = $this->parse_version_string($this->versionFileVersion); + + if($versionFileData['version_string'] == $dbVersion['version_string']) { + //good to go: no upgrade needed. + $retval = false; + } + else { + //NOTE: this seems very convoluted, but it works. + if($versionFileData['version_major'] == $dbVersion['version_major']) { + if($versionFileData['version_minor'] == $dbVersion['version_minor']) { + if($versionFileData['version_maintenance'] == $dbVersion['version_maintenance']) { + if($versionFileData['version_suffix'] == $dbVersion['version_suffix']) { + $this->error_handler(__METHOD__ .": no version upgrade detected, but version strings don't match (versionFile=". $versionFileData['version_string'] .", dbVersion=". $dbVersion['version_string'] .")"); + } + else { + $retval = "suffix"; + } + } + elseif($versionFileData['version_maintenance'] > $dbVersion['version_maintenance']) { + $retval = "maintenance"; + } + else { + $this->error_handler(__METHOD__ .": downgrading from maintenance versions is unsupported"); + } + } + elseif($versionFileData['version_minor'] > $dbVersion['version_minor']) { + $retval = "minor"; + } + else { + $this->error_handler(__METHOD__ .": downgrading minor versions is unsupported"); + } + } + elseif($versionFileData['version_major'] > $dbVersion['version_major']) { + $retval = "major"; + } + else { + $this->error_handler(__METHOD__ .": downgrading major versions is unsupported"); + } + } + + return($retval); + }//end check_for_version_conflict() + //========================================================================= + + + + //========================================================================= + private function get_database_version() { + $this->gfObj->debugPrintOpt=1; + //create a database object & attempt to read the database version. + + $sql = "SELECT * FROM ". $this->config['DB_TABLE'] ." WHERE project_name='" . + $this->gfObj->cleanString($this->projectName, 'sql') ."'"; + + $numrows = $this->db->exec($sql); + $dberror = $this->db->errorMsg(); + + if(strlen($dberror) || $numrows != 1) { + // + if(preg_match('/doesn\'t exist/', $dberror) || preg_match('/does not exist/', $dberror)) { + //add the table... + $loadTableResult = $this->load_table(); + if($loadTableResult === TRUE) { + //now try the SQL... + $numrows = $this->db->exec($sql); + $dberror = $this->db->errorMsg(); + } + else { + $this->error_handler(__METHOD__ .": no table in database, failed to create one... ORIGINAL " . + "ERROR: ". $dberror .", SCHEMA LOAD ERROR::: ". $loadTableResult); + } + } + elseif(!strlen($dberror) && $numrows == 0) { + if($this->allowNoDBVersion) { + $retval = false; + } + else { + $this->error_handler(__METHOD__ .": no version data found for (". $this->projectName .")"); + } + } + else { + $this->error_handler(__METHOD__ .": failed to retrieve version... numrows=(". $numrows ."), DBERROR::: ". $dberror); + } + } + else { + $data = $this->db->farray_fieldnames(); + $this->databaseVersion = $data['version_string']; + $retval = $this->parse_version_string($data['version_string']); + } + + return($retval); + }//end get_database_version() + //========================================================================= + + + + //========================================================================= + private function do_single_upgrade($fromVersion, $toVersion=null) { + //Use the "matching_syntax" data in the upgrade.xml file to determine the filename. + $versionIndex = "V". $this->get_full_version_string($fromVersion); + if(!isset($this->config['UPGRADELIST']['MATCHING'][$versionIndex])) { + //version-only upgrade. + $this->newVersion = $toVersion; + $this->update_database_version($toVersion); + } + else { + //scripted upgrade... + $scriptIndex = $versionIndex; + + $upgradeData = $this->config['UPGRADELIST']['MATCHING'][$versionIndex]; + + if(isset($upgradeData['TARGET_VERSION']) && count($upgradeData) > 1) { + $this->newVersion = $upgradeData['TARGET_VERSION']; + if(isset($upgradeData['SCRIPT_NAME']) && isset($upgradeData['CLASS_NAME']) && isset($upgradeData['CALL_METHOD'])) { + //good to go; it's a scripted upgrade. + $this->do_scripted_upgrade($upgradeData); + $this->update_database_version($upgradeData['TARGET_VERSION']); + } + else { + $this->error_handler(__METHOD__ .": not enough information to run scripted upgrade for ". $versionIndex); + } + } + else { + $this->error_handler(__METHOD__ .": target version not specified, unable to proceed with upgrade for ". $versionIndex); + } + } + $this->do_log("Finished upgrade to ". $this->newVersion, 'system'); + }//end do_single_upgrade() + //========================================================================= + + + + //========================================================================= + /** + * Updates information that's stored in the database, internal to cs-project, + * so the version there is consistent with all the others. + */ + protected function update_database_version($newVersionString) { + $versionInfo = $this->parse_version_string($newVersionString); + + $sql = "UPDATE ". $this->config['DB_TABLE'] ." SET version_string='". + $this->gfObj->cleanString($versionInfo['version_string'], 'sql') + ."' WHERE project_name='". + $this->gfObj->cleanString($this->projectName, 'sql') ."'"; + + + $updateRes = $this->db->run_update($sql,false); + if($updateRes == 1) { + $retval = $updateRes; + } + else { + $this->error_handler(__METHOD__ .": invalid result (". $updateRes .") "); + } + + //okay, now check that the version string matches the updated bits. + if(!$this->check_database_version($this->newVersion)) { + $this->error_handler(__METHOD__ .": database version information is invalid: (". $this->newVersion .")"); + } + + return($retval); + + }//end update_database_version() + //========================================================================= + + + + //========================================================================= + /** + * Checks consistency of version information in the database, and optionally + * against a given version string. + */ + private function check_database_version() { + //retrieve the internal version information. + if(!is_null($this->newVersion)) { + $data = $this->get_database_version(); + $versionString = $data['version_string']; + + if($versionString == $this->newVersion) { + $retval = TRUE; + } + else { + $retval = FALSE; + } + + if(!$retval) { + $this->do_log("Version check failed, versionString=(". $versionString ."), checkVersion=(". $this->newVersion .")", 'FATAL'); + } + + } + else { + $this->error_handler(__METHOD__ .": no version string given (". $this->newVersion .")"); + } + + return($retval); + }//end check_database_version() + //========================================================================= + + + + //========================================================================= + private function do_scripted_upgrade(array $upgradeData) { + $myConfigFile = $upgradeData['SCRIPT_NAME']; + + $this->do_log("Preparing to run script '". $myConfigFile ."'", 'debug'); + + //we've got the filename, see if it exists. + + $scriptsDir = dirname($this->config['UPGRADE_CONFIG_FILE']); + $fileName = $scriptsDir .'/'. $myConfigFile; + + if(file_exists($fileName)) { + + $this->do_log("(". __CLASS__ .") Performing scripted upgrade (". $myConfigFile .") from file '". $fileName ."'", 'DEBUG'); + $createClassName = $upgradeData['CLASS_NAME']; + $classUpgradeMethod = $upgradeData['CALL_METHOD']; + require_once($fileName); + + //now check to see that the class we need actually exists. + if(class_exists($createClassName)) { + $upgradeObj = new $createClassName($this->db); + if(method_exists($upgradeObj, $classUpgradeMethod)) { + $upgradeResult = $upgradeObj->$classUpgradeMethod(); + + if($upgradeResult === true) { + //yay, it worked! + $this->do_log("Upgrade succeeded (". $upgradeResult .")", 'success'); + } + else { + $this->error_handler(__METHOD__ .": upgrade failed (". $upgradeResult .")"); + } + $this->do_log("Finished running ". $createClassName ."::". $classUpgradeMethod ."(), result was (". $upgradeResult .")", 'debug'); + } + else { + $this->error_handler(__METHOD__ .": upgrade method doesn't exist (". $createClassName ."::". $classUpgradeMethod + ."), unable to perform upgrade "); + } + } + else { + $this->error_handler(__METHOD__ .": unable to locate upgrade class name (". $createClassName .")"); + } + } + else { + $this->error_handler(__METHOD__ .": upgrade filename (". $fileName .") does not exist"); + } + }//end do_scripted_upgrade() + //========================================================================= + + + + //========================================================================= + public function is_higher_version($version, $checkIfHigher) { + try { + $retval = parent::is_higher_version($version, $checkIfHigher); + } + catch(exception $e) { + $this->error_handler($e->getMessage()); + } + + return($retval); + + }//end is_higher_version() + //========================================================================= + + + + //========================================================================= + /** + * Determines list of upgrades to perform. + * + * If the current version is 1.0.1, the version file is 1.0.5, and there's a + * scripted upgrade at 1.0.4, this will update the database version to 1.0.3, + * run the scripted upgrade at 1.0.4, then update the database version to + * 1.0.5 (keeps from skipping the upgrade at 1.0.4) + */ + private function get_upgrade_list() { + $this->get_database_version(); + $dbVersion = $this->databaseVersion; + $newVersion = $this->versionFileVersion; + + $retval = array(); + if(!$this->is_higher_version($dbVersion, $newVersion)) { + $this->error_handler(__METHOD__ .": version (". $newVersion .") isn't higher than (". $dbVersion .")... something is broken"); + } + elseif(is_array($this->config['UPGRADELIST']['MATCHING'])) { + $lastVersion = $dbVersion; + foreach($this->config['UPGRADELIST']['MATCHING'] as $matchVersion=>$data) { + + $matchVersion = preg_replace('/^V/', '', $matchVersion); + if($matchVersion == $data['TARGET_VERSION']) { + $this->error_handler(__METHOD__ .": detected invalid TARGET_VERSION in (". $matchVersion ."): make sure TARGET_VERSION is higher than matching!"); + } + elseif($this->databaseVersion == $matchVersion || $this->is_higher_version($this->databaseVersion, $matchVersion)) { + //the version in MATCHING is equal to or HIGHER than our database version... make sure it is NOT + // higher than the version in our versionFile. + if(!$this->is_higher_version($this->versionFileVersion, $matchVersion)) { + if(!count($retval) && $matchVersion != $this->databaseVersion) { + $retval[$this->databaseVersion] = $matchVersion; + } + //the MATCHING version is NOT higher than the version file's version, looks ok. + $lastVersion = $data['TARGET_VERSION']; + $retval[$matchVersion] = $data['TARGET_VERSION']; + } + else { + $this->do_log(__METHOD__ .": entry in upgrade.xml (". $matchVersion .") is higher than the VERSION file (". $this->versionFileVersion .")", 'warning'); + } + } + else { + $this->do_log(__METHOD__ .": SKIPPING (". $matchVersion .")", 'debug'); + } + } + + if($lastVersion !== $newVersion && (!isset($retval[$lastVersion]) || $retval[$lastVersion] != $newVersion)) { + $retval[$lastVersion] = $newVersion; + } + } + else { + //no intermediary upgrades: just pass back the latest version. + $this->do_log(__METHOD__ .": no intermediary upgrades", 'debug'); + $retval[$dbVersion] = $this->versionFileVersion; + } + + return($retval); + + }//end get_upgrade_list() + //========================================================================= + + + + //========================================================================= + protected function parse_suffix($suffix) { + $retval = NULL; + if(strlen($suffix)) { + //determine what kind it is. + foreach($this->suffixList as $type) { + if(preg_match('/^'. $type .'/', $suffix)) { + $checkThis = preg_replace('/^'. $type .'/', '', $suffix); + if(strlen($checkThis) && is_numeric($checkThis)) { + //oooh... it's something like "BETA3" + $retval = array( + 'type' => $type, + 'number' => $checkThis + ); + } + else { + $this->error_handler(__METHOD__ .": invalid suffix (". $suffix .")"); + } + break; + } + } + } + else { + $this->error_handler(__METHOD__ .": invalid suffix (". $suffix .")"); + } + + return($retval); + }//end parse_suffix() + //========================================================================= + + + + //========================================================================= + private function fix_xml_config($config, $path=null) { + $this->xmlLoops++; + if($this->xmlLoops > 1000) { + $this->error_handler(__METHOD__ .": infinite loop detected..."); + } + + try { + $a2p = new cs_arrayToPath($config); + } + catch(exception $e) { + $this->do_log(__METHOD__ .': encountered exception: '. $e->getMessage()); + $this->error_handler($e->getMessage()); + } + if(!is_array($this->tempXmlConfig)) { + $this->tempXmlConfig = array(); + } + try { + $myA2p = new cs_arrayToPath(&$this->tempXmlConfig); + } + catch(exception $e) { + $this->do_log(__METHOD__ .': encountered exception: '. $e->getMessage()); + $this->error_handler($e->getMessage()); + } + + $myData = $a2p->get_data($path); + + if(is_array($myData)) { + if(isset($myData['type']) && $myData['type'] != 'open') { + if($myData['type'] == 'complete') { + $val = null; + if(isset($myData['value'])) { + $val = $myData['value']; + } + $oldData = $myA2p->get_data(); + $myA2p->set_data($path, $val); + $this->tempXmlConfig = $myA2p->get_data(); + } + else { + $this->error_handler(__METHOD__ .": invalid type (". $myData['type'] .")"); + } + } + else { + foreach($myData as $i=>$d) { + if(!in_array($i, array('type', 'attributes', 'value'))) { + $this->fix_xml_config($config, $path .'/'. $i); + } + } + } + } + else { + $this->error_handler(__METHOD__ .": unable to fix data on path=(". $path .")::: ". $this->gfObj->debug_print($myData,0)); + } + }//end fix_xml_config() + //========================================================================= + + + + //========================================================================= + public function load_table() { + $schemaFileLocation = dirname(__FILE__) .'/schema/schema.sql'; + $schema = file_get_contents($schemaFileLocation); + $schema = str_replace('{tableName}', $this->config['DB_TABLE'], $schema); + $schema = str_replace('{primaryKey}', $this->config['DB_PRIMARYKEY'], $schema); + $this->db->exec($schema); + + $loadTableResult = $this->db->errorMsg(); + if(!strlen($loadTableResult)) { + $loadTableResult = true; + $logRes = 'Successfully loaded'; + $logType = 'initialize'; + + //now set the initial version information... + if(strlen($this->projectName) && strlen($this->versionFileVersion)) { + $this->load_initial_version(); + } + else { + throw new exception(__METHOD__ .": missing projectName (". $this->projectName .") " . + "or versionFileVersion (". $this->versionFileVersion ."), cannot load data"); + } + } + else { + $logRes = 'Failed to load'; + $logType = 'error'; + } + $this->do_log($logRes .' table ('. $this->config['DB_TABLE'] .') into ' . + 'database::: '. $loadTableResult, $logType); + + return($loadTableResult); + }//end load_table() + //========================================================================= + + + + //========================================================================= + public function check_lockfile() { + $status = false; + if(file_exists($this->lockfile)) { + $status = true; + } + + return($status); + }//end check_lockfile() + //========================================================================= + + + + //========================================================================= + /** + * Create a *.lock file that indicates the system is in the process of + * performing an upgrade (safer than always updating the site's configuration + * file). + */ + public function create_lockfile($contents) { + if(!$this->check_lockfile()) { + if($this->fsObj->create_file($this->lockfile)) { + if(!preg_match('/\n$/', $contents)) { + $contents .= "\n"; + } + $writeRes = $this->fsObj->write($contents); + if(is_numeric($writeRes) && $writeRes > 0) { + $this->fsObj->closeFile(); + } + else { + $this->error_handler(__METHOD__ .": failed to write contents (". $contents .") to lockfile"); + } + } + else { + $this->error_handler(__METHOD__ .": failed to create lockfile (". $this->lockfile .")"); + } + } + else { + $this->error_handler(__METHOD__ .": failed to create lockfile, one already exists (". $this->lockfile .")"); + } + }//end create_lockfile() + //========================================================================= + + + + //========================================================================= + /** + * Destroy the *.lock file that indicates an upgrade is underway. + */ + private function remove_lockfile() { + if($this->check_lockfile()) { + if(!$this->fsObj->rm($this->lockfile)) { + $this->error_handler(__METHOD__ .": failed to remove lockfile (". $this->lockfile .")"); + } + } + else { + $this->error_handler(__METHOD__ .": no lockfile (". $this->lockfile .")"); + } + }//end remove_lockfile() + //========================================================================= + + + + //========================================================================= + private function get_full_version_string($versionString) { + if(strlen($versionString)) { + $bits = $this->parse_version_string($versionString); + + $fullVersion = $bits['version_major'] .'.'. $bits['version_minor'] .'.'. + $bits['version_maintenance']; + if(strlen($bits['version_suffix'])) { + $fullVersion .= '-'. $bits['version_suffix']; + } + } + else { + $this->error_handler(__METHOD__ .": no version string given"); + } + + return($fullVersion); + }//end get_full_version_string() + //========================================================================= + + + + //========================================================================= + public function error_handler($details) { + //log the error. + if(!is_object($this->logsObj)) { + throw new exception(__METHOD__ .": error while running an internal upgrade::: ". $details); + } + if($this->internalUpgradeInProgress === false) { + $this->do_log($details, 'exception in code'); + } + + //now throw an exception so other code can catch it. + throw new exception($details); + }//end error_handler() + //========================================================================= + + + + //========================================================================= + public function load_initial_version() { + //if there's an INITIAL_VERSION in the upgrade config file, use that. + $this->read_upgrade_config_file(); + $insertData = array(); + if(isset($this->config['UPGRADELIST']['INITIALVERSION'])) { + $parseThis = $this->config['UPGRADELIST']['INITIALVERSION']; + } + else { + $parseThis = $this->versionFileVersion; + } + $versionInfo = $this->parse_version_string($parseThis); + $insertData = array( + 'project_name' => $this->projectName, + 'version_string' => $versionInfo['version_string'] + ); + + $sql = 'INSERT INTO '. $this->config['DB_TABLE'] . $this->gfObj->string_from_array($insertData, 'insert'); + + if($this->db->run_insert($sql, $this->sequenceName)) { + $loadRes = true; + $this->do_log("Created data for '". $this->projectName ."' with version '". $insertData['version_string'] ."'", 'initialize'); + } + else { + $this->error_handler(__METHOD__ .": failed to load initial version::: ". $e->getMessage()); + } + + return($loadRes); + }//end load_initial_version() + //========================================================================= + + + + //========================================================================= + protected function do_log($message, $type) { + $this->debugLogs[] = array('project'=>$this->projectName,'upgradeFile'=>$this->config['UPGRADE_CONFIG_FILE'],'message'=>$message,'type'=>$type); + if($this->internalUpgradeInProgress === true) { + $this->storedLogs[] = func_get_args(); + } + else { + $this->logsObj->log_by_class($message, $type); + } + }//end do_log() + //========================================================================= + + +}//end upgrade{} + + +?> \ 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-08-19 15:44:59
|
Revision: 106 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=106&view=rev Author: crazedsanity Date: 2009-08-19 15:44:52 +0000 (Wed, 19 Aug 2009) Log Message: ----------- Consolidate schema into setup files & documentation into "docs" folder. Modified Paths: -------------- trunk/0.3/docs/README.txt trunk/0.3/setup/schema.mysql.sql trunk/0.3/setup/schema.pgsql.sql Removed Paths: ------------- trunk/0.3/CREDITS trunk/0.3/LICENSE trunk/0.3/README.txt trunk/0.3/schema/ Deleted: trunk/0.3/CREDITS =================================================================== --- trunk/0.3/CREDITS 2009-08-19 15:35:35 UTC (rev 105) +++ trunk/0.3/CREDITS 2009-08-19 15:44:52 UTC (rev 106) @@ -1,3 +0,0 @@ - -Lead Developer: Dan Falconer (cra...@us...) - Deleted: trunk/0.3/LICENSE =================================================================== --- trunk/0.3/LICENSE 2009-08-19 15:35:35 UTC (rev 105) +++ trunk/0.3/LICENSE 2009-08-19 15:44:52 UTC (rev 106) @@ -1,291 +0,0 @@ -NOTE: a full HTML version of this license can be found at: -http://www.opensource.org/licenses/gpl-license.php - -It has been reproduced below without any HTML. -========================================================================== - -The GNU General Public License (GPL) - -Version 2, June 1991 - - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - -NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS Deleted: trunk/0.3/README.txt =================================================================== --- trunk/0.3/README.txt 2009-08-19 15:35:35 UTC (rev 105) +++ trunk/0.3/README.txt 2009-08-19 15:44:52 UTC (rev 106) @@ -1,30 +0,0 @@ - -=== CS Web DB Logger === -Once the appropriate schema has been built, code can be updated easily to start logging: - -//Create the class... -$this->log = new cs_webdblogger($dbObj, 'Generic Activity'); - -//Now call the logger. -$this->log->log_by_class('User viewed page', 'info', $this->userId); - - - -UNDERSTANDING THE DATABASE SCHEMA::: -I understand things best from real data, so here goes:::: - -live_cs_project=# select rca.name as category, rcl.name as class, le.description from log_event_table AS le INNER JOIN log_class_table AS rcl USING (log_class_id) INNER JOIN log_category_table AS rca USING (log_category_id) limit 5; - category | class | description -----------+--------+-------------------------- - Project | Create | Project: created record - Project | Delete | Project: deleted record - Project | Update | Project: updated record - Project | Error | Project: ERROR - Helpdesk | Create | Helpdesk: Created record -(5 rows) - -The category indicates what system it is attached to, and class is a more -generic way of indicating what type of action it is. - - -$Id$ \ No newline at end of file Modified: trunk/0.3/docs/README.txt =================================================================== --- trunk/0.3/docs/README.txt 2009-08-19 15:35:35 UTC (rev 105) +++ trunk/0.3/docs/README.txt 2009-08-19 15:44:52 UTC (rev 106) @@ -1,6 +1,39 @@ $Id$ +=== CS Web DB Logger === +Once the appropriate schema has been built, code can be updated easily to start logging: + +//Create the class... +$this->log = new cs_webdblogger($dbObj, 'Generic Activity'); + +//Now call the logger. +$this->log->log_by_class('User viewed page', 'info', $this->userId); + + + +UNDERSTANDING THE DATABASE SCHEMA::: +I understand things best from real data, so here goes:::: + +live_cs_project=# select rca.name as category, rcl.name as class, le.description from log_event_table AS le INNER JOIN log_class_table AS rcl USING (log_class_id) INNER JOIN log_category_table AS rca USING (log_category_id) limit 5; + category | class | description +----------+--------+-------------------------- + Project | Create | Project: created record + Project | Delete | Project: deleted record + Project | Update | Project: updated record + Project | Error | Project: ERROR + Helpdesk | Create | Helpdesk: Created record +(5 rows) + +The category indicates what system it is attached to, and class is a more +generic way of indicating what type of action it is. + + + + +=== CS Web DB Upgrade === + + This system is built to make upgrading a database-driven app seamless. No need to coordinate SQL or schema changes with the code updates: previously, one would have to take the entire website down, run the schema/SQL change, update the code, Modified: trunk/0.3/setup/schema.mysql.sql =================================================================== --- trunk/0.3/setup/schema.mysql.sql 2009-08-19 15:35:35 UTC (rev 105) +++ trunk/0.3/setup/schema.mysql.sql 2009-08-19 15:44:52 UTC (rev 106) @@ -92,3 +92,20 @@ -- ALTER TABLE `cswdbl_log_table` ADD CONSTRAINT `cswdbl_log_table_event_id_fkey` FOREIGN KEY (`event_id`) REFERENCES `cswdbl_event_table` (`event_id`); + + +-- This table create statement MUST work in PostgreSQL v8.2.x+ AND MySQL v5.0.x+: +-- otherwise separate schema files have to be created and the code will have to +-- do extra checking... +-- +-- The "{tableName}" portion will be replaced with the value of the configured +-- "DB_TABLE" setting. +CREATE TABLE cs_version_table ( + version_id int NOT NULL PRIMARY KEY, + project_name varchar(30) NOT NULL UNIQUE, + version_string varchar(50) NOT NULL, + version_major integer NOT NULL, + version_minor integer NOT NULL, + version_maintenance integer NOT NULL, + version_suffix varchar(20) NOT NULL +); Modified: trunk/0.3/setup/schema.pgsql.sql =================================================================== --- trunk/0.3/setup/schema.pgsql.sql 2009-08-19 15:35:35 UTC (rev 105) +++ trunk/0.3/setup/schema.pgsql.sql 2009-08-19 15:44:52 UTC (rev 106) @@ -63,3 +63,16 @@ details text NOT NULL ); +-- This table create statement MUST work in PostgreSQL v8.2.x+ AND MySQL v5.0.x+: +-- otherwise separate schema files have to be created and the code will have to +-- do extra checking... +CREATE TABLE cs_version_table ( + version_id serial NOT NULL PRIMARY KEY, + project_name varchar(30) NOT NULL UNIQUE, + version_string varchar(50) NOT NULL, + version_major integer NOT NULL, + version_minor integer NOT NULL, + version_maintenance integer NOT NULL, + version_suffix varchar(20) NOT NULL +); + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-19 16:13:28
|
Revision: 109 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=109&view=rev Author: crazedsanity Date: 2009-08-19 16:13:16 +0000 (Wed, 19 Aug 2009) Log Message: ----------- Use a main abstract class which they all extend, fix require_once() paths. Modified Paths: -------------- trunk/0.3/cs_webdblogger.class.php trunk/0.3/cs_webdbupgrade.class.php Added Paths: ----------- trunk/0.3/cs_webapplibs.abstract.class.php Added: trunk/0.3/cs_webapplibs.abstract.class.php =================================================================== --- trunk/0.3/cs_webapplibs.abstract.class.php (rev 0) +++ trunk/0.3/cs_webapplibs.abstract.class.php 2009-08-19 16:13:16 UTC (rev 109) @@ -0,0 +1,20 @@ +<?php +/* + * Created on Aug 19, 2009 + * + * SVN INFORMATION::: + * ------------------- + * Last Author::::::::: $Author$ + * Current Revision:::: $Revision$ + * Repository Location: $HeadURL$ + * Last Updated:::::::: $Date$ + */ + +require_once(dirname(__FILE__) .'/cs_version.abstract.class.php'); + + +abstract class cs_webapplibsAbstract extends cs_versionAbstract { + +} + +?> Property changes on: trunk/0.3/cs_webapplibs.abstract.class.php ___________________________________________________________________ Added: svn:keywords + Id Author Revision HeadURL Date Modified: trunk/0.3/cs_webdblogger.class.php =================================================================== --- trunk/0.3/cs_webdblogger.class.php 2009-08-19 16:10:34 UTC (rev 108) +++ trunk/0.3/cs_webdblogger.class.php 2009-08-19 16:13:16 UTC (rev 109) @@ -27,9 +27,9 @@ //NOTE::: this class **REQUIRES** cs-content for its "cs_phpDB" class. -require_once(constant('LIBDIR') .'/cs-versionparse/cs_version.abstract.class.php'); +require_once(dirname(__FILE__) .'/cs_webapplibs.abstract.class.php'); -class cs_webdblogger extends cs_versionAbstract { +class cs_webdblogger extends cs_webapplibsAbstract { /** Database handle */ public $db; Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2009-08-19 16:10:34 UTC (rev 108) +++ trunk/0.3/cs_webdbupgrade.class.php 2009-08-19 16:13:16 UTC (rev 109) @@ -12,10 +12,10 @@ * */ -require_once(constant('LIBDIR') .'/cs-versionparse/cs_version.abstract.class.php'); -require_once(constant('LIBDIR') .'/cs_debug.php'); +require_once(dirname(__FILE__) .'/cs_webapplibs.abstract.class.php'); + require_once(dirname(__FILE__) .'/cs_webdblogger.class.php'); -class cs_webdbupgrade extends cs_versionAbstract { +class cs_webdbupgrade extends cs_webapplibsAbstract { /** cs_fileSystem{} object: for filesystem read/write operations. */ private $fsObj; @@ -89,7 +89,6 @@ require_once(constant('LIBDIR') .'/cs-content/cs_globalFunctions.class.php'); require_once(constant('LIBDIR') .'/cs-content/cs_fileSystem.class.php'); require_once(constant('LIBDIR') .'/cs-content/cs_phpDB.class.php'); - require_once(constant('LIBDIR') .'/cs-webdblogger/cs_webdblogger.class.php'); require_once(constant('LIBDIR') .'/cs-phpxml/cs_phpxmlParser.class.php'); require_once(constant('LIBDIR') .'/cs-phpxml/cs_phpxmlCreator.class.php'); require_once(constant('LIBDIR') .'/cs-phpxml/cs_arrayToPath.class.php'); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-19 17:14:30
|
Revision: 110 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=110&view=rev Author: crazedsanity Date: 2009-08-19 17:14:22 +0000 (Wed, 19 Aug 2009) Log Message: ----------- Beginnings of cs_authToken class, for storing of generic tokens to test against. Added Paths: ----------- trunk/0.3/cs_authToken.class.php trunk/0.3/setup/authtoken_schema.pgsql.sql trunk/0.3/tests/testOfAuthToken.php Added: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php (rev 0) +++ trunk/0.3/cs_authToken.class.php 2009-08-19 17:14:22 UTC (rev 110) @@ -0,0 +1,60 @@ +<?php +/* + * Created on Aug 19, 2009 + * + * SVN INFORMATION::: + * ------------------- + * Last Author::::::::: $Author$ + * Current Revision:::: $Revision$ + * Repository Location: $HeadURL$ + * Last Updated:::::::: $Date$ + */ + + +require_once(dirname(__FILE__) .'/cs_webapplibs.abstract.class.php'); + +class cs_authToken extends cs_webapplibsAbstract { + + /** Database object. */ + private $db; + + //========================================================================= + public function __construct(cs_phpDB $db) { + + if($db->is_connected()) { + $this->db = $db; + } + else { + throw new exception(__METHOD__ .": database object not connected"); + } + + }//end __construct() + //========================================================================= + + + + //========================================================================= + public function load_table() { + $file = dirname(__FILE__) .'/setup/authtoken_schema.'. $this->db->get_dbtype() .'.sql'; + + if(file_exists($file)) { + try { + $this->db->run_update(file_get_contents($file), true); + } + catch(exception $e) { + throw new exception(__METHOD__ .": error while trying to load table::: ". $e->getMessage()); + } + } + else { + throw new exception(__METHOD__ .": unsupported database type (". $this->db->get_dbtype() .")"); + } + }//end load_table() + //========================================================================= + + + + //========================================================================= + //========================================================================= + +} +?> Property changes on: trunk/0.3/cs_authToken.class.php ___________________________________________________________________ Added: svn:keywords + Id Author Revision HeadURL Date Added: trunk/0.3/setup/authtoken_schema.pgsql.sql =================================================================== --- trunk/0.3/setup/authtoken_schema.pgsql.sql (rev 0) +++ trunk/0.3/setup/authtoken_schema.pgsql.sql 2009-08-19 17:14:22 UTC (rev 110) @@ -0,0 +1,18 @@ +-- +-- SVN INFORMATION::: +-- --------------- +-- SVN Signature::::::: $Id$ +-- Last Author::::::::: $Author$ +-- Current Revision:::: $Revision$ +-- Repository Location: $HeadURL$ +-- Last Updated:::::::: $Date$ +-- + +CREATE TABLE cswal_auth_token_table ( + auth_token_id serial NOT NULL PRIMARY KEY, + uid integer NOT NULL DEFAULT 0, + checksum text NOT NULL, + token text NOT NULL, + creation date NOT NULL DEFAULT NOW(), + duration interval NOT NULL DEFAULT '1 day'::interval +); \ No newline at end of file Property changes on: trunk/0.3/setup/authtoken_schema.pgsql.sql ___________________________________________________________________ Added: svn:keywords + Id Author Revision HeadURL Date Copied: trunk/0.3/tests/testOfAuthToken.php (from rev 109, trunk/0.3/tests/testOfCSVersionParse.php) =================================================================== --- trunk/0.3/tests/testOfAuthToken.php (rev 0) +++ trunk/0.3/tests/testOfAuthToken.php 2009-08-19 17:14:22 UTC (rev 110) @@ -0,0 +1,80 @@ +<?php +/* + * Created on Jan 25, 2009 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +require_once(dirname(__FILE__) .'/../cs_authToken.class.php'); + +class testOfCSAuthToken extends UnitTestCase { + + //-------------------------------------------------------------------------- + function __construct() { + $this->gfObj = new cs_globalFunctions; + $this->gfObj->debugPrintOpt=1; + }//end __construct() + //-------------------------------------------------------------------------- + + + + //-------------------------------------------------------------------------- + function setUp() { + $tok = new cs_authToken($this->create_db()); + try { + $tok->load_table(); + } + catch(exception $e) { + } + }//end setUp() + //-------------------------------------------------------------------------- + + + + //-------------------------------------------------------------------------- + function tearDown() { + $db = $this->create_db(); + try { + $db->run_update('DROP TABLE cswal_auth_token_table', true); + } + catch(exception $e) { + } + }//end + //-------------------------------------------------------------------------- + + + + //-------------------------------------------------------------------------- + private function create_db() { + $dbParams = array( + 'host' => constant('DB_PG_HOST'), + 'dbname' => constant('DB_PG_DBNAME'), + 'user' => constant('DB_PG_DBUSER'), + 'password' => constant('DB_PG_DBPASS'), + 'port' => constant('DB_PG_PORT') + ); + $db = new cs_phpDB(constant('DBTYPE')); + $db->connect($dbParams); + return($db); + }//end create_db() + //-------------------------------------------------------------------------- + + + //-------------------------------------------------------------------------- + function test_basics() { + $db = $this->create_db(); + $tok = new cs_authToken($db); + + + }//end test_basics() + //-------------------------------------------------------------------------- +} + + +?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-19 17:44:19
|
Revision: 111 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=111&view=rev Author: crazedsanity Date: 2009-08-19 17:44:04 +0000 (Wed, 19 Aug 2009) Log Message: ----------- Testing of cs_authToken & ability to create a token. Modified Paths: -------------- trunk/0.3/cs_authToken.class.php trunk/0.3/setup/authtoken_schema.pgsql.sql trunk/0.3/tests/testOfAuthToken.php Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-19 17:14:22 UTC (rev 110) +++ trunk/0.3/cs_authToken.class.php 2009-08-19 17:44:04 UTC (rev 111) @@ -18,6 +18,15 @@ /** Database object. */ private $db; + /** Object that helps deal with strings. */ + private $gfObj; + + /** Name of the table */ + private $table = 'cswal_auth_token_table'; + + /** Sequence name for the given table (for PostgreSQL) */ + private $seq = 'cswal_auth_token_table_auth_token_id_seq'; + //========================================================================= public function __construct(cs_phpDB $db) { @@ -27,6 +36,7 @@ else { throw new exception(__METHOD__ .": database object not connected"); } + $this->gfObj = new cs_globalFunctions(); }//end __construct() //========================================================================= @@ -54,7 +64,46 @@ //========================================================================= + protected function create_hash_string($tokenId, $uid, $checksum, $stringToHash=NULL) { + return(md5($tokenId ."_". $uid ."_". $checksum ."_". $stringToHash)); + }//end create_hash_string() //========================================================================= + + + //========================================================================= + public function create_token($uid, $checksum, $stringToHash) { + + $this->db->beginTrans(); + + $insertData = array( + 'uid' => $uid, + 'checksum' => $checksum, + 'token' => '____INCOMPLETE____' + ); + try { + $sql = "INSERT INTO cswal_auth_token_table ". + $this->gfObj->string_from_array($insertData, 'insert', null, 'sql'); + $tokenId = $this->db->run_insert($sql, $this->seq); + + //now that we have the ID, let's create the real has string. + $finalHash = $this->create_hash_string($tokenId, $uid, $checksum, $stringToHash); + + $this->db->run_update("UPDATE ". $this->table ." SET token='". $finalHash ."' WHERE " . + "auth_token_id=". $tokenId); + + $tokenInfo = array( + 'id' => $tokenId, + 'hash' => $finalHash + ); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to create token::: ". $e->getMessage()); + } + + return($tokenInfo); + }//end create_token() + //========================================================================= + } ?> Modified: trunk/0.3/setup/authtoken_schema.pgsql.sql =================================================================== --- trunk/0.3/setup/authtoken_schema.pgsql.sql 2009-08-19 17:14:22 UTC (rev 110) +++ trunk/0.3/setup/authtoken_schema.pgsql.sql 2009-08-19 17:44:04 UTC (rev 111) @@ -13,6 +13,8 @@ uid integer NOT NULL DEFAULT 0, checksum text NOT NULL, token text NOT NULL, + use_limit integer DEFAULT NULL, + total_uses integer NOT NULL DEFAULT 0, creation date NOT NULL DEFAULT NOW(), duration interval NOT NULL DEFAULT '1 day'::interval ); \ No newline at end of file Modified: trunk/0.3/tests/testOfAuthToken.php =================================================================== --- trunk/0.3/tests/testOfAuthToken.php 2009-08-19 17:14:22 UTC (rev 110) +++ trunk/0.3/tests/testOfAuthToken.php 2009-08-19 17:44:04 UTC (rev 111) @@ -71,7 +71,14 @@ $db = $this->create_db(); $tok = new cs_authToken($db); - + //Generic test to ensure we get the appropriate data back. + $tokenData = $tok->create_token(0, 'test', 'abc123'); + $this->assertTrue(is_array($tokenData)); + $this->assertTrue((count($tokenData) == 2)); + $this->assertTrue(isset($tokenData['id'])); + $this->assertTrue(isset($tokenData['hash'])); + $this->assertTrue(($tokenData['id'] > 0)); + $this->assertTrue((strlen($tokenData['hash']) == 32)); }//end test_basics() //-------------------------------------------------------------------------- } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-19 19:01:31
|
Revision: 112 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=112&view=rev Author: crazedsanity Date: 2009-08-19 19:01:21 +0000 (Wed, 19 Aug 2009) Log Message: ----------- Can authenticate against a given token. /cs_authToken.class.php: * create_token(): -- ARG CHANGE: NEW ARG: #4 ($lifetime=null) -- ARG CHANGE: NEW ARG: #5 ($maxUses=null) -- allow setting of duration ($lifetime) or max_uses ($maxUses) when creating the token. -- update the $insertData array with 'duration' or 'max_uses' data if appropriate, based on args #4 and #5 * update_token_uses() [NEW]: -- updates the number of times a given token has been used. * destroy_token() [NEW]: -- deletes a specific token. * authenticate_token() [NEW]: -- authenticates the given data against a token. -- this handles updating uses & destroying tokens that have been used their maximum number of times: this means that mass token expiration can be done based purely on creation + duration. * get_token_data() [NEW]: -- returns data about the given token. /setup/authtoken_schema.pgsql.sql: * cswal_auth_token_table: -- changed "use_limit" to "max_uses" for sanity. /tests/testOfAuthToken.php: * additional tests for authentication. Modified Paths: -------------- trunk/0.3/cs_authToken.class.php trunk/0.3/setup/authtoken_schema.pgsql.sql trunk/0.3/tests/testOfAuthToken.php Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-19 17:44:04 UTC (rev 111) +++ trunk/0.3/cs_authToken.class.php 2009-08-19 19:01:21 UTC (rev 112) @@ -72,15 +72,19 @@ //========================================================================= - public function create_token($uid, $checksum, $stringToHash) { + public function create_token($uid, $checksum, $stringToHash, $lifetime=null, $maxUses=null) { - $this->db->beginTrans(); - $insertData = array( 'uid' => $uid, 'checksum' => $checksum, 'token' => '____INCOMPLETE____' ); + if(!is_null($lifetime) && strlen($lifetime)) { + $insertData['duration'] = $lifetime; + } + if(!is_null($maxUses) && is_numeric($maxUses) && $maxUses > 0) { + $insertData['max_uses'] = $maxUses; + } try { $sql = "INSERT INTO cswal_auth_token_table ". $this->gfObj->string_from_array($insertData, 'insert', null, 'sql'); @@ -105,5 +109,128 @@ }//end create_token() //========================================================================= + + + //========================================================================= + protected function update_token_uses($tokenId) { + + try { + $sql = "UPDATE ". $this->table ." SET total_uses= total_uses+1 " . + "WHERE auth_token_id=". $tokenId; + $updateRes = $this->db->run_update($sql); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to update usage count::: ". $e->getMessage()); + } + return($updateRes); + }//end update_token_uses() + //========================================================================= + + + + //========================================================================= + protected function destroy_token($tokenId) { + try { + $sql = "DELETE FROM ". $this->table ." WHERE auth_token_id=". $tokenId; + $deleteRes = $this->db->run_update($sql); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to "); + } + + return($deleteRes); + }//end destroy_token() + //========================================================================= + + + + //========================================================================= + /** + * Determine if a token is authentic: the id is used to make the search as + * fast as possible, while the hash & checksum are given to compare against. + * Failure results in FALSE, while success returns the contact_id for the + * given token. + * + * NOTE: the calling program can leave it to this method to say if the + * token is authentic, or use a checksum which can in turn be used to get + * a specific contact_id; when they authenticate, the return of this + * method must then match the contact_id retrieved from the checksum... + * + * EXAMPLE: + * $tokenUid = cs_authToken::authenticate_token($tokenId, $hash, $checksum); + * $realUid = userClass::get_uid_from_email($checksum); + * if($tokenUid == $realUid) { + * //token is truly authentic + * } + */ + public function authenticate_token($tokenId, $checksum, $hash) { + + $authTokenRes = null; + + if(is_numeric($tokenId) && strlen($checksum) && strlen($hash) == 32) { + $sql = "SELECT * FROM ". $this->table ." WHERE auth_token_id=". $tokenId + ." AND (creation + duration)::date >= CURRENT_DATE"; + + try { + $data = $this->db->run_query($sql, 'auth_token_id'); + + if(count($data) == 1 && isset($data[$tokenId]) && is_array($data[$tokenId])) { + $data = $data[$tokenId]; + + if($data['token'] == $hash && $data['checksum'] == $checksum) { + + $methodCall = 'update_token_uses'; + if(is_numeric($data['max_uses'])) { + $authTokenRes = null; + if($data['max_uses'] == $data['total_uses']) { + //reached max uses already... (maybe this should throw an exception?) + $methodCall = 'destroy_token'; + } + elseif($data['total_uses'] < $data['max_uses']) { + $authTokenRes = $data['uid']; + if(($data['total_uses'] +1) == $data['max_uses']) { + //this is the last use: just destroy it. + $methodCall = 'destroy_token'; + } + } + else { + throw new exception(__METHOD__ .": token (". $tokenId .") used more than max allowed uses [total=". $data['total_uses'] .", max=". $data['max_uses'] ."]"); + } + } + else { + $authTokenRes = $data['uid']; + } + $this->$methodCall($tokenId); + } + } + elseif($data === false) { + $authTokenRes = null; + } + else { + throw new exception(__METHOD__ .": invalid data returned:: ". $this->gfObj->debug_var_dump($data,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to authenticate token::: ". $e->getMessage()); + } + } + + return($authTokenRes); + }//end authenticate_token() + //========================================================================= + + + //========================================================================= + protected function get_token_data($tokenId) { + try { + $data = $this->db->run_query("SELECT * FROM ". $this->table ." WHERE auth_token_id=". $tokenId); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to retrieve tokenId (". $tokenId .")::: ". $e->getMessage()); + } + return($data); + }//end get_token_data(); + //========================================================================= + } ?> Modified: trunk/0.3/setup/authtoken_schema.pgsql.sql =================================================================== --- trunk/0.3/setup/authtoken_schema.pgsql.sql 2009-08-19 17:44:04 UTC (rev 111) +++ trunk/0.3/setup/authtoken_schema.pgsql.sql 2009-08-19 19:01:21 UTC (rev 112) @@ -13,7 +13,7 @@ uid integer NOT NULL DEFAULT 0, checksum text NOT NULL, token text NOT NULL, - use_limit integer DEFAULT NULL, + max_uses integer DEFAULT NULL, total_uses integer NOT NULL DEFAULT 0, creation date NOT NULL DEFAULT NOW(), duration interval NOT NULL DEFAULT '1 day'::interval Modified: trunk/0.3/tests/testOfAuthToken.php =================================================================== --- trunk/0.3/tests/testOfAuthToken.php 2009-08-19 17:44:04 UTC (rev 111) +++ trunk/0.3/tests/testOfAuthToken.php 2009-08-19 19:01:21 UTC (rev 112) @@ -69,19 +69,62 @@ //-------------------------------------------------------------------------- function test_basics() { $db = $this->create_db(); - $tok = new cs_authToken($db); + $tok = new authTokenTester($db); //Generic test to ensure we get the appropriate data back. - $tokenData = $tok->create_token(0, 'test', 'abc123'); + $tokenData = $tok->create_token(1, 'test', 'abc123'); $this->assertTrue(is_array($tokenData)); $this->assertTrue((count($tokenData) == 2)); $this->assertTrue(isset($tokenData['id'])); $this->assertTrue(isset($tokenData['hash'])); $this->assertTrue(($tokenData['id'] > 0)); $this->assertTrue((strlen($tokenData['hash']) == 32)); + + $this->assertEqual($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']), 1); + + + //now create a token with a maximum lifetime... + { + //Generic test to ensure we get the appropriate data back. + $tokenData = $tok->create_token(1, 'test', 'abc123', '2 years'); + $this->assertTrue(is_array($tokenData)); + $this->assertTrue((count($tokenData) == 2)); + $this->assertTrue(isset($tokenData['id'])); + $this->assertTrue(isset($tokenData['hash'])); + $this->assertTrue(($tokenData['id'] > 0)); + $this->assertTrue((strlen($tokenData['hash']) == 32)); + + $this->assertEqual($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']), 1); + } + + //create a token with only 1 available use and try to authenticate it twice. + { + //Generic test to ensure we get the appropriate data back. + $tokenData = $tok->create_token(1, 'test', 'abc123', null, 1); + $this->assertTrue(is_array($tokenData)); + $this->assertTrue((count($tokenData) == 2)); + $this->assertTrue(isset($tokenData['id'])); + $this->assertTrue(isset($tokenData['hash'])); + $this->assertTrue(($tokenData['id'] > 0)); + $this->assertTrue((strlen($tokenData['hash']) == 32)); + + if(!$this->assertEqual($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']), 1)) { + $this->gfObj->debug_print($tok->tokenData($tokenData['id']),1); + } + if(!$this->assertTrue(($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']) === null), "Able to authenticate twice on a token with only 1 use")) { + $this->gfObj->debug_print($tok->tokenData($tokenData['id'])); + } + } }//end test_basics() //-------------------------------------------------------------------------- } +class authTokenTester extends cs_authToken { + public $isTest=true; + + public function tokenData($id) { + return($this->get_token_data($id)); + } +} ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-19 20:12:40
|
Revision: 114 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=114&view=rev Author: crazedsanity Date: 2009-08-19 20:12:33 +0000 (Wed, 19 Aug 2009) Log Message: ----------- Changes to work with MySQL. /cs_authToken.class.php: * create_token(): -- use a combination of strftime(strtotime()) to create an appropriate expiration date based on a given lifetime (i.e. "1 day"). -- use "expiration" column instead of duration. * get_token_data(): -- updated to use expiration instead of creation + duration. /setup/authToken_schema.pgsql.sql: * cswal_auth_token_table: -- change creation to a timestamp. -- change duration(interval) to expiration(timestamp) Modified Paths: -------------- trunk/0.3/cs_authToken.class.php trunk/0.3/setup/authtoken_schema.pgsql.sql Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-19 19:24:52 UTC (rev 113) +++ trunk/0.3/cs_authToken.class.php 2009-08-19 20:12:33 UTC (rev 114) @@ -111,7 +111,7 @@ 'token' => '____INCOMPLETE____' ); if(!is_null($lifetime) && strlen($lifetime)) { - $insertData['duration'] = $lifetime; + $insertData['expiration'] = strftime('%Y-%m-%d %T', strtotime($lifetime)); } if(!is_null($maxUses) && is_numeric($maxUses) && $maxUses > 0) { $insertData['max_uses'] = $maxUses; @@ -282,7 +282,7 @@ protected function get_token_data($tokenId) { try { $data = $this->db->run_query("SELECT * FROM ". $this->table ." WHERE auth_token_id=". $tokenId - ." AND (creation + duration)::date >= CURRENT_DATE", 'auth_token_id'); + ." AND expiration::date >= CURRENT_DATE", 'auth_token_id'); if(is_array($data) && count($data) == 1) { $tokenData = $data; } Modified: trunk/0.3/setup/authtoken_schema.pgsql.sql =================================================================== --- trunk/0.3/setup/authtoken_schema.pgsql.sql 2009-08-19 19:24:52 UTC (rev 113) +++ trunk/0.3/setup/authtoken_schema.pgsql.sql 2009-08-19 20:12:33 UTC (rev 114) @@ -15,6 +15,6 @@ token text NOT NULL, max_uses integer DEFAULT NULL, total_uses integer NOT NULL DEFAULT 0, - creation date NOT NULL DEFAULT NOW(), - duration interval NOT NULL DEFAULT '1 day'::interval + creation timestamp NOT NULL DEFAULT NOW(), + expiration timestamp NOT NULL DEFAULT NOW() + '1 day'::interval ); \ 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-08-20 01:44:23
|
Revision: 115 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=115&view=rev Author: crazedsanity Date: 2009-08-20 01:44:14 +0000 (Thu, 20 Aug 2009) Log Message: ----------- Updated schema, tests, & set cs_authToken to be MySQL-compatible. TODO::: incorporate changes in cs-webdbupgrade that include the attribute tables into the main SQL file(s). /cs_authToken.class.php: * load_table() [DELETED]: -- this table should be included in with all the other tables. * create_token(): -- set a default value for expiration so the database doesn't have to set that. -- NOTE::: any tokens with a NULL expiration and unlimited uses will NEVER be automatically removed. /cs_webdbupgrade.class.php: * __construct(): -- set DB_TABLE and DB_PRIMARYKEY to hardcoded values. * load_table(): -- updated location of schema file -- NOTE::: this should probably be named "load_schema()", as it is actually loading several different tables now. /setup/authtoken_schema.pgsql.sql [DELETED]: * incorporated into the pgsql & mysql schema files. /setup/schema.mysql.sql: * changed "cs_version_table" to cswal_version_table (cswal == CS-WebAppLibs), removed unnecessary columns (previously removed in cs-webdbupgrade v0.2.0). * create cswal_auth_token_table. /setup/schema.pgsql.sql: * (same as the mysql version). /tests/testOfAuthToken.php: * remove code for creating & destroying tables (NOTE: my test site actually destroys & rebuilds the entire database... this should probably be changed to a series of "DROP TABLE" statements). Modified Paths: -------------- trunk/0.3/cs_authToken.class.php trunk/0.3/cs_webdbupgrade.class.php trunk/0.3/setup/schema.mysql.sql trunk/0.3/setup/schema.pgsql.sql trunk/0.3/tests/testOfAuthToken.php Removed Paths: ------------- trunk/0.3/setup/authtoken_schema.pgsql.sql Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-19 20:12:33 UTC (rev 114) +++ trunk/0.3/cs_authToken.class.php 2009-08-20 01:44:14 UTC (rev 115) @@ -48,29 +48,6 @@ //========================================================================= /** - * Load table into the database... - */ - public function load_table() { - $file = dirname(__FILE__) .'/setup/authtoken_schema.'. $this->db->get_dbtype() .'.sql'; - - if(file_exists($file)) { - try { - $this->db->run_update(file_get_contents($file), true); - } - catch(exception $e) { - throw new exception(__METHOD__ .": error while trying to load table::: ". $e->getMessage()); - } - } - else { - throw new exception(__METHOD__ .": unsupported database type (". $this->db->get_dbtype() .")"); - } - }//end load_table() - //========================================================================= - - - - //========================================================================= - /** * Standardized method of creating a hash from a string. * * @param $tokenId (int) matches auth_token_id column.... @@ -110,6 +87,8 @@ 'checksum' => $checksum, 'token' => '____INCOMPLETE____' ); + + $insertData['expiration'] = strftime('%Y-%m-%d %T', strtotime('1 day')); if(!is_null($lifetime) && strlen($lifetime)) { $insertData['expiration'] = strftime('%Y-%m-%d %T', strtotime($lifetime)); } Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2009-08-19 20:12:33 UTC (rev 114) +++ trunk/0.3/cs_webdbupgrade.class.php 2009-08-20 01:44:14 UTC (rev 115) @@ -99,13 +99,8 @@ $this->gfObj->debugPrintOpt = constant('DEBUGPRINTOPT'); } - if(!defined(__CLASS__ .'-DB_PRIMARYKEY') || !defined(__CLASS__ .'-DB_TABLE')) { - throw new exception(__METHOD__ .": no setting for DB_TABLE or DB_PRIMARYKEY, cannot continue"); - } - else { - $this->config['DB_TABLE'] = constant(__CLASS__ .'-DB_TABLE'); - $this->config['DB_PRIMARYKEY'] = constant(__CLASS__ .'-DB_PRIMARYKEY'); - } + $this->config['DB_TABLE'] = 'cswal_version_table'; + $this->config['DB_PRIMARYKEY'] = 'version_id'; $this->sequenceName = $this->config['DB_TABLE'] .'_'. $this->config['DB_PRIMARYKEY'] .'_seq'; if(!defined('DBTYPE')) { @@ -908,7 +903,7 @@ //========================================================================= public function load_table() { - $schemaFileLocation = dirname(__FILE__) .'/schema/schema.sql'; + $schemaFileLocation = dirname(__FILE__) .'/setup/schema.'. $this->db->get_dbtype() .'.sql'; $schema = file_get_contents($schemaFileLocation); $schema = str_replace('{tableName}', $this->config['DB_TABLE'], $schema); $schema = str_replace('{primaryKey}', $this->config['DB_PRIMARYKEY'], $schema); Deleted: trunk/0.3/setup/authtoken_schema.pgsql.sql =================================================================== --- trunk/0.3/setup/authtoken_schema.pgsql.sql 2009-08-19 20:12:33 UTC (rev 114) +++ trunk/0.3/setup/authtoken_schema.pgsql.sql 2009-08-20 01:44:14 UTC (rev 115) @@ -1,20 +0,0 @@ --- --- SVN INFORMATION::: --- --------------- --- SVN Signature::::::: $Id$ --- Last Author::::::::: $Author$ --- Current Revision:::: $Revision$ --- Repository Location: $HeadURL$ --- Last Updated:::::::: $Date$ --- - -CREATE TABLE cswal_auth_token_table ( - auth_token_id serial NOT NULL PRIMARY KEY, - uid integer NOT NULL DEFAULT 0, - checksum text NOT NULL, - token text NOT NULL, - max_uses integer DEFAULT NULL, - total_uses integer NOT NULL DEFAULT 0, - creation timestamp NOT NULL DEFAULT NOW(), - expiration timestamp NOT NULL DEFAULT NOW() + '1 day'::interval -); \ No newline at end of file Modified: trunk/0.3/setup/schema.mysql.sql =================================================================== --- trunk/0.3/setup/schema.mysql.sql 2009-08-19 20:12:33 UTC (rev 114) +++ trunk/0.3/setup/schema.mysql.sql 2009-08-20 01:44:14 UTC (rev 115) @@ -98,14 +98,19 @@ -- otherwise separate schema files have to be created and the code will have to -- do extra checking... -- --- The "{tableName}" portion will be replaced with the value of the configured --- "DB_TABLE" setting. -CREATE TABLE cs_version_table ( +CREATE TABLE cswal_version_table ( version_id int NOT NULL PRIMARY KEY, project_name varchar(30) NOT NULL UNIQUE, - version_string varchar(50) NOT NULL, - version_major integer NOT NULL, - version_minor integer NOT NULL, - version_maintenance integer NOT NULL, - version_suffix varchar(20) NOT NULL + version_string varchar(50) NOT NULL ); + +CREATE TABLE cswal_auth_token_table ( + auth_token_id serial NOT NULL PRIMARY KEY, + uid integer NOT NULL DEFAULT 0, + checksum text NOT NULL, + token text NOT NULL, + max_uses integer DEFAULT NULL, + total_uses integer NOT NULL DEFAULT 0, + creation timestamp NOT NULL DEFAULT NOW(), + expiration timestamp NOT NULL +); \ No newline at end of file Modified: trunk/0.3/setup/schema.pgsql.sql =================================================================== --- trunk/0.3/setup/schema.pgsql.sql 2009-08-19 20:12:33 UTC (rev 114) +++ trunk/0.3/setup/schema.pgsql.sql 2009-08-20 01:44:14 UTC (rev 115) @@ -66,13 +66,21 @@ -- This table create statement MUST work in PostgreSQL v8.2.x+ AND MySQL v5.0.x+: -- otherwise separate schema files have to be created and the code will have to -- do extra checking... -CREATE TABLE cs_version_table ( +CREATE TABLE cswal_version_table ( version_id serial NOT NULL PRIMARY KEY, project_name varchar(30) NOT NULL UNIQUE, - version_string varchar(50) NOT NULL, - version_major integer NOT NULL, - version_minor integer NOT NULL, - version_maintenance integer NOT NULL, - version_suffix varchar(20) NOT NULL + version_string varchar(50) NOT NULL ); + +CREATE TABLE cswal_auth_token_table ( + auth_token_id serial NOT NULL PRIMARY KEY, + uid integer NOT NULL DEFAULT 0, + checksum text NOT NULL, + token text NOT NULL, + max_uses integer DEFAULT NULL, + total_uses integer NOT NULL DEFAULT 0, + creation timestamp NOT NULL DEFAULT NOW(), + expiration timestamp NOT NULL +); + Modified: trunk/0.3/tests/testOfAuthToken.php =================================================================== --- trunk/0.3/tests/testOfAuthToken.php 2009-08-19 20:12:33 UTC (rev 114) +++ trunk/0.3/tests/testOfAuthToken.php 2009-08-20 01:44:14 UTC (rev 115) @@ -38,35 +38,6 @@ //-------------------------------------------------------------------------- - function tearDown() { - $db = $this->create_db(); - try { - $db->run_update('DROP TABLE cswal_auth_token_table', true); - } - catch(exception $e) { - } - }//end - //-------------------------------------------------------------------------- - - - - //-------------------------------------------------------------------------- - private function create_db() { - $dbParams = array( - 'host' => constant('DB_PG_HOST'), - 'dbname' => constant('DB_PG_DBNAME'), - 'user' => constant('DB_PG_DBUSER'), - 'password' => constant('DB_PG_DBPASS'), - 'port' => constant('DB_PG_PORT') - ); - $db = new cs_phpDB(constant('DBTYPE')); - $db->connect($dbParams); - return($db); - }//end create_db() - //-------------------------------------------------------------------------- - - - //-------------------------------------------------------------------------- function test_basics() { $db = $this->create_db(); $tok = new authTokenTester($db); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-20 01:51:04
|
Revision: 116 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=116&view=rev Author: crazedsanity Date: 2009-08-20 01:50:46 +0000 (Thu, 20 Aug 2009) Log Message: ----------- Incorporate upgrades from cs-webdblogger v0.2.0 into the main schema. Modified Paths: -------------- trunk/0.3/setup/schema.mysql.sql trunk/0.3/setup/schema.pgsql.sql trunk/0.3/upgrades/upgrade.xml Removed Paths: ------------- trunk/0.3/upgrades/sql/ trunk/0.3/upgrades/upgradeTo0.2.0.php trunk/0.3/upgrades/upgradeTo0.2.1.php Modified: trunk/0.3/setup/schema.mysql.sql =================================================================== --- trunk/0.3/setup/schema.mysql.sql 2009-08-20 01:44:14 UTC (rev 115) +++ trunk/0.3/setup/schema.mysql.sql 2009-08-20 01:50:46 UTC (rev 116) @@ -92,6 +92,50 @@ -- ALTER TABLE `cswdbl_log_table` ADD CONSTRAINT `cswdbl_log_table_event_id_fkey` FOREIGN KEY (`event_id`) REFERENCES `cswdbl_event_table` (`event_id`); + + + +-- +-- Table structure for table `cswdbl_log_attribute_table` +-- + +CREATE TABLE `cswdbl_log_attribute_table` ( + `log_attribute_id` int(11) NOT NULL auto_increment, + `log_id` int(11) NOT NULL, + `attribute_id` int(11) NOT NULL, + `value_text` text NOT NULL, + PRIMARY KEY (`log_attribute_id`), + KEY `cswdbl_log_attribute_table_log_id_fkey` (`log_id`), + KEY `cswdbl_log_attribute_table_attribute_id_fkey` (`attribute_id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `cswdbl_log_table` +-- + +CREATE TABLE `cswdbl_log_table` ( + `log_id` int(11) NOT NULL auto_increment, + `creation` timestamp NOT NULL default CURRENT_TIMESTAMP, + `event_id` int(11) NOT NULL, + `uid` int(11) NOT NULL, + `affected_uid` int(11) NOT NULL, + `details` text NOT NULL, + PRIMARY KEY (`log_id`), + KEY `cswdbl_log_table_event_id_fkey` (`event_id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + + + +-- +-- Constraints for table `cswdbl_log_attribute_table` +-- +ALTER TABLE `cswdbl_log_attribute_table` + ADD CONSTRAINT `cswdbl_log_attribute_table_attribute_id_fkey` FOREIGN KEY (`attribute_id`) REFERENCES `cswdbl_attribute_table` (`attribute_id`), + ADD CONSTRAINT `cswdbl_log_attribute_table_log_id_fkey` FOREIGN KEY (`log_id`) REFERENCES `cswdbl_log_table` (`log_id`); + + -- This table create statement MUST work in PostgreSQL v8.2.x+ AND MySQL v5.0.x+: Modified: trunk/0.3/setup/schema.pgsql.sql =================================================================== --- trunk/0.3/setup/schema.pgsql.sql 2009-08-20 01:44:14 UTC (rev 115) +++ trunk/0.3/setup/schema.pgsql.sql 2009-08-20 01:50:46 UTC (rev 116) @@ -63,6 +63,25 @@ details text NOT NULL ); + +-- +-- List of distinct attribute names. +-- +CREATE TABLE cswdbl_attribute_table ( + attribute_id serial NOT NULL PRIMARY KEY, + attribute_name text NOT NULL UNIQUE +); + +-- +-- Linkage for attributes to logs. +-- +CREATE TABLE cswdbl_log_attribute_table ( + log_attribute_id serial NOT NULL PRIMARY KEY, + log_id int NOT NULL REFERENCES cswdbl_log_table(log_id), + attribute_id int NOT NULL REFERENCES cswdbl_attribute_table(attribute_id), + value_text text +); + -- This table create statement MUST work in PostgreSQL v8.2.x+ AND MySQL v5.0.x+: -- otherwise separate schema files have to be created and the code will have to -- do extra checking... Modified: trunk/0.3/upgrades/upgrade.xml =================================================================== --- trunk/0.3/upgrades/upgrade.xml 2009-08-20 01:44:14 UTC (rev 115) +++ trunk/0.3/upgrades/upgrade.xml 2009-08-20 01:50:46 UTC (rev 116) @@ -18,12 +18,5 @@ to get skipped, or an exception to be thrown, potentially leaving the system in an unstable state. Unstable is bad, m'kay?</system_note> - <matching> - <v0.2.0> - <target_version>0.2.1</target_version> - <script_name>upgradeTo0.2.1.php</script_name> - <class_name>upgrade_to_0_2_1</class_name> - <call_method>run_upgrade</call_method> - </v0.2.0> - </matching> + <matching /> </upgrade> Deleted: trunk/0.3/upgrades/upgradeTo0.2.0.php =================================================================== --- trunk/0.3/upgrades/upgradeTo0.2.0.php 2009-08-20 01:44:14 UTC (rev 115) +++ trunk/0.3/upgrades/upgradeTo0.2.0.php 2009-08-20 01:50:46 UTC (rev 116) @@ -1,95 +0,0 @@ -<?php - -class upgrade_to_0_2_0 { - - //========================================================================= - public function __construct(cs_phpDB &$db) { - if(!$db->is_connected()) { - throw new exception(__METHOD__ .": database is not connected"); - } - $this->db = $db; - - $this->gfObj = new cs_globalFunctions; - $this->gfObj->debugPrintOpt = 1; - - }//end __construct() - //========================================================================= - - - - //========================================================================= - public function run_upgrade() { - - - $upgradeFilename = dirname(__FILE__) ."/sql/upgradeTo0_2_0.". $this->db->get_dbtype() .".sql"; - if(!file_exists($upgradeFilename)) { - throw new exception(__METHOD__ .": missing upgrade filename (". $upgradeFilename ."), " . - "probably due to unsupported database type (". $this->db->get_dbtype() .")"); - } - - - $tables = array( - 'cat' => array( - 'cswdbl_category_table', - 'log_category_table', - 'category_id' - ), - 'class' => array( - 'cswdbl_class_table', - 'log_class_table', - 'class_id' - ), - 'event' => array( - 'cswdbl_event_table', - 'log_event_table', - 'event_id' - ), - 'log' => array( - 'cswdbl_log_table', - 'log_table', - 'log_id' - ) - ); - - //run the SQL file. - $file = dirname(__FILE__) .'/sql/upgradeTo0_2_0.'. $this->db->get_dbtype() .'.sql'; - $upgradeRes = false; - if(file_exists($file)) { - $this->db->run_update(file_get_contents($file),true); - $totalToSync = count($tables); - $totalSynced = 0; - - //now make sure there's the same amount of data in BOTH tables. - foreach($tables as $key => $tables) { - $c1 = $this->db->run_query("SELECT * FROM ". $tables[0]); - $num1 = $this->db->numRows(); - $c2 = $this->db->run_query("SELECT * FROM ". $tables[1]); - $num2 = $this->db->numRows(); - - if($num1 === $num2) { - $totalSynced++; - $this->db->run_update("DROP TABLE ". $tables[1] ." CASCADE", true); - - if($this->db->get_dbtype() == 'pgsql') { - //Update the sequence... - $seq = $tables[0] .'_'. $tables[2] .'_seq'; - $this->db->run_update("SELECT setval('". $seq ."', (SELECT max(". $tables[2] .") FROM ". $tables[0] ."))",true); - } - } - else { - throw new exception(__METHOD__ .": failed to sync ". $tables[0] ." with ". $tables[1] ." (". $num1 ." != ". $num2 .")"); - } - } - $upgradeRes = true; - } - else { - throw new exception(__METHOD__ .": missing upgrade SQL file (". $file .")"); - } - - return($upgradeRes); - - }//end run_upgrade() - //========================================================================= -} - -?> Deleted: trunk/0.3/upgrades/upgradeTo0.2.1.php =================================================================== --- trunk/0.3/upgrades/upgradeTo0.2.1.php 2009-08-20 01:44:14 UTC (rev 115) +++ trunk/0.3/upgrades/upgradeTo0.2.1.php 2009-08-20 01:50:46 UTC (rev 116) @@ -1,47 +0,0 @@ -<?php - -class upgrade_to_0_2_1 { - - //========================================================================= - public function __construct(cs_phpDB &$db) { - if(!$db->is_connected()) { - throw new exception(__METHOD__ .": database is not connected"); - } - $this->db = $db; - - $this->gfObj = new cs_globalFunctions; - $this->gfObj->debugPrintOpt = 1; - - }//end __construct() - //========================================================================= - - - - //========================================================================= - public function run_upgrade() { - - - $upgradeFilename = dirname(__FILE__) ."/sql/upgradeTo0_2_1.". $this->db->get_dbtype() .".sql"; - if(!file_exists($upgradeFilename)) { - throw new exception(__METHOD__ .": missing upgrade filename (". $upgradeFilename ."), " . - "probably due to unsupported database type (". $this->db->get_dbtype() .")"); - } - - //run the SQL file. - $file = dirname(__FILE__) .'/sql/upgradeTo0_2_1.'. $this->db->get_dbtype() .'.sql'; - $upgradeRes = false; - if(file_exists($file)) { - $this->db->run_update(file_get_contents($file),true); - $upgradeRes = true; - } - else { - throw new exception(__METHOD__ .": missing upgrade SQL file (". $file .")"); - } - - return($upgradeRes); - - }//end run_upgrade() - //========================================================================= -} - -?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-20 14:55:30
|
Revision: 120 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=120&view=rev Author: crazedsanity Date: 2009-08-20 14:55:21 +0000 (Thu, 20 Aug 2009) Log Message: ----------- Drop tables (instead of DB), extra tests. /cs_authToken.class.php: * __construct(): -- create an instance of cs_webdbupgrade{} to see if an upgrade needs to be performed. -- NOTE::: this can be removed simply by adding logging, as cs_webdblogger::__construct() checks for upgrades. /tests/testOfCSWebAppLibs.php: * create_dbconn() RENAMED FROM create_db() * remove_tables() [NEW]: -- does a DROP ... CASCADE on all tables belonging to cs-webapplibs * test_token_basics(): -- updated references to use create_dbconn() -- move tests around slighly so I can view the database after & know for sure that the record that had only 1 use is actually missing (because there is a gap in auth_token_id's). -- test for creating a token with 0 max uses (to see that the invalid value for max_uses is ignored). Modified Paths: -------------- trunk/0.3/cs_authToken.class.php trunk/0.3/tests/testOfCSWebAppLibs.php Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-20 13:57:54 UTC (rev 119) +++ trunk/0.3/cs_authToken.class.php 2009-08-20 14:55:21 UTC (rev 120) @@ -41,6 +41,8 @@ } $this->gfObj = new cs_globalFunctions(); + $upg = new cs_webdbupgrade(dirname(__FILE__) .'/VERSION', dirname(__FILE__) .'/upgrades/upgrade.xml'); + $upg->check_versions(true); }//end __construct() //========================================================================= Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-20 13:57:54 UTC (rev 119) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-20 14:55:21 UTC (rev 120) @@ -126,7 +126,7 @@ //-------------------------------------------------------------------------- - private function create_db() { + private function create_dbconn() { $dbParams = array( 'host' => constant('DB_PG_HOST'), 'dbname' => constant('DB_PG_DBNAME'), @@ -141,9 +141,33 @@ //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + private function remove_tables() { + $tableList = array( + 'cswal_auth_token_table', 'cswal_version_table', 'cswdbl_attribute_table', + 'cswdbl_category_table', 'cswdbl_class_table', 'cswdbl_event_table', + 'cswdbl_log_attribute_table', 'cswdbl_log_table', + ); + + $db = $this->create_dbconn(); + foreach($tableList as $name) { + try { + $db->run_update("DROP TABLE ". $name ." CASCADE", true); + } + catch(exception $e) { + //force an error. + $this->assertTrue(false, "Error while dropping (". $name .")::: ". $e->getMessage()); + } + } + }//end remove_tables() + //-------------------------------------------------------------------------- + + + //-------------------------------------------------------------------------- function test_token_basics() { - $db = $this->create_db(); + $db = $this->create_dbconn(); + $this->remove_tables(); $tok = new authTokenTester($db); //Generic test to ensure we get the appropriate data back. @@ -157,11 +181,10 @@ $this->assertEqual($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']), 1); - - //now create a token with a maximum lifetime... + //create a token with only 1 available use and try to authenticate it twice. { //Generic test to ensure we get the appropriate data back. - $tokenData = $tok->create_token(1, 'test', 'abc123', '2 years'); + $tokenData = $tok->create_token(1, 'test', 'abc123', null, 1); $this->assertTrue(is_array($tokenData)); $this->assertTrue((count($tokenData) == 2)); $this->assertTrue(isset($tokenData['id'])); @@ -169,13 +192,19 @@ $this->assertTrue(($tokenData['id'] > 0)); $this->assertTrue((strlen($tokenData['hash']) == 32)); - $this->assertEqual($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']), 1); + if(!$this->assertEqual($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']), 1)) { + $this->gfObj->debug_print($tok->tokenData($tokenData['id']),1); + } + if(!$this->assertTrue(($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']) === null), "Able to authenticate twice on a token with only 1 use")) { + $this->gfObj->debug_print($tok->tokenData($tokenData['id'])); + } } - //create a token with only 1 available use and try to authenticate it twice. + + //now create a token with a maximum lifetime... { //Generic test to ensure we get the appropriate data back. - $tokenData = $tok->create_token(1, 'test', 'abc123', null, 1); + $tokenData = $tok->create_token(1, 'test', 'abc123', '2 years'); $this->assertTrue(is_array($tokenData)); $this->assertTrue((count($tokenData) == 2)); $this->assertTrue(isset($tokenData['id'])); @@ -183,12 +212,20 @@ $this->assertTrue(($tokenData['id'] > 0)); $this->assertTrue((strlen($tokenData['hash']) == 32)); - if(!$this->assertEqual($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']), 1)) { - $this->gfObj->debug_print($tok->tokenData($tokenData['id']),1); + $this->assertEqual($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']), 1); + } + + //try to create a token with max_uses of 0. + { + $tokenData = $tok->create_token(2, 'test', 'xxxxyyyyyxxxx', null, 0); + $checkData = $tok->tokenData($tokenData['id']); + $checkData = $checkData[$tokenData['id']]; + + $this->assertTrue(is_array($checkData)); + if(!$this->assertEqual($tokenData['id'], $checkData['auth_token_id'])) { + $this->gfObj->debug_print($checkData); } - if(!$this->assertTrue(($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']) === null), "Able to authenticate twice on a token with only 1 use")) { - $this->gfObj->debug_print($tok->tokenData($tokenData['id'])); - } + $this->assertEqual($checkData['max_uses'], null); } }//end test_token_basics() //-------------------------------------------------------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-20 15:52:17
|
Revision: 121 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=121&view=rev Author: crazedsanity Date: 2009-08-20 15:52:11 +0000 (Thu, 20 Aug 2009) Log Message: ----------- More tests, add "last_updated" to tokens. /cs_authToken.class.php: * create_token(): -- call _generic_update() to do the update statement. * update_token_uses(): -- call _generic_update() to do the update statement. * get_token_data(): -- ARG CHANGE: NEW ARG: #2 ($onlyNonExpired=true) -- add ability to get ANY token's data (for unit testing & eventually for logging purposes). * remove_expired_tokens() [NEW]: -- destroys tokens that are expired (doesn't do any checking as far as whether or not there are uses left). * _generic_update() [NEW]: -- besides the update string given, it also updates the (new) "last_updated" column. -- NOTE::: this was done so that the cs_sessionDB{} class from cs-content could potentially just call methods in this class to create & expire records... its just an idea for now. /setup/schema.mysql.sql: * cswal_auth_token_table: -- added "last_updated" (timestamp) column. -- NOTE::: didn't set the default as NOW() because MySQL won't allow more than one timestamp field to have that as the default...? /setup/schema.pgsql.sql: * mirrored changes to mysql schema. /tests/testOfCSWebAppLibs.php: * test_token_basics(): -- removed duplicate code into a private method, "basic_token_tests()" -- added test for creating an already-expired token. -- TODO: retrieve the token's data before authenticating, then test to see if it was removed afterward. * basic_token_tests() [NEW]: -- set of tests that are performed for pretty much every token created, so code was moved here so it is more standardized. Modified Paths: -------------- trunk/0.3/cs_authToken.class.php trunk/0.3/setup/schema.mysql.sql trunk/0.3/setup/schema.pgsql.sql trunk/0.3/tests/testOfCSWebAppLibs.php Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-20 14:55:21 UTC (rev 120) +++ trunk/0.3/cs_authToken.class.php 2009-08-20 15:52:11 UTC (rev 121) @@ -105,9 +105,7 @@ //now that we have the ID, let's create the real has string. $finalHash = $this->create_hash_string($tokenId, $uid, $checksum, $stringToHash); - $this->db->run_update("UPDATE ". $this->table ." SET token='". $finalHash ."' WHERE " . - "auth_token_id=". $tokenId); - + $this->_generic_update($tokenId, "token='". $finalHash ."'"); $tokenInfo = array( 'id' => $tokenId, 'hash' => $finalHash @@ -134,11 +132,8 @@ * @return (exception) FAIL: exception denotes problem */ protected function update_token_uses($tokenId) { - try { - $sql = "UPDATE ". $this->table ." SET total_uses= total_uses+1 " . - "WHERE auth_token_id=". $tokenId; - $updateRes = $this->db->run_update($sql); + $updateRes = $this->_generic_update($tokenId, "total_uses= total_uses+1"); } catch(exception $e) { throw new exception(__METHOD__ .": failed to update usage count::: ". $e->getMessage()); @@ -260,10 +255,15 @@ * @return (array) PASS: contains data about the given ID * @return (exception) FAIL: exception contains error details. */ - protected function get_token_data($tokenId) { + protected function get_token_data($tokenId, $onlyNonExpired=true) { try { - $data = $this->db->run_query("SELECT * FROM ". $this->table ." WHERE auth_token_id=". $tokenId - ." AND expiration::date >= CURRENT_DATE", 'auth_token_id'); + $sql = "SELECT * FROM ". $this->table ." WHERE auth_token_id=". $tokenId; + if($onlyNonExpired === true) { + $sql .= " AND expiration::date >= CURRENT_DATE"; + } + + $data = $this->db->run_query($sql, 'auth_token_id'); + if(is_array($data) && count($data) == 1) { $tokenData = $data; } @@ -281,5 +281,49 @@ }//end get_token_data(); //========================================================================= + + + //========================================================================= + /** + * Deletes any tokens that are past expiration (does not test for total vs. + * max uses; authenticate_token() does that). + * + * @param (null) (void) + */ + public function remove_expired_tokens() { + $sql = "SELECT * FROM ". $this->table ." WHERE NOW() > expiration"; + + try { + $data = $this->db->run_query($sql, 'auth_token_id'); + + if(is_array($data)) { + foreach($data as $tokenId => $tokenData) { + //TODO: add logging here? + $this->destroy_token($tokenId); + } + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": error encountered while expiring tokens::: ". $e->getMessage()); + } + }//end remove_expired_tokens() + //========================================================================= + + + + //========================================================================= + private function _generic_update($tokenId, $updateString) { + try { + $sql = "UPDATE ". $this->table ." SET ". $updateString .", last_updated=NOW() " . + "WHERE auth_token_id=". $tokenId; + $updateRes = $this->db->run_update($sql); + } + catch(exception $e) { + throw new exception("failed to update token::: ". $e->getMessage()); + } + return($updateRes); + }//end generic_update() + //========================================================================= + } ?> Modified: trunk/0.3/setup/schema.mysql.sql =================================================================== --- trunk/0.3/setup/schema.mysql.sql 2009-08-20 14:55:21 UTC (rev 120) +++ trunk/0.3/setup/schema.mysql.sql 2009-08-20 15:52:11 UTC (rev 121) @@ -156,5 +156,6 @@ max_uses integer DEFAULT NULL, total_uses integer NOT NULL DEFAULT 0, creation timestamp NOT NULL DEFAULT NOW(), + last_updated timestamp, expiration timestamp NOT NULL ); \ No newline at end of file Modified: trunk/0.3/setup/schema.pgsql.sql =================================================================== --- trunk/0.3/setup/schema.pgsql.sql 2009-08-20 14:55:21 UTC (rev 120) +++ trunk/0.3/setup/schema.pgsql.sql 2009-08-20 15:52:11 UTC (rev 121) @@ -100,6 +100,7 @@ max_uses integer DEFAULT NULL, total_uses integer NOT NULL DEFAULT 0, creation timestamp NOT NULL DEFAULT NOW(), + last_updated timestamp, expiration timestamp NOT NULL ); Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-20 14:55:21 UTC (rev 120) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-20 15:52:11 UTC (rev 121) @@ -164,6 +164,7 @@ //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- function test_token_basics() { $db = $this->create_dbconn(); @@ -185,12 +186,7 @@ { //Generic test to ensure we get the appropriate data back. $tokenData = $tok->create_token(1, 'test', 'abc123', null, 1); - $this->assertTrue(is_array($tokenData)); - $this->assertTrue((count($tokenData) == 2)); - $this->assertTrue(isset($tokenData['id'])); - $this->assertTrue(isset($tokenData['hash'])); - $this->assertTrue(($tokenData['id'] > 0)); - $this->assertTrue((strlen($tokenData['hash']) == 32)); + $this->basic_token_tests($tokenData, 1, 'test'); if(!$this->assertEqual($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']), 1)) { $this->gfObj->debug_print($tok->tokenData($tokenData['id']),1); @@ -205,12 +201,7 @@ { //Generic test to ensure we get the appropriate data back. $tokenData = $tok->create_token(1, 'test', 'abc123', '2 years'); - $this->assertTrue(is_array($tokenData)); - $this->assertTrue((count($tokenData) == 2)); - $this->assertTrue(isset($tokenData['id'])); - $this->assertTrue(isset($tokenData['hash'])); - $this->assertTrue(($tokenData['id'] > 0)); - $this->assertTrue((strlen($tokenData['hash']) == 32)); + $this->basic_token_tests($tokenData, 1, 'test'); $this->assertEqual($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash']), 1); } @@ -218,17 +209,43 @@ //try to create a token with max_uses of 0. { $tokenData = $tok->create_token(2, 'test', 'xxxxyyyyyxxxx', null, 0); + $this->basic_token_tests($tokenData, 2, 'test'); $checkData = $tok->tokenData($tokenData['id']); $checkData = $checkData[$tokenData['id']]; $this->assertTrue(is_array($checkData)); - if(!$this->assertEqual($tokenData['id'], $checkData['auth_token_id'])) { - $this->gfObj->debug_print($checkData); - } + $this->assertEqual($tokenData['id'], $checkData['auth_token_id']); $this->assertEqual($checkData['max_uses'], null); } + + //try creating a token that is purposely expired, make sure it exists, then make sure authentication fails. + { + $tokenData = $tok->create_token(88, 'test', 'This is a big old TEST', '-3 days'); + if($this->assertTrue(is_array($tokenData))) { + $this->basic_token_tests($tokenData, 88, 'This is a big old TEST'); + $this->assertFalse($tok->authenticate_token($tokenData['id'], 'test', $tokenData['hash'])); + } + } }//end test_token_basics() //-------------------------------------------------------------------------- + + + + //-------------------------------------------------------------------------- + private function basic_token_tests(array $tokenData, $uid, $checksum) { + + if($this->assertTrue(is_array($tokenData)) && $this->assertTrue(is_numeric($uid)) && $this->assertTrue(strlen($checksum))) { + + $this->assertTrue(is_array($tokenData)); + $this->assertTrue((count($tokenData) == 2)); + $this->assertTrue(isset($tokenData['id'])); + $this->assertTrue(isset($tokenData['hash'])); + $this->assertTrue(($tokenData['id'] > 0)); + $this->assertTrue((strlen($tokenData['hash']) == 32)); + } + + }//end basic_token_tests() + //-------------------------------------------------------------------------- } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-20 16:21:57
|
Revision: 122 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=122&view=rev Author: crazedsanity Date: 2009-08-20 16:21:45 +0000 (Thu, 20 Aug 2009) Log Message: ----------- Moved cs_versionAbstract to cs-content, abstract class into abstract folder. NOTE::: as stated in a recent commit to cs-content, moving cs_versionAbstract into the cs-content project means the two projects are not inextricably attached to one another, and that this project is truly an extension of cs-content. Previously, since everything in cs-content required cs_versionAbstract{}, this project would ALWAYS have to be available (which wasn't a problem when cs_versionAbstract{} was in it's own project, "cs-versionparse"). /cs_authToken.class.php: * fix location of cs_webapplibsAbstract. /cs_version.abstract.class.php [MOVED]: * moved to cs-content/abstract/ /cs_webdblogger.class.php: * fix location of cs_webapplibsAbstract. /cs_webdbupgrade.class.php: * fix location of cs_webapplibsAbstract. /tests/testOfCSWebAppLibs.php: * test_version_basics() [DELETED] * test_check_higher() [DELETED] * middleTestClass{} [DELETED] /tests/files/version* [DELETED]: * moved to cs-content for testing cs_versionAbstract Modified Paths: -------------- trunk/0.3/cs_authToken.class.php trunk/0.3/cs_webdblogger.class.php trunk/0.3/cs_webdbupgrade.class.php trunk/0.3/tests/testOfCSWebAppLibs.php Added Paths: ----------- trunk/0.3/abstract/ trunk/0.3/abstract/cs_webapplibs.abstract.class.php Removed Paths: ------------- trunk/0.3/cs_version.abstract.class.php trunk/0.3/cs_webapplibs.abstract.class.php trunk/0.3/tests/files/version1 trunk/0.3/tests/files/version2 trunk/0.3/tests/files/version3 Copied: trunk/0.3/abstract/cs_webapplibs.abstract.class.php (from rev 119, trunk/0.3/cs_webapplibs.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_webapplibs.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_webapplibs.abstract.class.php 2009-08-20 16:21:45 UTC (rev 122) @@ -0,0 +1,20 @@ +<?php +/* + * Created on Aug 19, 2009 + * + * SVN INFORMATION::: + * ------------------- + * Last Author::::::::: $Author$ + * Current Revision:::: $Revision$ + * Repository Location: $HeadURL$ + * Last Updated:::::::: $Date$ + */ + +require_once(constant('LIBDIR') .'/cs-content/abstract/cs_version.abstract.class.php'); + + +abstract class cs_webapplibsAbstract extends cs_versionAbstract { + +} + +?> Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-20 15:52:11 UTC (rev 121) +++ trunk/0.3/cs_authToken.class.php 2009-08-20 16:21:45 UTC (rev 122) @@ -11,7 +11,7 @@ */ -require_once(dirname(__FILE__) .'/cs_webapplibs.abstract.class.php'); +require_once(dirname(__FILE__) .'/abstract/cs_webapplibs.abstract.class.php'); class cs_authToken extends cs_webapplibsAbstract { Deleted: trunk/0.3/cs_version.abstract.class.php =================================================================== --- trunk/0.3/cs_version.abstract.class.php 2009-08-20 15:52:11 UTC (rev 121) +++ trunk/0.3/cs_version.abstract.class.php 2009-08-20 16:21:45 UTC (rev 122) @@ -1,398 +0,0 @@ -<?php -/* - * Created on January 01, 2009 by Dan Falconer - * - * SVN INFORMATION::: - * ------------------- - * Last Author::::::::: $Author$ - * Current Revision:::: $Revision$ - * Repository Location: $HeadURL$ - * Last Updated:::::::: $Date$ - */ - -abstract class cs_versionAbstract { - - public $isTest = FALSE; - - - - private $versionFileLocation=null; - private $fullVersionString; - private $suffixList = array( - 'ALPHA', //very unstable - 'BETA', //kinda unstable, but probably useable - 'RC' //all known bugs fixed, searching for unknown ones - ); - - - - abstract public function __construct(); - - - - //========================================================================= - /** - * Retrieve our version string from the VERSION file. - */ - final public function get_version($asArray=false) { - $retval = NULL; - - $this->auto_set_version_file(); - - if(file_exists($this->versionFileLocation)) { - $myMatches = array(); - $findIt = preg_match('/VERSION: (.+)/', file_get_contents($this->versionFileLocation), $matches); - - if($findIt == 1 && count($matches) == 2) { - $fullVersionString = $matches[1]; - $versionInfo = $this->parse_version_string($fullVersionString); - $this->fullVersionString = $this->build_full_version_string($versionInfo); - - - if($asArray) { - $retval = $versionInfo; - $retval['version_string'] = $this->fullVersionString; - } - else { - $retval = $this->build_full_version_string($versionInfo); - } - } - else { - throw new exception(__METHOD__ .": failed to retrieve version string in file " . - "(". $this->versionFileLocation .")"); - } - } - else { - throw new exception(__METHOD__ .": failed to retrieve version information, file " . - "(". $this->versionFileLocation .") does not exist or was not set"); - } - - return($retval); - }//end get_version() - //========================================================================= - - - - //========================================================================= - public function __get($var) { - return($this->$var); - }//end __get() - //========================================================================= - - - - //========================================================================= - final public function get_project() { - $retval = NULL; - $this->auto_set_version_file(); - if(file_exists($this->versionFileLocation)) { - $myMatches = array(); - $findIt = preg_match('/PROJECT: (.+)/', file_get_contents($this->versionFileLocation), $matches); - - if($findIt == 1 && count($matches) == 2 && strlen($matches[1])) { - $retval = $matches[1]; - } - else { - throw new exception(__METHOD__ .": failed to retrieve project string"); - } - } - else { - throw new exception(__METHOD__ .": failed to retrieve project information"); - } - - return($retval); - }//end get_project() - //========================================================================= - - - - //========================================================================= - public function set_version_file_location($location) { - if(file_exists($location)) { - $this->versionFileLocation = $location; - } - else { - throw new exception(__METHOD__ .": invalid location of VERSION file (". $location .")"); - } - }//end set_version_file_location() - //========================================================================= - - - - //========================================================================= - protected function auto_set_version_file() { - if(!strlen($this->versionFileLocation)) { - $bt = debug_backtrace(); - foreach($bt as $callNum=>$data) { - if(strlen($data['class'])) { - if($data['class'] != __CLASS__) { - $dir = dirname($data['file']); - if(preg_match('/tests$/', $dir)) { - $dir = preg_replace('/\/tests$/', '', $dir); - } - elseif(preg_match('/test$/', $dir)) { - $dir = preg_replace('/\/test$/', '', $dir); - } - break; - } - } - else { - throw new exception(__METHOD__ .": failed to locate the calling class in backtrace"); - } - } - - if(file_exists($dir .'/VERSION')) { - $this->set_version_file_location($dir .'/VERSION'); - } - else { - throw new exception(__METHOD__ .": failed to automatically set version file (tried ". $dir ."/VERSION)"); - } - } - }//end auto_set_version_file() - //========================================================================= - - - - //========================================================================= - /** - * - * TODO: add logic to split apart the suffix (i.e. "-ALPHA5" broken into "ALPHA" and "5"). - */ - public function parse_version_string($version) { - if(is_string($version) && strlen($version) && preg_match('/\./', $version)) { - $version = preg_replace('/ /', '', $version); - - $pieces = explode('.', $version); - $retval = array( - 'version_major' => $pieces[0], - 'version_minor' => $pieces[1] - ); - if(isset($pieces[2]) && strlen($pieces[2])) { - $retval['version_maintenance'] = $pieces[2]; - } - else { - $retval['version_maintenance'] = 0; - } - - if(preg_match('/-/', $retval['version_maintenance'])) { - $bits = explode('-', $retval['version_maintenance']); - $retval['version_maintenance'] = $bits[0]; - $suffix = $bits[1]; - } - elseif(preg_match('/-/', $retval['version_minor'])) { - $bits = explode('-', $retval['version_minor']); - $retval['version_minor'] = $bits[0]; - $suffix = $bits[1]; - } - else { - $suffix = ""; - } - $retval['version_suffix'] = $suffix; - } - else { - throw new exception(__METHOD__ .": invalid version string passed (". $version .")"); - } - - return($retval); - }//end parse_version_string() - //========================================================================= - - - - //========================================================================= - public function build_full_version_string(array $versionInfo) { - $requiredIndexes = array( - 'version_major', 'version_minor', 'version_maintenance', 'version_suffix' - ); - - $missing=""; - $count=0; - foreach($requiredIndexes as $indexName) { - if(isset($versionInfo[$indexName])) { - $count++; - } - else { - if(strlen($missing)) { - $missing .= ", ". $indexName; - } - else { - $missing = $indexName; - } - } - } - - if($count == count($requiredIndexes) && !strlen($missing)) { - $suffix = $versionInfo['version_suffix']; - unset($versionInfo['version_suffix']); - - $retval = ""; - foreach($versionInfo as $name=>$value) { - if(strlen($retval)) { - $retval .= ".". $value; - } - else { - $retval = $value; - } - } - if(strlen($suffix)) { - $retval .= "-". $suffix; - } - } - else { - throw new exception(__METHOD__ .": missing indexes in given array (". $missing .")"); - } - - return($retval); - - }//end build_full_version_string() - //========================================================================= - - - - //========================================================================= - public function is_higher_version($version, $checkIfHigher) { - $retval = FALSE; - $this->gfObj = new cs_globalFunctions; - if(!is_string($version) || !is_string($checkIfHigher)) { - throw new exception(__METHOD__ .": no valid version strings, version=(". $version ."), checkIfHigher=(". $checkIfHigher .")"); - } - elseif($version == $checkIfHigher) { - $retval = FALSE; - } - else { - $curVersionArr = $this->parse_version_string($version); - $checkVersionArr = $this->parse_version_string($checkIfHigher); - - unset($curVersionArr['version_string'], $checkVersionArr['version_string']); - - - $curVersionSuffix = $curVersionArr['version_suffix']; - $checkVersionSuffix = $checkVersionArr['version_suffix']; - - - unset($curVersionArr['version_suffix']); - - foreach($curVersionArr as $index=>$versionNumber) { - $checkThis = $checkVersionArr[$index]; - - if(is_numeric($checkThis) && is_numeric($versionNumber)) { - //set them as integers. - settype($versionNumber, 'int'); - settype($checkThis, 'int'); - - if($checkThis > $versionNumber) { - $retval = TRUE; - break; - } - elseif($checkThis == $versionNumber) { - //they're equal... - } - else { - //TODO: should there maybe be an option to throw an exception (freak out) here? - } - } - else { - throw new exception(__METHOD__ .": ". $index ." is not numeric in one of the strings " . - "(versionNumber=". $versionNumber .", checkThis=". $checkThis .")"); - } - } - - //now deal with those damnable suffixes, but only if the versions are so far identical: if - // the "$checkIfHigher" is actually higher, don't bother (i.e. suffixes don't matter when - // we already know there's a major, minor, or maintenance version that's also higher. - if($retval === FALSE) { - //EXAMPLE: $version="1.0.0-BETA3", $checkIfHigher="1.1.0" - // Moving from a non-suffixed version to a suffixed version isn't supported, but the inverse is: - // i.e. (1.0.0-BETA3 to 1.0.0) is okay, but (1.0.0 to 1.0.0-BETA3) is NOT. - // Also: (1.0.0-BETA3 to 1.0.0-BETA4) is okay, but (1.0.0-BETA4 to 1.0.0-BETA3) is NOT. - if(strlen($curVersionSuffix) && strlen($checkVersionSuffix) && $curVersionSuffix == $checkVersionSuffix) { - //matching suffixes. - } - elseif(strlen($curVersionSuffix) || strlen($checkVersionSuffix)) { - //we know the suffixes are there and DO match. - if(strlen($curVersionSuffix) && strlen($checkVersionSuffix)) { - //okay, here's where we do some crazy things... - $curVersionData = $this->parse_suffix($curVersionSuffix); - $checkVersionData = $this->parse_suffix($checkVersionSuffix); - - if($curVersionData['type'] == $checkVersionData['type']) { - //got the same suffix type (like "BETA"), check the number. - if($checkVersionData['number'] > $curVersionData['number']) { - //new version's suffix number higher than current... - $retval = TRUE; - } - elseif($checkVersionData['number'] == $curVersionData['number']) { - //new version's suffix number is EQUAL TO current... - $retval = FALSE; - } - else { - //new version's suffix number is LESS THAN current... - $retval = FALSE; - } - } - else { - //not the same suffix... see if the new one is higher. - $suffixValues = array_flip($this->suffixList); - if($suffixValues[$checkVersionData['type']] > $suffixValues[$curVersionData['type']]) { - $retval = TRUE; - } - else { - //current suffix type is higher... - } - } - - } - elseif(strlen($curVersionSuffix) && !strlen($checkVersionSuffix)) { - //i.e. "1.0.0-BETA1" to "1.0.0" --->>> OKAY! - $retval = TRUE; - } - elseif(!strlen($curVersionSuffix) && strlen($checkVersionSuffix)) { - //i.e. "1.0.0" to "1.0.0-BETA1" --->>> NOT ACCEPTABLE! - } - } - else { - //no suffix to care about - } - } - } - - return($retval); - - }//end is_higher_version() - //========================================================================= - - - - //========================================================================= - protected function parse_suffix($suffix) { - $retval = NULL; - if(strlen($suffix)) { - //determine what kind it is. - foreach($this->suffixList as $type) { - if(preg_match('/^'. $type .'/', $suffix)) { - $checkThis = preg_replace('/^'. $type .'/', '', $suffix); - if(strlen($checkThis) && is_numeric($checkThis)) { - //oooh... it's something like "BETA3" - $retval = array( - 'type' => $type, - 'number' => $checkThis - ); - } - else { - throw new exception(__METHOD__ .": invalid suffix (". $suffix .")"); - } - break; - } - } - } - else { - throw new exception(__METHOD__ .": invalid suffix (". $suffix .")"); - } - - return($retval); - }//end parse_suffix() - //========================================================================= - - -} -?> \ No newline at end of file Deleted: trunk/0.3/cs_webapplibs.abstract.class.php =================================================================== --- trunk/0.3/cs_webapplibs.abstract.class.php 2009-08-20 15:52:11 UTC (rev 121) +++ trunk/0.3/cs_webapplibs.abstract.class.php 2009-08-20 16:21:45 UTC (rev 122) @@ -1,20 +0,0 @@ -<?php -/* - * Created on Aug 19, 2009 - * - * SVN INFORMATION::: - * ------------------- - * Last Author::::::::: $Author$ - * Current Revision:::: $Revision$ - * Repository Location: $HeadURL$ - * Last Updated:::::::: $Date$ - */ - -require_once(dirname(__FILE__) .'/cs_version.abstract.class.php'); - - -abstract class cs_webapplibsAbstract extends cs_versionAbstract { - -} - -?> Modified: trunk/0.3/cs_webdblogger.class.php =================================================================== --- trunk/0.3/cs_webdblogger.class.php 2009-08-20 15:52:11 UTC (rev 121) +++ trunk/0.3/cs_webdblogger.class.php 2009-08-20 16:21:45 UTC (rev 122) @@ -27,7 +27,7 @@ //NOTE::: this class **REQUIRES** cs-content for its "cs_phpDB" class. -require_once(dirname(__FILE__) .'/cs_webapplibs.abstract.class.php'); +require_once(dirname(__FILE__) .'/abstract/cs_webapplibs.abstract.class.php'); require_once(dirname(__FILE__) .'/cs_webdbupgrade.class.php'); class cs_webdblogger extends cs_webapplibsAbstract { Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2009-08-20 15:52:11 UTC (rev 121) +++ trunk/0.3/cs_webdbupgrade.class.php 2009-08-20 16:21:45 UTC (rev 122) @@ -12,7 +12,7 @@ * */ -require_once(dirname(__FILE__) .'/cs_webapplibs.abstract.class.php'); +require_once(dirname(__FILE__) .'/abstract/cs_webapplibs.abstract.class.php'); require_once(dirname(__FILE__) .'/cs_webdblogger.class.php'); class cs_webdbupgrade extends cs_webapplibsAbstract { Deleted: trunk/0.3/tests/files/version1 =================================================================== --- trunk/0.3/tests/files/version1 2009-08-20 15:52:11 UTC (rev 121) +++ trunk/0.3/tests/files/version1 2009-08-20 16:21:45 UTC (rev 122) @@ -1,3 +0,0 @@ - -PROJECT: test1 -VERSION: 0.1.2-ALPHA8754 \ No newline at end of file Deleted: trunk/0.3/tests/files/version2 =================================================================== --- trunk/0.3/tests/files/version2 2009-08-20 15:52:11 UTC (rev 121) +++ trunk/0.3/tests/files/version2 2009-08-20 16:21:45 UTC (rev 122) @@ -1,3 +0,0 @@ - -PROJECT: test2 -VERSION: 5.4 \ No newline at end of file Deleted: trunk/0.3/tests/files/version3 =================================================================== --- trunk/0.3/tests/files/version3 2009-08-20 15:52:11 UTC (rev 121) +++ trunk/0.3/tests/files/version3 2009-08-20 16:21:45 UTC (rev 122) @@ -1,3 +0,0 @@ - -PROJECT: test3 stuff -VERSION: 5.4.3-BETA5543 \ No newline at end of file Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-20 15:52:11 UTC (rev 121) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-20 16:21:45 UTC (rev 122) @@ -11,7 +11,6 @@ * $LastChangedRevision$ */ -require_once(dirname(__FILE__) .'/../cs_version.abstract.class.php'); require_once(dirname(__FILE__) .'/../cs_authToken.class.php'); class testOfCSWebAppLibs extends UnitTestCase { @@ -24,108 +23,8 @@ //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - function test_version_basics() { - - $tests = array( - 'files/version1' => array( - '0.1.2-ALPHA8754', - 'test1', - array( - 'version_major' => 0, - 'version_minor' => 1, - 'version_maintenance' => 2, - 'version_suffix' => 'ALPHA8754' - ) - ), - 'files/version2' => array( - '5.4.0', - 'test2', - array( - 'version_major' => 5, - 'version_minor' => 4, - 'version_maintenance' => 0, - 'version_suffix' => null - ) - ), - 'files/version3' => array( - '5.4.3-BETA5543', - 'test3 stuff', - array( - 'version_major' => 5, - 'version_minor' => 4, - 'version_maintenance' => 3, - 'version_suffix' => 'BETA5543' - ) - ) - ); - - foreach($tests as $fileName=>$expectedArr) { - $ver = new middleTestClass(); - $ver->set_version_file_location(dirname(__FILE__) .'/'. $fileName); - - $this->assertEqual($expectedArr[0], $ver->get_version(), "Failed to match string from file (". $fileName .")"); - $this->assertEqual($expectedArr[1], $ver->get_project(), "Failed to match project from file (". $fileName .")"); - - //now check that pulling the version as an array is the same... - $checkItArr = $ver->get_version(true); - $expectThis = $expectedArr[2]; - $expectThis['version_string'] = $expectedArr[0]; - } - }//end test_version_basics() - //-------------------------------------------------------------------------- - - //-------------------------------------------------------------------------- - function test_check_higher() { - - //NOTE: the first item should ALWAYS be higher. - $tests = array( - 'basic, no suffix' => array('1.0.1', '1.0.0'), - 'basic + suffix' => array('1.0.0-ALPHA1', '1.0.0-ALPHA0'), - 'basic w/o maint' => array('1.0.1', '1.0'), - 'suffix check' => array('1.0.0-BETA1', '1.0.0-ALPHA1'), - 'suffix check2' => array('1.0.0-ALPHA10', '1.0.0-ALPHA1'), - 'suffix check3' => array('1.0.1', '1.0.0-RC1') - ); - - foreach($tests as $name=>$checkData) { - $ver = new middleTestClass; - $this->assertTrue($ver->is_higher_version($checkData[1], $checkData[0])); - $this->assertFalse($ver->is_higher_version($checkData[0], $checkData[1])); - } - - //now check to ensure there's no problem with parsing equivalent versions. - $tests = array( - 'no suffix' => array('1.0', '1.0.0'), - 'no maint + suffix' => array('1.0-ALPHA1', '1.0.0-ALPHA1'), - 'no maint + BETA' => array('1.0-BETA5555', '1.0.0-BETA5555'), - 'no maint + RC' => array('1.0-RC33', '1.0.0-RC33'), - 'maint with space' => array('1.0-RC 33', '1.0.0-RC33'), - 'extra spaces' => array(' 1.0 ', '1.0.0') - ); - foreach($tests as $name=>$checkData) { - $ver = new middleTestClass; - - //rip apart & recreate first version to test against the expected... - $derivedFullVersion = $ver->build_full_version_string($ver->parse_version_string($checkData[0])); - $this->assertEqual($derivedFullVersion, $checkData[1], "TEST=(". $name ."): derived version " . - "(". $derivedFullVersion .") doesn't match expected (". $checkData[1] .")"); - - //now rip apart & recreate the expected version (second) and make sure it matches itself. - $derivedFullVersion = $ver->build_full_version_string($ver->parse_version_string($checkData[1])); - $this->assertEqual($derivedFullVersion, $checkData[1], "TEST=(". $name ."): derived version " . - "(". $derivedFullVersion .") doesn't match expected (". $checkData[1] .")"); - } - - - }//end test_check_higher() - //-------------------------------------------------------------------------- - - - - //-------------------------------------------------------------------------- private function create_dbconn() { $dbParams = array( 'host' => constant('DB_PG_HOST'), @@ -249,10 +148,6 @@ } -class middleTestClass extends cs_versionAbstract { - function __construct(){} -} - class authTokenTester extends cs_authToken { public $isTest=true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-20 18:47:12
|
Revision: 125 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=125&view=rev Author: crazedsanity Date: 2009-08-20 18:47:04 +0000 (Thu, 20 Aug 2009) Log Message: ----------- Make hash unguessable. NOTE::: the last commit missed cs_authToken.class.php, so this looks a bit like a duplicate. NOTE2:: the hash could be encrypted using SHA-1, using the function sha1(), though this would possibly hinder using it for cs_sessionDB{}...? /cs_authToken.class.php: * create_token(): -- add microtime() and a random number to the hash string for better unguessability. * authenticate_token(): -- check length of the array from get_token_data(), and make sure the checksums match (the checksum match was incomplete, must've been distracted or something). * get_token_data(): -- remove initial index (of $tokenId) for simpler checking. -- add exception if the $tokenId index isn't there. /tests/testOfCSWebAppLibs.php: * test_token_basics(): -- test to ensure the token's hash isn't guessable. * authTokenTester::doHash() [NEW]: -- calls cs_authToken::create_hash_string(). Modified Paths: -------------- trunk/0.3/cs_authToken.class.php trunk/0.3/tests/testOfCSWebAppLibs.php Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-20 18:15:30 UTC (rev 124) +++ trunk/0.3/cs_authToken.class.php 2009-08-20 18:47:04 UTC (rev 125) @@ -103,6 +103,7 @@ $tokenId = $this->db->run_insert($sql, $this->seq); //now that we have the ID, let's create the real has string. + $stringToHash .= microtime(true) ."__". rand(1000, 9999999); $finalHash = $this->create_hash_string($tokenId, $uid, $checksum, $stringToHash); $this->_generic_update($tokenId, "token='". $finalHash ."'"); @@ -199,10 +200,9 @@ try { $data = $this->get_token_data($tokenId); - if(count($data) == 1 && isset($data[$tokenId]) && is_array($data[$tokenId])) { - $data = $data[$tokenId]; + if(count($data) == 9 && is_array($data) && isset($data['auth_token_id'])) { - if($data['token'] == $hash && $data['checksum']) { + if($data['token'] == $hash && $data['checksum'] == $checksum) { $methodCall = 'update_token_uses'; if(is_numeric($data['max_uses'])) { @@ -265,7 +265,12 @@ $data = $this->db->run_query($sql, 'auth_token_id'); if(is_array($data) && count($data) == 1) { - $tokenData = $data; + if(isset($data[$tokenId])) { + $tokenData = $data[$tokenId]; + } + else { + throw new exception("missing sub-array for tokenId (". $tokenId .")"); + } } elseif($data === false) { $tokenData = false; Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-20 18:15:30 UTC (rev 124) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-20 18:47:04 UTC (rev 125) @@ -165,6 +165,19 @@ $this->assertEqual($uniq, ($numTests -1)); } } + + //make sure the hash string isn't guessable, even if they can access our super-secret encryption algorithm. ;) + { + $uid = rand(1,99999); + $checksum = "my birfday"; + $hashThis = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque ut."; + + $tokenData = $tok->create_token($uid, $checksum, $hashThis); + $this->basic_token_tests($tokenData, $uid, $checksum); + + $this->assertNotEqual($tokenData['hash'], $tok->doHash($tokenData['id'], $uid, $checksum, $hashThis), + "hash is guessable"); + } }//end test_token_basics() //-------------------------------------------------------------------------- @@ -194,5 +207,8 @@ public function tokenData($id, $onlyNonExpired=true) { return($this->get_token_data($id, $onlyNonExpired)); } + public function doHash($tokenId, $uid, $checksum, $hash) { + return($this->create_hash_string($tokenId, $uid, $checksum, $hash)); + } } ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-20 19:04:46
|
Revision: 126 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=126&view=rev Author: crazedsanity Date: 2009-08-20 19:04:39 +0000 (Thu, 20 Aug 2009) Log Message: ----------- Convert to sha-1 hashes for better security. /cs_authToken.class.php: * create_hash_string(): -- use sha1() instead of md5(). * authenticate_token(): -- test that the hash is 40 characters (sha-1) instead of 32 (md5) /tests/testOfCSWebAppLibs.php: * basic_token_tests(): -- test that the hash is 40 characters (sha-1) instead of 32 (md5) Modified Paths: -------------- trunk/0.3/cs_authToken.class.php trunk/0.3/tests/testOfCSWebAppLibs.php Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-20 18:47:04 UTC (rev 125) +++ trunk/0.3/cs_authToken.class.php 2009-08-20 19:04:39 UTC (rev 126) @@ -61,7 +61,7 @@ * something very unique. */ protected function create_hash_string($tokenId, $uid, $checksum, $stringToHash=NULL) { - return(md5($tokenId ."_". $uid ."_". $checksum ."_". $stringToHash)); + return(sha1($tokenId ."_". $uid ."_". $checksum ."_". $stringToHash)); }//end create_hash_string() //========================================================================= @@ -196,7 +196,7 @@ $authTokenRes = null; - if(is_numeric($tokenId) && strlen($checksum) && strlen($hash) == 32) { + if(is_numeric($tokenId) && strlen($checksum) && strlen($hash) == 40) { try { $data = $this->get_token_data($tokenId); Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-20 18:47:04 UTC (rev 125) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-20 19:04:39 UTC (rev 126) @@ -193,7 +193,7 @@ $this->assertTrue(isset($tokenData['id'])); $this->assertTrue(isset($tokenData['hash'])); $this->assertTrue(($tokenData['id'] > 0)); - $this->assertTrue((strlen($tokenData['hash']) == 32)); + $this->assertTrue((strlen($tokenData['hash']) == 40)); } }//end basic_token_tests() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-20 20:39:44
|
Revision: 127 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=127&view=rev Author: crazedsanity Date: 2009-08-20 20:39:35 +0000 (Thu, 20 Aug 2009) Log Message: ----------- All webapp-related items moved here from cs-content... NOTE::: nearly all files now have the "svn:keywords" property set. NOTE2:: this is done to facilitate much faster changes to cs-content. While it may slow development of cs-webapplibs, there is also a lot of work being done to build unit tests there: this should hopefully avoid unexpected breakage in code during upgrades. This also makes upgrading of the database-reliant stuff (like cs_phpDB) to be more easily upgraded. CODE MOVED FROM cs-content::: * /cs_bbCodeParser.class.php * /cs_phpDB.class.php (including db_types & abstract) * /cs_sessionDB.class.php (including schema files) * /cs_siteConfig.class.php * /cs_tabs.class.php * /abstract/cs_phpDB.abstract.class.php * /tests/testOfCSPHPDB.php CHANGED REQUIRE_ONCE PATHS::: * /contentSystem.class.php (cs_sessionDB) MISC::: * /contentSystem.class.php: -- MAIN::: don't require cs_tabs -- initialize_locals(): drop cs_tabs stuff (unneeded) Modified Paths: -------------- trunk/0.3/cs_webdbupgrade.class.php Added Paths: ----------- trunk/0.3/abstract/cs_phpDB.abstract.class.php trunk/0.3/cs_bbCodeParser.class.php trunk/0.3/cs_phpDB.class.php trunk/0.3/cs_sessionDB.class.php trunk/0.3/cs_siteConfig.class.php trunk/0.3/cs_tabs.class.php trunk/0.3/db_types/ trunk/0.3/db_types/cs_phpDB__mysql.class.php trunk/0.3/db_types/cs_phpDB__pgsql.class.php trunk/0.3/db_types/cs_phpDB__sqlite.class.php trunk/0.3/setup/db_session_schema.mysql.sql trunk/0.3/setup/db_session_schema.pgsql.sql trunk/0.3/tests/testOfCSPHPDB.php Property Changed: ---------------- trunk/0.3/docs/CREDITS trunk/0.3/docs/LICENSE trunk/0.3/docs/README.txt trunk/0.3/docs/SETUP.txt trunk/0.3/tests/example_test.php trunk/0.3/tests/testOfCSWebAppLibs.php Added: trunk/0.3/abstract/cs_phpDB.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_phpDB.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_phpDB.abstract.class.php 2009-08-20 20:39:35 UTC (rev 127) @@ -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 Property changes on: trunk/0.3/abstract/cs_phpDB.abstract.class.php ___________________________________________________________________ Added: svn:keywords + Id Author Revision HeadURL Date Added: trunk/0.3/cs_bbCodeParser.class.php =================================================================== --- trunk/0.3/cs_bbCodeParser.class.php (rev 0) +++ trunk/0.3/cs_bbCodeParser.class.php 2009-08-20 20:39:35 UTC (rev 127) @@ -0,0 +1,165 @@ +<?php +/** + * Created on 2007-09-26 + * + * + * SVN INFORMATION::: + * ------------------ + * SVN Signature::::::: $Id$ + * Last Author::::::::: $Author$ + * Current Revision:::: $Revision$ + * Repository Location: $HeadURL$ + * Last Updated:::::::: $Date$ + * + * + * Originally from a snippet (just the function) on PHPFreaks.com: http://www.phpfreaks.com/quickcode/BBCode/712.php + * The original code had parse errors, so it had to be fixed... While it was posted as just a basic function, + * the code within (such as the reference to "$this->bbCodeData" indicated it was from a class... so it has + * been converted. + */ + +require_once(dirname(__FILE__) ."/abstract/cs_webapplibs.abstract.class.php"); + +class cs_bbCodeParser extends cs_contentAbstract { + + /** Array containing all the codes & how to parse them. */ + private $bbCodeData = NULL; + + //========================================================================= + /** + * Setup internal structures. + */ + function __construct() { + parent::__construct(false); + # Which BBCode is accepted here + $this->bbCodeData = array( + 'bold' => array( + 'start' => array('[b]', '\[b\](.*)', '<b>\\1'), + 'end' => array('[/b]', '\[\/b\]', '</b>'), + ), + + 'underline' => array( + 'start' => array('[u]', '\[u\](.*)', '<u>\\1'), + 'end' => array('[/u]', '\[\/u\]', '</u>'), + ), + + 'italic' => array( + 'start' => array('[i]', '\[i\](.*)', '<i>\\1'), + 'end' => array('[/i]', '\[\/i\]', '</i>'), + ), + + 'image' => array( + 'start' => array('[img]', '\[img\](http:\/\/|https:\/\/|ftp:\/\/|\/)(.*)(.jpg|.jpeg|.bmp|.gif|.png)', '<img src=\'\\1\\2\\3\' />'), + 'end' => array('[/img]', '\[\/img\]', ''), + ), + + # [url]http://x.com[/url] + 'url1' => array( + 'start' => array('[url]', '\[url\](http:\/\/|https:\/\/|ftp:\/\/)(.*)', '<a target="_blank" href=\'\\1\\2\'>\\1\\2'), + 'end' => array('[/url]', '\[\/url\]', '</a>'), + ), + + # [url=http://x.com]stuff[/url] + 'url2' => array( + 'start' => array('[url]', '\[url=(http:\/\/|https:\/\/|ftp:\/\/)(.*)\](.*)', '<a target="_blank" href=\'\\1\\2\'>\\3'), + 'end' => array('[/url]', '\[\/url\]', '</a>'), + ), + + 'code' => array( + 'start' => array('[code]', '\[code\](.*)', '<br /><br /><b>CODE</b>:<div class="code">\\1'), + 'end' => array('[/code]', '\[\/code\]', '</div><br />'), + ), + ); + }//end __construct() + //========================================================================= + + + + //========================================================================= + /** + * Ensure the object is initialized properly, throw exception if not. + */ + private function isInitialized() { + if(!is_array($this->bbCodeData) || !count($this->bbCodeData)) { + throw new exception(__METHOD__ .": BBCode array not initialized"); + } + }//end isInitialized() + //========================================================================= + + + + //========================================================================= + /** + * Parse BBCode from the given string & return it with formatting. + */ + function parseString($data, $newlines2BR=FALSE) { + if(is_string($data) && strlen($data) > 10) { + $this->isInitialized(); + $data = str_replace("\n", '||newline||', $data); + + foreach( $this->bbCodeData as $k => $v ) { + if(isset($this->bbCodeData[$k]['special'])) { + $myMatches = array(); + $regex = '/'. $this->bbCodeData[$k]['start'][1] . $this->bbCodeData[$k]['end'][1] .'/'; + $x = preg_match_all($regex .'U', $data, $myMatches); + + if(count($myMatches[1])) { + $funcName = $v['special']; + $myArgs = $myMatches[1]; + $myArgs = array_unique($myArgs); + + foreach($myArgs as $index=>$value) { + $showThis = $this->$funcName($value); + $replaceThis = str_replace(array('[', ']'), array('\\[', '\\]'), $myMatches[0][$index]); + $data = preg_replace('/'. $replaceThis .'/U', $showThis, $data); + } + } + } + else { + $data = preg_replace("/".$this->bbCodeData[$k]['start'][1].$this->bbCodeData[$k]['end'][1]."/U", $this->bbCodeData[$k]['start'][2].$this->bbCodeData[$k]['end'][2], $data); + } + } + + $replaceNewlineStr = "\n"; + if($newlines2BR) { + $replaceNewlineStr = "<br />\n"; + } + $data = str_replace('||newline||', $replaceNewlineStr, $data); + + } + return $data; + }//end parseString() + //========================================================================= + + + + //========================================================================= + /** + * Enables extending classes to register a bbCode with special parsing. + * + * NOTE: right now, this will only handle syntax like "[{bbCodeString}={arg}]". + */ + protected function register_code_with_callback($bbCodeString, $method) { + + if(method_exists($this, $method)) { + $this->bbCodeData[$bbCodeString] = array( + 'special' => $method, + 'start' => array( + '['. $bbCodeString .']', + '\['. $bbCodeString .'=(.*)' + ), + 'end' => array( + '', + '\]' + ) + ); + } + else { + throw new exception(__METHOD__ .": method (". $method .") doesn't exist"); + } + + }//end register_code_with_callback() + //========================================================================= + +} +?> Property changes on: trunk/0.3/cs_bbCodeParser.class.php ___________________________________________________________________ Added: svn:keywords + Id Author Revision HeadURL Date Added: trunk/0.3/cs_phpDB.class.php =================================================================== --- trunk/0.3/cs_phpDB.class.php (rev 0) +++ trunk/0.3/cs_phpDB.class.php 2009-08-20 20:39:35 UTC (rev 127) @@ -0,0 +1,197 @@ +<?php + +/* + * A class for generic PostgreSQL database access. + * + * SVN INFORMATION::: + * SVN Signature:::::::: $Id$ + * 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. +// +/////////////////////// + +require_once(dirname(__FILE__) ."/abstract/cs_webapplibs.abstract.class.php"); +require_once(dirname(__FILE__) ."/abstract/cs_phpDB.abstract.class.php"); + +class cs_phpDB extends cs_contentAbstract { + + private $dbLayerObj; + private $dbType; + public $connectParams = array(); + + //========================================================================= + public function __construct($type='pgsql') { + + if(strlen($type)) { + + require_once(dirname(__FILE__) .'/db_types/'. __CLASS__ .'__'. $type .'.class.php'); + $className = __CLASS__ .'__'. $type; + $this->dbLayerObj = new $className; + $this->dbType = $type; + + parent::__construct(); + + $this->isInitialized = TRUE; + } + else { + throw new exception(__METHOD__ .": failed to give a type (". $type .")"); + } + }//end __construct() + //========================================================================= + + + + //========================================================================= + /** + * Magic method to call methods within the database abstraction layer ($this->dbLayerObj). + */ + public function __call($methodName, $args) { + if(method_exists($this->dbLayerObj, $methodName)) { + if($methodName == 'connect' && is_array($args[0])) { + //capture the connection parameters. + $this->connectParams = $args[0]; + } + $retval = call_user_func_array(array($this->dbLayerObj, $methodName), $args); + } + else { + throw new exception(__METHOD__ .': unsupported method ('. $methodName .') for database of type ('. $this->dbType .')'); + } + return($retval); + }//end __call() + //========================================================================= + + + + //========================================================================= + public function get_dbtype() { + return($this->dbType); + }//end get_dbtype() + //========================================================================= + + + + //========================================================================= + /** + * Performs queries which require results. Passing $indexField returns a + * complex array indexed from that field; passing $valueField will change + * it to a name=>value formatted array. + * + * NOTE:: when using an index field, be sure it is guaranteed to be unique, + * i.e. it is a primary key! If duplicates are found, the database class + * will throw an exception! + */ + public function run_query($sql, $indexField=null, $valueField=null) { + + $retval = array(); + + //length must be 19 as that's about the shortest valid SQL: "select * from table" + if(strlen($sql) >= 19) { + $this->exec($sql); + + $numRows = $this->numRows(); + $dbError = $this->errorMsg(); + if($numRows > 0 && !strlen($dbError)) { + if(strlen($indexField) && (is_null($valueField) || !strlen($valueField))) { + //return a complex array based on a given field. + $retval = $this->farray_fieldnames($indexField, null, 0); + } + elseif(strlen($indexField) && strlen($valueField)) { + //return an array as name=>value pairs. + $retval = $this->farray_nvp($indexField, $valueField); + } + else { + $retval = $this->farray_fieldnames(); + } + } + elseif($numRows == 0 && !strlen($dbError)) { + $retval = false; + } + else { + throw new exception(__METHOD__ .": no rows (". $numRows .") or dbError::: ". $dbError ."<BR>\nSQL::: ". $sql); + } + } + else { + throw new exception(__METHOD__ .": invalid length SQL (". $sql .")"); + } + + return($retval); + }//end run_query() + //========================================================================= + + + + //========================================================================= + /** + * Handles performing the insert statement & returning the last inserted ID. + */ + public function run_insert($sql, $sequence='null') { + + $this->exec($sql); + + if($this->numAffected() == 1 && !strlen($this->errorMsg())) { + //retrieve the ID just created. + $retval = $this->lastID($sequence); + } + else { + //something broke... + throw new exception(__METHOD__ .": failed to insert, rows=(". $this->numRows .")... " + ."ERROR::: ". $this->errorMsg() ."\n -- SQL:::: ". $sql); + } + + return($retval); + }//end run_insert() + //========================================================================= + + + + //========================================================================= + /** + * Performs the update & returns how many rows were affected. + */ + public function run_update($sql, $zeroIsOk=false) { + $this->exec($sql); + + $dberror = $this->errorMsg(); + $numAffected = $this->numAffected(); + + if(strlen($dberror)) { + throw new exception(__METHOD__ .": error while running update::: ". $dberror ." -- SQL::: ". $sql); + } + elseif($numAffected==0 && $zeroIsOk == false) { + throw new exception(__METHOD__ .": no rows updated (". $numAffected ."), SQL::: ". $sql); + } + + return($numAffected); + }//end run_update() + //========================================================================= + + + + //========================================================================= + public function reconnect() { + if(is_array($this->connectParams) && count($this->connectParams)) { + $this->dbLayerObj->connect($this->connectParams, true); + } + else { + throw new exception(__METHOD__ .": no connection parameters stored"); + } + }//end reconnect() + //========================================================================= + +} // end class phpDB + +?> Property changes on: trunk/0.3/cs_phpDB.class.php ___________________________________________________________________ Added: svn:keywords + Id Author Revision HeadURL Date Added: trunk/0.3/cs_sessionDB.class.php =================================================================== --- trunk/0.3/cs_sessionDB.class.php (rev 0) +++ trunk/0.3/cs_sessionDB.class.php 2009-08-20 20:39:35 UTC (rev 127) @@ -0,0 +1,366 @@ +<?php +/* + * FILE INFORMATION: + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +require_once(constant('LIBDIR') .'/cs-content/cs_session.class.php'); +require_once(dirname(__FILE__) .'/cs_phpDB.class.php'); +require_once(constant('LIBDIR') .'/cs-phpxml/cs_arrayToPath.class.php'); +require_once(constant('LIBDIR') .'/cs-webapplibs/cs_webdblogger.class.php'); + +class cs_sessionDB extends cs_session { + + protected $db; + + protected $logger = null; + + protected $logCategory = "DB Sessions"; + + //------------------------------------------------------------------------- + /** + * The constructor. + * + * @param $createSession (mixed,optional) determines if a session will be started or not; if + * this parameter is non-null and non-numeric, the value will be + * used as the session name. + */ + function __construct() { + + + //map some constants to connection parameters. + //NOTE::: all constants should be prefixed... + $constantPrefix = 'SESSION_DB_'; + $params = array('host', 'port', 'dbname', 'user', 'password'); + foreach($params as $name) { + $value = null; + $constantName = $constantPrefix . strtoupper($name); + if(defined($constantName)) { + $value = constant($constantName); + } + $dbParams[$name] = $value; + } + $this->db = new cs_phpDB(constant('DBTYPE')); + $this->db->connect($dbParams); + + $this->tableName = 'cs_session_store_table'; + $this->tablePKey = 'session_store_id'; + $this->sequenceName = 'cs_session_store_table_session_store_id_seq'; + + if(!$this->sessdb_table_exists()) { + $this->load_table(); + } + + //now tell PHP to use this class's methods for saving the session. + session_set_save_handler( + array(&$this, 'sessdb_open'), + array(&$this, 'sessdb_close'), + array(&$this, 'sessdb_read'), + array(&$this, 'sessdb_write'), + array(&$this, 'sessdb_destroy'), + array(&$this, 'sessdb_gc') + ); + + //NOTE::: calling session_id() here, prior to parent's construct, can set a specific session_id; if + // something like cs_authToken (part of cs-webapplibs project) were used, just call + // cs_authToken::create_token() here... + + parent::__construct(true); + + //Stop things from going into an audit log... see + //http://www.developertutorials.com/tutorials/php/saving-php-session-data-database-050711/page3.html + // NOTE::: not sure if this is valid or not... + $this->audit_logging = false; + + }//end __construct() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + /** + * Determines if the appropriate table exists in the database. + */ + public function sessdb_table_exists() { + try { + $test = $this->db->run_query("SELECT * FROM ". $this->tableName . + " ORDER BY ". $this->tablePKey ." LIMIT 1"); + $exists = true; + } + catch(exception $e) { + $this->exception_handler(__METHOD__ .": exception while trying to detect table::: ". $e->getMessage()); + $exists = false; + } + + return($exists); + }//end sessdb_table_exists() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + private function load_table() { + $filename = dirname(__FILE__) .'/schema/db_session_schema.'. $this->db->get_dbtype() .'.sql'; + if(file_exists($filename)) { + try { + $this->db->run_update(file_get_contents($filename),true); + } + catch(exception $e) { + $this->exception_handler(__METHOD__ .": failed to load required table " . + "into your database automatically::: ". $e->getMessage(), true); + } + } + else { + $this->exception_handler(__METHOD__ .": while attempting to load required " . + "table into your database, discovered you have a missing schema " . + "file (". $filename .")", true); + } + }//end load_table() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + protected function is_valid_sid($sid) { + $isValid = false; + if(strlen($sid) == 32) { + try { + $sql = "SELECT * FROM ". $this->tableName ." WHERE session_id='". + $sid ."'"; + $this->db->run_query($sql); + $numrows = $this->db->numRows(); + if($numrows == 1) { + $isValid = true; + } + elseif($numrows > 0 || $numrows < 0) { + $this->exception_handler(__METHOD__ .": invalid numrows returned (". $numrows .")",true); + } + } + catch(exception $e) { + //well... do nothing I guess. + } + } + + return($isValid); + }//end is_valid_sid() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + /** + * Open the session (doesn't really do anything) + */ + public function sessdb_open($savePath, $sessionName) { + return(true); + }//end sessdb_open() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + /** + * Close the session (call the "gc" method) + */ + public function sessdb_close() { + return($this->sessdb_gc(0)); + }//end sessdb_close() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + /** + * Read information about the session. If there is no data, it MUST return + * an empty string instead of NULL. + */ + public function sessdb_read($sid) { + $retval = ''; + try { + $sql = "SELECT * FROM ". $this->tableName ." WHERE session_id='". + $sid ."'"; + $data = $this->db->run_query($sql); + + if($this->db->numRows() == 1) { + $retval = $data['session_data']; + } + } + catch(exception $e) { + //no throwing exceptions... + $this->exception_handler(__METHOD__ .": failed to read::: ". $e->getMessage()); + } + return($retval); + }//end sessdb_read() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function sessdb_write($sid, $data) { + $data = array( + 'session_data' => $data, + 'user_id' => null + ); + $cleanString = array( + 'session_data' => 'sql', + 'user_id' => 'numeric' + ); + + + + //pull the uid out of the session... + if(defined('SESSION_DBSAVE_UIDPATH')) { + $a2p = new cs_arrayToPath($_SESSION); + $uidVal = $a2p->get_data(constant('SESSION_DBSAVE_UIDPATH')); + + if(is_string($uidVal) || is_numeric($uidVal)) { + $data['user_id'] = $uidVal; + } + } + + $afterSql = ""; + if($this->is_valid_sid($sid)) { + $type = 'update'; + $sql = "UPDATE ". $this->tableName ." SET "; + $afterSql = "WHERE session_id='". $sid ."'"; + $data['last_updated'] = 'NOW()'; + $secondArg = false; + } + else { + $type = 'insert'; + $sql = "INSERT INTO ". $this->tableName ." "; + $data['session_id'] = $sid; + $secondArg = $this->sequenceName; + } + + $sql .= $this->gfObj->string_from_array($data, $type, null, $cleanString) .' '. $afterSql; + try { + $funcName = 'run_'. $type; + $res = $this->db->$funcName($sql, $secondArg); + } + catch(exception $e) { + //umm... yeah. + $this->exception_handler(__METHOD__ .": failed to perform action (". $type .")::: ". $e->getMessage()); + } + + return(true); + }//end sessdb_write() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function sessdb_destroy($sid) { + try { + $sql = "DELETE FROM ". $this->tableName ." WHERE session_id='". $sid ."'"; + $numDeleted = $this->db->run_update($sql, true); + + if($numDeleted > 0) { + $this->do_log("Destroyed session_id (". $sid .")", 'deleted'); + } + } + catch(exception $e) { + //do... nothing? + } + return(true); + }//end sessdb_destroy() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + /** + * Define maximum lifetime (in seconds) to store sessions in the database. + * Anything that is older than that time will be purged (gc='garbage collector'). + */ + public function sessdb_gc($maxLifetime=null) { + + $dateFormat = 'Y-m-d H:i:s'; + $strftimeFormat = '%Y-%m-%d %H:%M:%S'; + $nowTime = date($dateFormat); + $excludeCurrent = true; + if(defined('SESSION_MAX_TIME') || defined('SESSION_MAX_IDLE')) { + $maxFreshness = null; + if(defined('SESSION_MAX_TIME')) { + $date = strtotime('- '. constant('SESSION_MAX_TIME')); + $maxFreshness = "date_created < '". strftime($strftimeFormat, $date) ."'"; + $excludeCurrent=false; + } + if(defined('SESSION_MAX_IDLE')) { + + $date = strtotime('- '. constant('SESSION_MAX_IDLE')); + $addThis = "last_updated < '". strftime($strftimeFormat, $date) ."'"; + $maxFreshness = $this->gfObj->create_list($maxFreshness, $addThis, ' OR '); + } + } + elseif(is_null($maxLifetime) || !is_numeric($maxLifetime) || $maxLifetime <= 0) { + //pull it from PHP's ini settings. + $maxLifetime = ini_get("session.gc_maxlifetime"); + $interval = $maxLifetime .' seconds'; + + $dt1 = strtotime($nowTime .' - '. $interval); + $maxFreshness = "last_updated < '". date($dateFormat, $dt1) ."'"; + } + + + + try { + //destroy old sessions, but don't complain if nothing is deleted. + $sql = "DELETE FROM ". $this->tableName ." WHERE ". $maxFreshness; + if(strlen($this->sid) && $excludeCurrent === false) { + $sql .= " AND session_id != '". $this->sid ."'"; + } + $numCleaned = $this->db->run_update($sql, true); + + if($numCleaned > 0) { + $this->do_log("cleaned (". $numCleaned .") old sessions, " . + "excludeCurrent=(". $this->gfObj->interpret_bool($excludeCurrent) .")" . + ", maxFreshness=(". $maxFreshness .")", "debug"); + } + } + catch(exception $e) { + $this->exception_handler(__METHOD__ .": exception while cleaning: ". $e->getMessage()); + } + + return(true); + + }//end sessdb_gc() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + protected function do_log($message, $type) { + + //check if the logger object has been created. + if(!is_object($this->logger)) { + $newDB = new cs_phpDB(constant('DBTYPE')); + $newDB->connect($this->db->connectParams, true); + $this->logger = new cs_webdblogger($newDB, $this->logCategory); + } + + return($this->logger->log_by_class("SID=(". $this->sid .") -- ". $message,$type)); + + }//end do_log() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + protected function exception_handler($message, $throwException=false) { + $logId = $this->do_log($message, 'exception in code'); + if($throwException === true) { + //in this class, it is mostly useless to throw exceptions, so by default they're not thrown. + throw new exception($message); + } + return($logId); + }//end exception_handler() + //------------------------------------------------------------------------- + + +}//end cs_session{} +?> \ No newline at end of file Property changes on: trunk/0.3/cs_sessionDB.class.php ___________________________________________________________________ Added: svn:executable + * Added: svn:keywords + Id Author Revision HeadURL Date Added: trunk/0.3/cs_siteConfig.class.php =================================================================== --- trunk/0.3/cs_siteConfig.class.php (rev 0) +++ trunk/0.3/cs_siteConfig.class.php 2009-08-20 20:39:35 UTC (rev 127) @@ -0,0 +1,404 @@ +<?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-content/abstract/cs_content.abstract.class.php'); +require_once(dirname(__FILE__) .'/../cs-content/cs_fileSystem.class.php'); +require_once(dirname(__FILE__). '/../cs-phpxml/cs_phpxmlParser.class.php'); +require_once(dirname(__FILE__) .'/../cs-phpxml/cs_phpxmlBuilder.class.php'); + +class cs_siteConfig extends cs_contentAbstract { + + /** XMLParser{} object, for reading XML config file. */ + private $xmlReader; + + /** cs_fileSystem{} object, for writing/updating XML config file + * (only available if file is writable) + */ + private $xmlWriter; + + /** XMLBuilder{} object, for updating XML. */ + private $xmlBuilder; + + /** cs_fileSystem{} 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; + + /** Location of the configuration file itself. */ + private $configFile; + + /** 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; + + /** Store a list of items that need to be pushed into $GLOBALS on a given path. */ + private $setGlobalArrays=array(); + + //------------------------------------------------------------------------- + /** + * 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; + + parent::__construct(); + + if(strlen($configFileLocation) && file_exists($configFileLocation)) { + + $this->configDirname = dirname($configFileLocation); + $this->configFile = $configFileLocation; + $this->fs = new cs_fileSystem($this->configDirname); + + $this->xmlReader = new cs_phpxmlParser($this->fs->read($configFileLocation)); + + if($this->fs->is_writable($configFileLocation)) { + $this->readOnly = false; + $this->xmlWriter = new cs_fileSystem($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 = $this->build_special_vars(); + $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; + + unset($secData['type']); + + if(isset($secData['attributes']) && is_array($secData['attributes'])) { + $sectionAttribs = $secData['attributes']; + unset($secData['attributes']); + + //put stuff into the globals scope... + if(isset($sectionAttribs['SETGLOBAL'])) { + $path = $section; + + $setPath = $path; + if(strlen($sectionAttribs['GLOBALARRAYLOCATION'])) { + $setPath = $sectionAttribs['GLOBALARRAYLOCATION']; + } + $this->setGlobalArrays[$path] = $setPath; + } + } + + foreach($secData as $itemName=>$itemValue) { + $attribs = array(); + if(isset($itemValue['attributes']) && is_array($itemValue['attributes'])) { + $attribs = $itemValue['attributes']; + } + if(isset($itemValue['value'])) { + $itemValue = $itemValue['value']; + } + else { + $itemValue = null; + } + if(preg_match("/{/", $itemValue)) { + $origVal = $itemValue; + + //remove double-slashes (//) + $itemValue = preg_replace('/[\/]{2,}/', '\/', $itemValue); + + //remove leading slash for string replaces (i.e. "{/MAIN/SITE_ROOT}" becomes "{MAIN/SITE_ROOT}") + $itemValue = preg_replace('/{\//', '{', $itemValue); + + //replace special vars. + $itemValue = $this->gfObj->mini_parser($itemValue, $specialVars, '{', '}'); + + //replace internal vars. + $itemValue = $this->gfObj->mini_parser($itemValue, $parseThis, '{', '}'); + } + + if(isset($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(isset($attribs['SETGLOBAL'])) { + $GLOBALS[$setVarIndex] = $itemValue; + } + if(isset($attribs['SETCONSTANT'])) { + if(isset($attribs['SETCONSTANTPREFIX'])) { + //did they give a specific prefix, or just a number/true? + if(strlen($attribs['SETCONSTANTPREFIX']) == 1) { + $setVarIndex = $section ."-". $setVarIndex; + } + else { + //use the prefix they gave. + $setVarIndex = $attribs['SETCONSTANTPREFIX'] ."-". $setVarIndex; + } + } + if(!defined($setVarIndex)) { + define($setVarIndex, $itemValue); + } + } + } + } + } + + $this->a2p = new cs_arrayToPath($data); + $this->isInitialized=true; + + if(count($this->setGlobalArrays)) { + $globA2p = new cs_arrayToPath(&$GLOBALS); + foreach($this->setGlobalArrays as $configPath=>$globalsPath) { + if($this->a2p->get_data($configPath)) { + $setMe = array(); + foreach($this->a2p->get_data($configPath) as $i=>$v) { + $setMe[$i] = $v['value']; + } + $globA2p->set_data($globalsPath, $setMe); + } + else { + throw new exception(__METHOD__ .": attempted to set global array from non-existent path (". $configPath .")"); + } + } + } + } + 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) { + $section = strtoupper($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 (". $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() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + private function build_special_vars() { + //determine the current "APPURL" (current URL minus hostname and current filename) + { + $appUrl = $_SERVER['SCRIPT_NAME']; + $bits = explode('/', $appUrl); + if(!strlen($bits[0])) { + array_shift($bits); + } + if(count($bits)) { + array_pop($bits); + } + if(!count($bits)) { + $appUrl = '/'; + } + else { + $appUrl = '/'. $this->gfObj->string_from_array($bits, null, '/'); + } + } + + $specialVars = array( + '_DIRNAMEOFFILE_' => $this->configDirname, + '_CONFIGFILE_' => $this->configFile, + '_THISFILE_' => $this->configFile, + '_APPURL_' => $appUrl + ); + return($specialVars); + }//end build_special_vars() + //------------------------------------------------------------------------- + +}//end cs_siteConfig + +?> Property changes on: trunk/0.3/cs_siteConfig.class.php ___________________________________________________________________ Added: svn:keywords + Id Author Revision HeadURL Date Added: trunk/0.3/cs_tabs.class.php =================================================================== --- trunk/0.3/cs_tabs.class.php (rev 0) +++ trunk/0.3/cs_tabs.class.php 2009-08-20 20:39:35 UTC (rev 127) @@ -0,0 +1,175 @@ +<?php +/* + * Created on Jan 9, 2007 + * + */ + +require_once(dirname(__FILE__) .'/abstract/cs_content.abstract.class.php'); + + +class cs_tabs extends cs_contentAbstract { + private $tabsArr=array(); + private $selectedTab; + + private $templateVar; + private $gfObj; + + /** This is the default suffix to use when none is given during the add_tab() call. */ + private $defaultSuffix='tab'; + + //--------------------------------------------------------------------------------------------- + /** + * 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($templateVar="tabs") { + parent::__construct(false); + + if(is_object($templateVar)) { + //trying to pass cs_genericPage{}... tell 'em we don't like that anymore. + throw new exception(__METHOD__ .": got an object (". get_class($templateVar) .") instead of template var name"); + } + elseif(is_string($templateVar) && 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; + } + + $this->gfObj = new cs_globalFunctions; + }//end __construct() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + public function add_tab_array(array $tabs, $useSuffix=null) { + $retval = 0; + foreach($tabs as $name=>$url) { + //call an internal method to do it. + $retval += $this->add_tab($name, $url, $useSuffix); + } + + 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, $useSuffix=null) { + + //set the default suffix. + if(is_null($useSuffix)) { + $useSuffix = $this->defaultSuffix; + } + + //add it to an array. + $this->tabsArr[$tabName] = array( + 'url' => $url, + 'suffix' => $useSuffix + ); + }//end add_tab() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + /** + * Call this to add the parsed tabs into the page. + */ + public function display_tabs(array $blockRows) { + + if(!strlen($this->selectedTab)) { + $keys = array_keys($this->tabsArr); + $this->select_tab($keys[0]); + } + + if(is_array($this->tabsArr) && count($this->tabsArr)) { + $finalString = ""; + //loop through the array. + foreach($this->tabsArr as $tabName=>$tabData) { + + $url = $tabData['url']; + $suffix = $tabData['suffix']; + + $blockRowName = 'unselected_'. $suffix; + if(strtolower($tabName) == strtolower($this->selectedTab)) { + $blockRowName = 'selected_'. $suffix; + } + + if(isset($blockRows[$blockRowName])) { + $useTabContent = $blockRows[$blockRowName]; + } + else { + throw new exception(__METHOD__ ."(): failed to load block row " . + "(". $blockRowName .") for tab (". $tabName .")". + $this->gfObj->debug_print($blockRows,0)); + } + + $parseThis = array( + 'title' => $tabName, + 'url' => $url, + 'cleanTitle' => preg_replace('/[^a-zA-Z0-9]/', '_', $tabName) + ); + $finalString .= $this->gfObj->mini_parser($useTabContent, $parseThis, '%%', '%%'); + } + } + else { + //something bombed. + throw new exception(__METHOD__ ."(): no tabs to add"); + } + + return($finalString); + }//end display_tabs() + //--------------------------------------------------------------------------------------------- + + + //--------------------------------------------------------------------------------------------- + /** + * Determine if the given named tab exists (returns boolean true/false) + */ + public function tab_exists($tabName) { + $retval = false; + if(isset($this->tabsArr[$tabName])) { + $retval = true; + } + return($retval); + }//end tab_exists() + //--------------------------------------------------------------------------------------------- + + + + //--------------------------------------------------------------------------------------------- + public function rename_tab($tabName, $newTabName) { + if($this->tab_exists($tabName) && !$this->tab_exists($newTabName)) { + $tabContents = $this->tabsArr[$tabName]; + unset($this->tabsArr[$tabName]); + $this->tabsArr[$newTabName] = $tabContents; + } + else { + throw new exception(__METHOD__ .": tried to rename non-existent tab (". $tabName .") to (". $newTabName .")"); + } + }//end rename_tab(); + //--------------------------------------------------------------------------------------------- + +} +?> Property changes on: trunk/0.3/cs_tabs.class.php ___________________________________________________________________ Added: svn:keywords + Id Author Revision HeadURL Date Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2009-08-20 19:04:39 UTC (rev 126) +++ trunk/0.3/cs_webdbupgrade.class.php 2009-08-20 20:39:35 UTC (rev 127) @@ -13,7 +13,8 @@ */ require_once(dirname(__FILE__) .'/abstract/cs_webapplibs.abstract.class.php'); - require_once(dirname(__FILE__) .'/cs_webdblogger.class.php'); +require_once(dirname(__FILE__) .'/cs_webdblogger.class.php'); +require_once(dirname(__FILE__) .'/cs_phpDB.class.php'); class cs_webdbupgrade extends cs_webapplibsAbstract { @@ -88,7 +89,6 @@ require_once(constant('LIBDIR') .'/cs-content/cs_globalFunctions.class.php'); require_once(constant('LIBDIR') .'/cs-content/cs_fileSystem.class.php'); - require_once(constant('LIBDIR') .'/cs-content/cs_phpDB.class.php'); require_once(constant('LIBDIR') .'/cs-phpxml/cs_phpxmlParser.class.php'); require_once(constant('LIBDIR') .'/cs-phpxml/cs_phpxmlCreator.class.php'); require_once(constant('LIBDIR') .'/cs-phpxml/cs_arrayToPath.class.php'); Added: trunk/0.3/db_types/cs_phpDB__mysql.class.php =================================================================== --- trunk/0.3/db_types/cs_phpDB__mysql.class.php (rev 0) +++ trunk/0.3/db_types/cs_phpDB__mysql.class.php 2009-08-20 20:39:35 UTC (rev 127) @@ -0,0 +1,821 @@ +<?php + +/* + * A class for generic MySQL database access. + * + * SVN INFORMATION::: + * SVN Signature:::::::: $Id$ + * Last Committted Date: $Date$ + * Last Committed Path:: $HeadURL$ + * + */ + + +class cs_phpDB__mysql extends 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; + + //////////////////////////////////////////// + // Core primary connection/database function + //////////////////////////////////////////// + + + //========================================================================= + public function __construct() { + parent::__construct(); + }//end __construct() + //========================================================================= + + + + //========================================================================= + /** + * Set appropriate parameters for database connection + */ + public function set_db_info(array $params){ + $this->sanity_check(); + $required = array('host', 'dbname', 'user', 'password'); + + $requiredCount = 0; + foreach($params as $index=>$value) { + if(property_exists($this, $index) && in_array($index, $required)) { + $this->$index = $value; + $requiredCount++; + } + else { + throw new exception(__METHOD__. ": property (". $index .") does " . + "not exist or isn't allowed"); + } + } + + if($requiredCount == count($required)) { + $this->paramsAreSet = TRUE; + } + else { + throw new exception(__METHOD__ .": required count (". $requiredCount + .") does not match required number of fields (". count($required) .")"); + } + }//end set_db_info() + //========================================================================= + + + + //========================================================================= + /** + * Standard method to close connection. + */ + function close() { + $this->isConnected = FALSE; + $retval = null; + if($this->connectionID != -1) { + $retval = mysql_close($this->connectionID); + $this->transStatus = null; + $this->inTrans=null; + $this->transactionTree=null; + } + else { + throw new exception(__METHOD__ .": Failed to close connection: connection is invalid"); + } + + return($retval); + }//end close() + //========================================================================= + + + + //========================================================================= + /** + * Connect to the database + */ + function connect(array $dbParams=NULL, $forceNewConnection=FALSE){ + $this->sanity_check(); + $retval = NULL; + if(is_array($dbParams)) { + $this->set_db_info($dbParams); + } + + if($this->paramsAreSet === TRUE) { + + //start output buffer for displaying error. + ob_start(); + $connID = mysql_connect($this->host, $this->user, $this->password, $forceNewConnection); + if(!$connID) { + $connectError = mysql_error(); + } + else { + mysql_select_db($this->dbname); + $connectError = ob_get_contents(); + } + ob_end_clean(); + + if(is_resource($connID)) { + $this->errorCode=0; + $this->connectionID = $connID; + $this->isConnected = TRUE; + $retval = $this->connectionID; + } + else { + if(is_bool($connID) && !strlen($connectError)) { + $connectError = "generic connection failure"; + } + throw new exception(__METHOD__ .": FATAL ERROR: ". $connectError); + } + } + else { + throw new exception(__METHOD__ .": paramsAreSet=(". $this->paramsAreSet ."), isConnected=(". $this->isConnected .")"); + } + + return($retval); + }//end connect() + //========================================================================= + + + + //========================================================================= + function get_hostname() { + $this->sanity_check(); + return($this->host); + }//end get_hostname() + //========================================================================= + + + + //========================================================================= + /** + * Run sql queries + * + * TODO: re-implement query logging (setting debug, logfilename, etc). + */ + function exec($query) { + $this->lastQuery = $query; + if($this->useQueryList) { + $this->queryList[] = $query; + } + $returnVal = false; + + $this->result = mysql_query($query, $this->connectionID); + + if($this->result !== false) { + if (eregi("^[[:space:]]*select", $query)) { + //If we didn't have an error and we are a select statement, move the pointer to first result + $numRows = $this->numRows(); + if($numRows > 0) { + $this->move_first(); + } + $returnVal = $numRows; + + } + else { + //We got something other than an update. Use numAffected + $returnVal = $this->numAffected(); + } + } + return($returnVal); + }//end exec() + //========================================================================= + + + + //========================================================================= + /** + * Returns any error caused by the last executed query. + * + * @return NULL OK: no error + * @return (string) FAIL: contains error returned from the query. + */ + function errorMsg($setMessage=NULL,$logError=NULL) { + $this->sanity_check(); + if ($this->connectionID < 0) { + //TODO: implement MySQL version (error codes may vary)... + switch ($this->errorCode) { + //############################################### + case -1: + $retVal = "FATAL ERROR - CONNECTION ERROR: RESOURCE NOT FOUND"; + break; + //############################################### + + //############################################### + case -2: + $retVal = "FATAL ERROR - CLASS ERROR: FUNCTION CALLED WITHOUT PARAMETERS"; + break; + //############################################### + + //############################################### + case -3: + $retVal = "Query exceeded maximum timeout (". $this->timeoutSeconds ."... [truncated message content] |
From: <cra...@us...> - 2009-08-21 16:16:31
|
Revision: 130 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=130&view=rev Author: crazedsanity Date: 2009-08-21 16:16:22 +0000 (Fri, 21 Aug 2009) Log Message: ----------- Fix/consolidate schema, logging. /setup/db_session_schema.*.sql: * consolidated with main schema files. /schema.mysql.sql: * changed all tables to run on InnoDB. * add cswal_session_store_table (for cs_sessionDB) /schema.pgsql.sql: * add cswal_session_store_table (for cs_sessionDB) /cs_sessionDB.class.php: * __construct(): -- fix table name & sequence to use "cswal" prefix. -- create instance of cs_webdblogger (which will automatically cause any upgrades to cs-webapplibs to run). -- remove note about session_id() -- remove the "audit_logging" setting. * do_log(): -- clone internal db handle & call reconnect() to establish a new connection to the database. Modified Paths: -------------- trunk/0.3/cs_sessionDB.class.php trunk/0.3/setup/schema.mysql.sql trunk/0.3/setup/schema.pgsql.sql Removed Paths: ------------- trunk/0.3/setup/db_session_schema.mysql.sql trunk/0.3/setup/db_session_schema.pgsql.sql Modified: trunk/0.3/cs_sessionDB.class.php =================================================================== --- trunk/0.3/cs_sessionDB.class.php 2009-08-21 14:47:11 UTC (rev 129) +++ trunk/0.3/cs_sessionDB.class.php 2009-08-21 16:16:22 UTC (rev 130) @@ -47,13 +47,12 @@ $this->db = new cs_phpDB(constant('DBTYPE')); $this->db->connect($dbParams); - $this->tableName = 'cs_session_store_table'; + $this->tableName = 'cswal_session_store_table'; $this->tablePKey = 'session_store_id'; - $this->sequenceName = 'cs_session_store_table_session_store_id_seq'; + $this->sequenceName = 'cswal_session_store_table_session_store_id_seq'; - if(!$this->sessdb_table_exists()) { - $this->load_table(); - } + //create a logger (this will automatically cause any upgrades to happen). + $this->logger = new cs_webdblogger($this->db, 'Session DB', true); //now tell PHP to use this class's methods for saving the session. session_set_save_handler( @@ -65,17 +64,9 @@ array(&$this, 'sessdb_gc') ); - //NOTE::: calling session_id() here, prior to parent's construct, can set a specific session_id; if - // something like cs_authToken (part of cs-webapplibs project) were used, just call - // cs_authToken::create_token() here... parent::__construct(true); - //Stop things from going into an audit log... see - //http://www.developertutorials.com/tutorials/php/saving-php-session-data-database-050711/page3.html - // NOTE::: not sure if this is valid or not... - $this->audit_logging = false; - }//end __construct() //------------------------------------------------------------------------- @@ -338,8 +329,8 @@ //check if the logger object has been created. if(!is_object($this->logger)) { - $newDB = new cs_phpDB(constant('DBTYPE')); - $newDB->connect($this->db->connectParams, true); + $newDB = clone $this->db; + $newDB->reconnect(true); $this->logger = new cs_webdblogger($newDB, $this->logCategory); } Deleted: trunk/0.3/setup/db_session_schema.mysql.sql =================================================================== --- trunk/0.3/setup/db_session_schema.mysql.sql 2009-08-21 14:47:11 UTC (rev 129) +++ trunk/0.3/setup/db_session_schema.mysql.sql 2009-08-21 16:16:22 UTC (rev 130) @@ -1,17 +0,0 @@ - - --- --- Store session data in here. --- Idea originally from: http://www.developertutorials.com/tutorials/php/saving-php-session-data-database-050711 --- - -CREATE TABLE `cswal_session_store_table` ( - `session_store_id` int NOT NULL AUTO_INCREMENT, - `session_id` varchar(32) NOT NULL, - `user_id` varchar(16) NOT NULL, - `date_created` datetime NOT NULL, - `last_updated` datetime NOT NULL, - `session_data` LONGTEXT NOT NULL, - PRIMARY KEY (`session_store_id`) -) -ENGINE = InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; \ No newline at end of file Deleted: trunk/0.3/setup/db_session_schema.pgsql.sql =================================================================== --- trunk/0.3/setup/db_session_schema.pgsql.sql 2009-08-21 14:47:11 UTC (rev 129) +++ trunk/0.3/setup/db_session_schema.pgsql.sql 2009-08-21 16:16:22 UTC (rev 130) @@ -1,16 +0,0 @@ - - --- --- Store session data in here. --- Idea originally from: http://www.developertutorials.com/tutorials/php/saving-php-session-data-database-050711 --- - -CREATE TABLE cswal_session_store_table ( - session_store_id serial NOT NULL PRIMARY KEY, - session_id varchar(32) NOT NULL DEFAULT '' UNIQUE, - user_id varchar(16), - date_created timestamp NOT NULL DEFAULT NOW(), - last_updated timestamp NOT NULL DEFAULT NOW(), - session_data text -); - Modified: trunk/0.3/setup/schema.mysql.sql =================================================================== --- trunk/0.3/setup/schema.mysql.sql 2009-08-21 14:47:11 UTC (rev 129) +++ trunk/0.3/setup/schema.mysql.sql 2009-08-21 16:16:22 UTC (rev 130) @@ -146,7 +146,7 @@ version_id int NOT NULL PRIMARY KEY, project_name varchar(30) NOT NULL UNIQUE, version_string varchar(50) NOT NULL -); +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; CREATE TABLE cswal_auth_token_table ( auth_token_id serial NOT NULL PRIMARY KEY, @@ -158,4 +158,21 @@ creation timestamp NOT NULL DEFAULT NOW(), last_updated timestamp, expiration timestamp NOT NULL -); \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + + + +-- +-- Store session data in here. +-- Idea originally from: http://www.developertutorials.com/tutorials/php/saving-php-session-data-database-050711 +-- + +CREATE TABLE `cswal_session_store_table` ( + `session_store_id` int NOT NULL AUTO_INCREMENT, + `session_id` varchar(32) NOT NULL, + `user_id` varchar(16) NOT NULL, + `date_created` datetime NOT NULL, + `last_updated` datetime NOT NULL, + `session_data` LONGTEXT NOT NULL, + PRIMARY KEY (`session_store_id`) +) ENGINE = InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; \ No newline at end of file Modified: trunk/0.3/setup/schema.pgsql.sql =================================================================== --- trunk/0.3/setup/schema.pgsql.sql 2009-08-21 14:47:11 UTC (rev 129) +++ trunk/0.3/setup/schema.pgsql.sql 2009-08-21 16:16:22 UTC (rev 130) @@ -104,3 +104,19 @@ expiration timestamp NOT NULL ); + +-- +-- Store session data in here. +-- Idea originally from: http://www.developertutorials.com/tutorials/php/saving-php-session-data-database-050711 +-- + +CREATE TABLE cswal_session_store_table ( + session_store_id serial NOT NULL PRIMARY KEY, + session_id varchar(32) NOT NULL DEFAULT '' UNIQUE, + user_id varchar(16), + date_created timestamp NOT NULL DEFAULT NOW(), + last_updated timestamp NOT NULL DEFAULT NOW(), + session_data text +); + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-21 16:30:25
|
Revision: 131 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=131&view=rev Author: crazedsanity Date: 2009-08-21 16:30:05 +0000 (Fri, 21 Aug 2009) Log Message: ----------- Table prefix changes, optionally create new connection when reconnecting db. /cs_phpDB.class.php: * ARG CHANGE: NEW ARG: #1 ($forceNewConnection=TRUE) * optionally create a new connection (default is true) /cs_webdblogger.class.php: * fix table prefix from cswdbl to cswal. /cs_webdbupgrade.class.php: * load_table(): -- remove unnecessary str_replace() calls. /tests/testOfCSWebAppLibs.php: * remove_tables(): -- fix table prefixes -- add cswal_session_store_table as one that is dropped, since that is now in the main schema file. Modified Paths: -------------- trunk/0.3/cs_phpDB.class.php trunk/0.3/cs_webdblogger.class.php trunk/0.3/cs_webdbupgrade.class.php trunk/0.3/tests/testOfCSWebAppLibs.php Modified: trunk/0.3/cs_phpDB.class.php =================================================================== --- trunk/0.3/cs_phpDB.class.php 2009-08-21 16:16:22 UTC (rev 130) +++ trunk/0.3/cs_phpDB.class.php 2009-08-21 16:30:05 UTC (rev 131) @@ -182,9 +182,9 @@ //========================================================================= - public function reconnect() { + public function reconnect($forceNewConnection=TRUE) { if(is_array($this->connectParams) && count($this->connectParams)) { - $this->dbLayerObj->connect($this->connectParams, true); + $this->dbLayerObj->connect($this->connectParams, $forceNewConnection); } else { throw new exception(__METHOD__ .": no connection parameters stored"); Modified: trunk/0.3/cs_webdblogger.class.php =================================================================== --- trunk/0.3/cs_webdblogger.class.php 2009-08-21 16:16:22 UTC (rev 130) +++ trunk/0.3/cs_webdblogger.class.php 2009-08-21 16:30:05 UTC (rev 131) @@ -22,7 +22,7 @@ * * QUERY TO GET LAST COUPLE OF LOGS:::: SELECT l.log_id as id, l.creation, l.event_id as lid, le.description AS event, l.details - FROM cswdbl_log_table AS l INNER JOIN cswdbl_event_table AS le USING (event_id) ORDER BY log_id DESC LIMIT 25; + FROM cswal_log_table AS l INNER JOIN cswal_event_table AS le USING (event_id) ORDER BY log_id DESC LIMIT 25; */ //NOTE::: this class **REQUIRES** cs-content for its "cs_phpDB" class. @@ -64,22 +64,22 @@ /** List of tables keyed off an internal reference name. */ protected $tables = array( - 'category' => 'cswdbl_category_table', - 'class' => 'cswdbl_class_table', - 'event' => 'cswdbl_event_table', - 'log' => 'cswdbl_log_table', - 'attrib' => 'cswdbl_attribute_table', - 'logAttrib' => 'cswdbl_log_attribute_table' + 'category' => 'cswal_category_table', + 'class' => 'cswal_class_table', + 'event' => 'cswal_event_table', + 'log' => 'cswal_log_table', + 'attrib' => 'cswal_attribute_table', + 'logAttrib' => 'cswal_log_attribute_table' ); /** List of sequences keyed off an internal reference name (MUST match references above) */ protected $seqs = array( - 'category' => "cswdbl_category_table_category_id_seq", - 'class' => "cswdbl_class_table_class_id_seq", - 'event' => "cswdbl_event_table_event_id_seq", - 'log' => "cswdbl_log_table_log_id_seq", - 'attrib' => "cswdbl_attribute_table_attribute_id_seq", - 'logAttrib' => "cswdbl_log_attribute_table_log_attribute_id_seq" + 'category' => "cswal_category_table_category_id_seq", + 'class' => "cswal_class_table_class_id_seq", + 'event' => "cswal_event_table_event_id_seq", + 'log' => "cswal_log_table_log_id_seq", + 'attrib' => "cswal_attribute_table_attribute_id_seq", + 'logAttrib' => "cswal_log_attribute_table_log_attribute_id_seq" ); //========================================================================= Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2009-08-21 16:16:22 UTC (rev 130) +++ trunk/0.3/cs_webdbupgrade.class.php 2009-08-21 16:30:05 UTC (rev 131) @@ -905,8 +905,6 @@ public function load_table() { $schemaFileLocation = dirname(__FILE__) .'/setup/schema.'. $this->db->get_dbtype() .'.sql'; $schema = file_get_contents($schemaFileLocation); - $schema = str_replace('{tableName}', $this->config['DB_TABLE'], $schema); - $schema = str_replace('{primaryKey}', $this->config['DB_PRIMARYKEY'], $schema); $this->db->exec($schema); $loadTableResult = $this->db->errorMsg(); Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-21 16:16:22 UTC (rev 130) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-21 16:30:05 UTC (rev 131) @@ -44,9 +44,9 @@ //-------------------------------------------------------------------------- private function remove_tables() { $tableList = array( - 'cswal_auth_token_table', 'cswal_version_table', 'cswdbl_attribute_table', - 'cswdbl_category_table', 'cswdbl_class_table', 'cswdbl_event_table', - 'cswdbl_log_attribute_table', 'cswdbl_log_table', + 'cswal_auth_token_table', 'cswal_version_table', 'cswal_attribute_table', + 'cswal_category_table', 'cswal_class_table', 'cswal_event_table', + 'cswal_log_attribute_table', 'cswal_log_table', 'cswal_session_store_table' ); $db = $this->create_dbconn(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-21 16:45:17
|
Revision: 133 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=133&view=rev Author: crazedsanity Date: 2009-08-21 16:45:10 +0000 (Fri, 21 Aug 2009) Log Message: ----------- Modified Paths: -------------- trunk/0.3/cs_authToken.class.php trunk/0.3/tests/testOfCSWebAppLibs.php Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-21 16:34:42 UTC (rev 132) +++ trunk/0.3/cs_authToken.class.php 2009-08-21 16:45:10 UTC (rev 133) @@ -298,19 +298,22 @@ public function remove_expired_tokens() { $sql = "SELECT * FROM ". $this->table ." WHERE NOW() > expiration"; + $destroyedTokens = 0; try { $data = $this->db->run_query($sql, 'auth_token_id'); if(is_array($data)) { foreach($data as $tokenId => $tokenData) { //TODO: add logging here? - $this->destroy_token($tokenId); + $destroyedTokens += $this->destroy_token($tokenId); } } } catch(exception $e) { throw new exception(__METHOD__ .": error encountered while expiring tokens::: ". $e->getMessage()); } + + return($destroyedTokens); }//end remove_expired_tokens() //========================================================================= Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-21 16:34:42 UTC (rev 132) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-21 16:45:10 UTC (rev 133) @@ -178,6 +178,22 @@ $this->assertNotEqual($tokenData['hash'], $tok->doHash($tokenData['id'], $uid, $checksum, $hashThis), "hash is guessable"); } + + //test expiring tokens... + { + //create a token that is immediately expired. + $tokenData = $tok->create_token(22, 'token expiration test', 'Lorem ipsum dolor sit amet, consectetur.', '-5 days'); + $this->do_tokenTest($tokenData, 22, 'token expiration test'); + + $this->assertFalse(is_array($tok->tokenData($tokenData['id'], true))); + $this->assertTrue(is_array($tok->tokenData($tokenData['id'], false))); + $this->assertTrue(count($tok->tokenData($tokenData['id'],false)) == 9); + + //REMEMBER: we've created other tokens that will now expire... + $removedTokens = $tok->remove_expired_tokens(); + $this->assertEqual(2, $removedTokens); + } + }//end test_token_basics() //-------------------------------------------------------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-26 16:01:48
|
Revision: 140 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=140&view=rev Author: crazedsanity Date: 2009-08-26 16:01:41 +0000 (Wed, 26 Aug 2009) Log Message: ----------- Fix class "extends" settings. /cs_bbCodeParser.class.php: * MAIN::: -- extend cs_webAppLibsAbstract{}, not cs_contentAbstract{}. /cs_phpDB.class.php: * MAIN::: -- extend cs_webAppLibsAbstract{}, not cs_contentAbstract{}. /cs_siteconfig.class.php: * MAIN::: -- extend cs_webAppLibsAbstract{}, not cs_contentAbstract{}. Modified Paths: -------------- trunk/0.3/cs_bbCodeParser.class.php trunk/0.3/cs_phpDB.class.php trunk/0.3/cs_siteConfig.class.php Modified: trunk/0.3/cs_bbCodeParser.class.php =================================================================== --- trunk/0.3/cs_bbCodeParser.class.php 2009-08-24 16:56:14 UTC (rev 139) +++ trunk/0.3/cs_bbCodeParser.class.php 2009-08-26 16:01:41 UTC (rev 140) @@ -20,7 +20,7 @@ require_once(dirname(__FILE__) ."/abstract/cs_webapplibs.abstract.class.php"); -class cs_bbCodeParser extends cs_contentAbstract { +class cs_bbCodeParser extends cs_webAppLibsAbstract { /** Array containing all the codes & how to parse them. */ private $bbCodeData = NULL; Modified: trunk/0.3/cs_phpDB.class.php =================================================================== --- trunk/0.3/cs_phpDB.class.php 2009-08-24 16:56:14 UTC (rev 139) +++ trunk/0.3/cs_phpDB.class.php 2009-08-26 16:01:41 UTC (rev 140) @@ -27,7 +27,7 @@ require_once(dirname(__FILE__) ."/abstract/cs_webapplibs.abstract.class.php"); require_once(dirname(__FILE__) ."/abstract/cs_phpDB.abstract.class.php"); -class cs_phpDB extends cs_contentAbstract { +class cs_phpDB extends cs_webAppLibsAbstract { private $dbLayerObj; private $dbType; Modified: trunk/0.3/cs_siteConfig.class.php =================================================================== --- trunk/0.3/cs_siteConfig.class.php 2009-08-24 16:56:14 UTC (rev 139) +++ trunk/0.3/cs_siteConfig.class.php 2009-08-26 16:01:41 UTC (rev 140) @@ -20,7 +20,7 @@ require_once(dirname(__FILE__). '/../cs-phpxml/cs_phpxmlParser.class.php'); require_once(dirname(__FILE__) .'/../cs-phpxml/cs_phpxmlBuilder.class.php'); -class cs_siteConfig extends cs_contentAbstract { +class cs_siteConfig extends cs_webAppLibsAbstract { /** XMLParser{} object, for reading XML config file. */ private $xmlReader; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-26 16:12:21
|
Revision: 141 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=141&view=rev Author: crazedsanity Date: 2009-08-26 16:12:12 +0000 (Wed, 26 Aug 2009) Log Message: ----------- Minor fixes... /cs_siteConfig.class.php: * MAIN::: require cs-webapplibsAbstract. /abstract/cs_webapplibs.abstract.class.php: * MAIN::: -- require cs_contentAbstract{} -- extend cs_contentAbstract{} Modified Paths: -------------- trunk/0.3/abstract/cs_webapplibs.abstract.class.php trunk/0.3/cs_siteConfig.class.php Modified: trunk/0.3/abstract/cs_webapplibs.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_webapplibs.abstract.class.php 2009-08-26 16:01:41 UTC (rev 140) +++ trunk/0.3/abstract/cs_webapplibs.abstract.class.php 2009-08-26 16:12:12 UTC (rev 141) @@ -10,10 +10,10 @@ * Last Updated:::::::: $Date$ */ -require_once(constant('LIBDIR') .'/cs-content/abstract/cs_version.abstract.class.php'); +require_once(dirname(__FILE__) .'/../../cs-content/abstract/cs_content.abstract.class.php'); -abstract class cs_webapplibsAbstract extends cs_versionAbstract { +abstract class cs_webapplibsAbstract extends cs_contentAbstract { } Modified: trunk/0.3/cs_siteConfig.class.php =================================================================== --- trunk/0.3/cs_siteConfig.class.php 2009-08-26 16:01:41 UTC (rev 140) +++ trunk/0.3/cs_siteConfig.class.php 2009-08-26 16:12:12 UTC (rev 141) @@ -15,7 +15,7 @@ * */ -require_once(dirname(__FILE__) .'/../cs-content/abstract/cs_content.abstract.class.php'); +require_once(dirname(__FILE__) .'/abstract/cs_webapplibs.abstract.class.php'); require_once(dirname(__FILE__) .'/../cs-content/cs_fileSystem.class.php'); require_once(dirname(__FILE__). '/../cs-phpxml/cs_phpxmlParser.class.php'); require_once(dirname(__FILE__) .'/../cs-phpxml/cs_phpxmlBuilder.class.php'); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-27 16:43:06
|
Revision: 143 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=143&view=rev Author: crazedsanity Date: 2009-08-27 16:43:00 +0000 (Thu, 27 Aug 2009) Log Message: ----------- Update main abstract class to handle cs_globalFunctions & cs_versionParse stuff. /cs_authToken.class.php: * MAIN::: -- set gfObj as protected (not private) * __construct(): -- call parent::__construct() (creates gfObj). /cs_bbCodeParser.class.php: * MAIN::: -- extends cs_webapplibsAbstract instead of cs_contentAbstract. /cs_phpDB.class.php: * MAIN::: -- extends cs_webapplibsAbstract instead of cs_contentAbstract. * __construct(): -- call parent::__construct() (creates gfObj). /cs_siteConfig.class.php: * MAIN::: -- require cs_webapplibsAbstract class file. -- extend cs_webapplibsAbstract instead of cs_contentAbstract /cs_tabs.class.php: * __construct(): -- call parent::__construct(). /cs_webdblogger.class.php: * __construct(): -- call parent::__construct() -- don't create cs_globalFunctions object (parent does that) /cs_webdbupgrade.class.php: * __construct(): -- call parent::__construct() -- don't create cs_globalFunctions object (parent does that) /abstract/cs_webapplibs.abstract.class.php: * MAIN::: -- don't require cs_contentAbstract -- new var, protected $gfObj * __construct() [NEW]: -- do all the stuff required to use cs_versionAbstract -- create gfObj (according to constructor arg #1) Modified Paths: -------------- trunk/0.3/abstract/cs_webapplibs.abstract.class.php trunk/0.3/cs_authToken.class.php trunk/0.3/cs_bbCodeParser.class.php trunk/0.3/cs_phpDB.class.php trunk/0.3/cs_siteConfig.class.php trunk/0.3/cs_tabs.class.php trunk/0.3/cs_webdblogger.class.php trunk/0.3/cs_webdbupgrade.class.php Modified: trunk/0.3/abstract/cs_webapplibs.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_webapplibs.abstract.class.php 2009-08-26 17:50:33 UTC (rev 142) +++ trunk/0.3/abstract/cs_webapplibs.abstract.class.php 2009-08-27 16:43:00 UTC (rev 143) @@ -10,11 +10,24 @@ * Last Updated:::::::: $Date$ */ -require_once(dirname(__FILE__) .'/../../cs-content/abstract/cs_content.abstract.class.php'); - - -abstract class cs_webapplibsAbstract extends cs_contentAbstract { +abstract class cs_webapplibsAbstract extends cs_versionAbstract { + protected $gfObj; + + //------------------------------------------------------------------------- + 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. + //TODO::: find a way to avoid h + require_once(dirname(__FILE__) ."/../../cs-content/cs_globalFunctions.class.php"); + $this->gfObj = new cs_globalFunctions(); + } + }//end __construct() + //------------------------------------------------------------------------- } ?> Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-26 17:50:33 UTC (rev 142) +++ trunk/0.3/cs_authToken.class.php 2009-08-27 16:43:00 UTC (rev 143) @@ -19,7 +19,7 @@ private $db; /** Object that helps deal with strings. */ - private $gfObj; + protected $gfObj; /** Name of the table */ private $table = 'cswal_auth_token_table'; @@ -39,7 +39,7 @@ else { throw new exception(__METHOD__ .": database object not connected"); } - $this->gfObj = new cs_globalFunctions(); + parent::__construct(true); $upg = new cs_webdbupgrade(dirname(__FILE__) .'/VERSION', dirname(__FILE__) .'/upgrades/upgrade.xml'); $upg->check_versions(true); Modified: trunk/0.3/cs_bbCodeParser.class.php =================================================================== --- trunk/0.3/cs_bbCodeParser.class.php 2009-08-26 17:50:33 UTC (rev 142) +++ trunk/0.3/cs_bbCodeParser.class.php 2009-08-27 16:43:00 UTC (rev 143) @@ -20,7 +20,7 @@ require_once(dirname(__FILE__) ."/abstract/cs_webapplibs.abstract.class.php"); -class cs_bbCodeParser extends cs_webAppLibsAbstract { +class cs_bbCodeParser extends cs_webapplibsAbstract { /** Array containing all the codes & how to parse them. */ private $bbCodeData = NULL; Modified: trunk/0.3/cs_phpDB.class.php =================================================================== --- trunk/0.3/cs_phpDB.class.php 2009-08-26 17:50:33 UTC (rev 142) +++ trunk/0.3/cs_phpDB.class.php 2009-08-27 16:43:00 UTC (rev 143) @@ -27,11 +27,12 @@ require_once(dirname(__FILE__) ."/abstract/cs_webapplibs.abstract.class.php"); require_once(dirname(__FILE__) ."/abstract/cs_phpDB.abstract.class.php"); -class cs_phpDB extends cs_webAppLibsAbstract { +class cs_phpDB extends cs_webapplibsAbstract { private $dbLayerObj; private $dbType; public $connectParams = array(); + protected $gfObj; //========================================================================= public function __construct($type='pgsql') { @@ -43,7 +44,7 @@ $this->dbLayerObj = new $className; $this->dbType = $type; - parent::__construct(); + parent::__construct(true); $this->isInitialized = TRUE; } Modified: trunk/0.3/cs_siteConfig.class.php =================================================================== --- trunk/0.3/cs_siteConfig.class.php 2009-08-26 17:50:33 UTC (rev 142) +++ trunk/0.3/cs_siteConfig.class.php 2009-08-27 16:43:00 UTC (rev 143) @@ -20,7 +20,7 @@ require_once(dirname(__FILE__). '/../cs-phpxml/cs_phpxmlParser.class.php'); require_once(dirname(__FILE__) .'/../cs-phpxml/cs_phpxmlBuilder.class.php'); -class cs_siteConfig extends cs_webAppLibsAbstract { +class cs_siteConfig extends cs_webapplibsAbstract { /** XMLParser{} object, for reading XML config file. */ private $xmlReader; Modified: trunk/0.3/cs_tabs.class.php =================================================================== --- trunk/0.3/cs_tabs.class.php 2009-08-26 17:50:33 UTC (rev 142) +++ trunk/0.3/cs_tabs.class.php 2009-08-27 16:43:00 UTC (rev 143) @@ -38,6 +38,7 @@ //set the internal var. $this->templateVar = $templateVar; } + parent::__construct(); $this->gfObj = new cs_globalFunctions; }//end __construct() Modified: trunk/0.3/cs_webdblogger.class.php =================================================================== --- trunk/0.3/cs_webdblogger.class.php 2009-08-26 17:50:33 UTC (rev 142) +++ trunk/0.3/cs_webdblogger.class.php 2009-08-27 16:43:00 UTC (rev 143) @@ -99,7 +99,7 @@ throw new exception(__METHOD__ .": requires cs_phpDB of higher than v". $mustBeHigherThan,1); } - $this->gfObj = new cs_globalFunctions; + parent::__construct(true); //see if there's an upgrade to perform... if($checkForUpgrades === true) { Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2009-08-26 17:50:33 UTC (rev 142) +++ trunk/0.3/cs_webdbupgrade.class.php 2009-08-27 16:43:00 UTC (rev 143) @@ -94,7 +94,7 @@ require_once(constant('LIBDIR') .'/cs-phpxml/cs_arrayToPath.class.php'); $this->fsObj = new cs_fileSystem(constant('SITE_ROOT')); - $this->gfObj = new cs_globalFunctions; + parent::__construct(true); if(defined('DEBUGPRINTOPT')) { $this->gfObj->debugPrintOpt = constant('DEBUGPRINTOPT'); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-08-28 20:31:01
|
Revision: 145 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=145&view=rev Author: crazedsanity Date: 2009-08-28 20:30:54 +0000 (Fri, 28 Aug 2009) Log Message: ----------- No more include/requires: include before or use __autoload(). NOTE::: this was tested using the current (trunk/1.0) version of cs-content's __autoload.php script. REMOVED require_once() STATEMENTS::: * /cs_authToken.class.php * /cs_bbCodeParser.class.php * /cs_phpDB.class.php * /cs_sessionDB.class.php * /cs_siteConfig.class.php * /cs_tabs.class.php * /cs_webdblogger.class.php * /cs_webdbupgrade.class.php * /abstract/cs_webapplibs.abstract.class.php * /tests/testOfCSPHPDB.php * /tests/testOfCSWebAppLibs.php Modified Paths: -------------- trunk/0.3/abstract/cs_webapplibs.abstract.class.php trunk/0.3/cs_authToken.class.php trunk/0.3/cs_bbCodeParser.class.php trunk/0.3/cs_phpDB.class.php trunk/0.3/cs_sessionDB.class.php trunk/0.3/cs_siteConfig.class.php trunk/0.3/cs_tabs.class.php trunk/0.3/cs_webdblogger.class.php trunk/0.3/cs_webdbupgrade.class.php trunk/0.3/tests/testOfCSPHPDB.php trunk/0.3/tests/testOfCSWebAppLibs.php Modified: trunk/0.3/abstract/cs_webapplibs.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_webapplibs.abstract.class.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/abstract/cs_webapplibs.abstract.class.php 2009-08-28 20:30:54 UTC (rev 145) @@ -10,7 +10,6 @@ * Last Updated:::::::: $Date$ */ -require_once(dirname(__FILE__) .'/../../cs-content/abstract/cs_version.abstract.class.php'); abstract class cs_webapplibsAbstract extends cs_versionAbstract { protected $gfObj; @@ -24,7 +23,6 @@ if($makeGfObj === true) { //make a cs_globalFunctions{} object. //TODO::: find a way to avoid h - require_once(dirname(__FILE__) ."/../../cs-content/cs_globalFunctions.class.php"); $this->gfObj = new cs_globalFunctions(); } }//end __construct() Modified: trunk/0.3/cs_authToken.class.php =================================================================== --- trunk/0.3/cs_authToken.class.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/cs_authToken.class.php 2009-08-28 20:30:54 UTC (rev 145) @@ -11,7 +11,6 @@ */ -require_once(dirname(__FILE__) .'/abstract/cs_webapplibs.abstract.class.php'); class cs_authToken extends cs_webapplibsAbstract { Modified: trunk/0.3/cs_bbCodeParser.class.php =================================================================== --- trunk/0.3/cs_bbCodeParser.class.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/cs_bbCodeParser.class.php 2009-08-28 20:30:54 UTC (rev 145) @@ -18,7 +18,6 @@ * been converted. */ -require_once(dirname(__FILE__) ."/abstract/cs_webapplibs.abstract.class.php"); class cs_bbCodeParser extends cs_webapplibsAbstract { Modified: trunk/0.3/cs_phpDB.class.php =================================================================== --- trunk/0.3/cs_phpDB.class.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/cs_phpDB.class.php 2009-08-28 20:30:54 UTC (rev 145) @@ -24,9 +24,6 @@ // /////////////////////// -require_once(dirname(__FILE__) ."/abstract/cs_webapplibs.abstract.class.php"); -require_once(dirname(__FILE__) ."/abstract/cs_phpDB.abstract.class.php"); - class cs_phpDB extends cs_webapplibsAbstract { private $dbLayerObj; Modified: trunk/0.3/cs_sessionDB.class.php =================================================================== --- trunk/0.3/cs_sessionDB.class.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/cs_sessionDB.class.php 2009-08-28 20:30:54 UTC (rev 145) @@ -8,10 +8,6 @@ * $LastChangedRevision$ */ -require_once(constant('LIBDIR') .'/cs-content/cs_session.class.php'); -require_once(dirname(__FILE__) .'/cs_phpDB.class.php'); -require_once(constant('LIBDIR') .'/cs-phpxml/cs_arrayToPath.class.php'); -require_once(constant('LIBDIR') .'/cs-webapplibs/cs_webdblogger.class.php'); class cs_sessionDB extends cs_session { Modified: trunk/0.3/cs_siteConfig.class.php =================================================================== --- trunk/0.3/cs_siteConfig.class.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/cs_siteConfig.class.php 2009-08-28 20:30:54 UTC (rev 145) @@ -15,10 +15,6 @@ * */ -require_once(dirname(__FILE__) .'/abstract/cs_webapplibs.abstract.class.php'); -require_once(dirname(__FILE__) .'/../cs-content/cs_fileSystem.class.php'); -require_once(dirname(__FILE__). '/../cs-phpxml/cs_phpxmlParser.class.php'); -require_once(dirname(__FILE__) .'/../cs-phpxml/cs_phpxmlBuilder.class.php'); class cs_siteConfig extends cs_webapplibsAbstract { Modified: trunk/0.3/cs_tabs.class.php =================================================================== --- trunk/0.3/cs_tabs.class.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/cs_tabs.class.php 2009-08-28 20:30:54 UTC (rev 145) @@ -4,9 +4,7 @@ * */ -require_once(dirname(__FILE__) .'/abstract/cs_webapplibs.abstract.class.php'); - class cs_tabs extends cs_webapplibsAbstract { private $tabsArr=array(); private $selectedTab; Modified: trunk/0.3/cs_webdblogger.class.php =================================================================== --- trunk/0.3/cs_webdblogger.class.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/cs_webdblogger.class.php 2009-08-28 20:30:54 UTC (rev 145) @@ -27,8 +27,6 @@ //NOTE::: this class **REQUIRES** cs-content for its "cs_phpDB" class. -require_once(dirname(__FILE__) .'/abstract/cs_webapplibs.abstract.class.php'); -require_once(dirname(__FILE__) .'/cs_webdbupgrade.class.php'); class cs_webdblogger extends cs_webapplibsAbstract { /** Database handle */ Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/cs_webdbupgrade.class.php 2009-08-28 20:30:54 UTC (rev 145) @@ -12,9 +12,6 @@ * */ -require_once(dirname(__FILE__) .'/abstract/cs_webapplibs.abstract.class.php'); -require_once(dirname(__FILE__) .'/cs_webdblogger.class.php'); -require_once(dirname(__FILE__) .'/cs_phpDB.class.php'); class cs_webdbupgrade extends cs_webapplibsAbstract { @@ -87,11 +84,6 @@ throw new exception(__METHOD__ .": required constant 'SITE_ROOT' not set"); } - require_once(constant('LIBDIR') .'/cs-content/cs_globalFunctions.class.php'); - require_once(constant('LIBDIR') .'/cs-content/cs_fileSystem.class.php'); - require_once(constant('LIBDIR') .'/cs-phpxml/cs_phpxmlParser.class.php'); - require_once(constant('LIBDIR') .'/cs-phpxml/cs_phpxmlCreator.class.php'); - require_once(constant('LIBDIR') .'/cs-phpxml/cs_arrayToPath.class.php'); $this->fsObj = new cs_fileSystem(constant('SITE_ROOT')); parent::__construct(true); Modified: trunk/0.3/tests/testOfCSPHPDB.php =================================================================== --- trunk/0.3/tests/testOfCSPHPDB.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/tests/testOfCSPHPDB.php 2009-08-28 20:30:54 UTC (rev 145) @@ -4,8 +4,6 @@ */ -require_once(dirname(__FILE__) .'/../cs_phpDB.class.php'); - class TestOfCSPHPDB extends UnitTestCase { private $dbParams=array(); Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-27 16:44:16 UTC (rev 144) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-08-28 20:30:54 UTC (rev 145) @@ -11,7 +11,6 @@ * $LastChangedRevision$ */ -require_once(dirname(__FILE__) .'/../cs_authToken.class.php'); class testOfCSWebAppLibs extends UnitTestCase { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-09-21 04:40:44
|
Revision: 150 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=150&view=rev Author: crazedsanity Date: 2009-09-21 04:40:36 +0000 (Mon, 21 Sep 2009) Log Message: ----------- Default db type instead of exception, dbparameters for cs-webapplibs. /cs_phpDB.class.php: * __construct(): -- set type as 'pgsql' if it isn't set. -- dont' throw an exception anymore since type is always set. /cs_webdbupgrade.class.php: * MAIN::: -- new (private) var $dbType=null * __construct(): -- ARG CHANGE: ARG SHIFTED ($lockFile from #3 to #4) -- ARG CHANGE: NEW ARG: #3 (array $dbparams=null) -- allow an array of database parameters to be set -- use array of paramenters vs. constants by default. -- for constant definitions, use (modified) project name as prefix. -- only set internal dbType if the appropriate constant is set -- set default rwDir (don't throw an exception on missing constant) -- user internal dbType as first argument to cs_phpDB. /tests/testOfCSWebAppLibs.php: * create_db(): -- use proper constants for connection parameters * remove_tables(): -- don't force an error if dropping the tables fails. Modified Paths: -------------- trunk/0.3/cs_phpDB.class.php trunk/0.3/cs_webdbupgrade.class.php trunk/0.3/tests/testOfCSWebAppLibs.php Modified: trunk/0.3/cs_phpDB.class.php =================================================================== --- trunk/0.3/cs_phpDB.class.php 2009-09-10 17:39:07 UTC (rev 149) +++ trunk/0.3/cs_phpDB.class.php 2009-09-21 04:40:36 UTC (rev 150) @@ -33,21 +33,18 @@ //========================================================================= public function __construct($type='pgsql') { - - if(strlen($type)) { - - require_once(dirname(__FILE__) .'/db_types/'. __CLASS__ .'__'. $type .'.class.php'); - $className = __CLASS__ .'__'. $type; - $this->dbLayerObj = new $className; - $this->dbType = $type; - - parent::__construct(true); - - $this->isInitialized = TRUE; + if(is_null($type) || !strlen($type)) { + $type = 'pgsql'; } - else { - throw new exception(__METHOD__ .": failed to give a type (". $type .")"); - } + + require_once(dirname(__FILE__) .'/db_types/'. __CLASS__ .'__'. $type .'.class.php'); + $className = __CLASS__ .'__'. $type; + $this->dbLayerObj = new $className; + $this->dbType = $type; + + parent::__construct(true); + + $this->isInitialized = TRUE; }//end __construct() //========================================================================= Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2009-09-10 17:39:07 UTC (rev 149) +++ trunk/0.3/cs_webdbupgrade.class.php 2009-09-21 04:40:36 UTC (rev 150) @@ -55,6 +55,8 @@ private $storedLogs = array(); private $debugLogs=array(); + private $dbType=null; + /** List of acceptable suffixes; example "1.0.0-BETA3" -- NOTE: these MUST be in * an order that reflects newest -> oldest; "ALPHA happens before BETA, etc. */ private $suffixList = array( @@ -64,16 +66,19 @@ ); //========================================================================= - public function __construct($versionFileLocation, $upgradeConfigFile, $lockFile='upgrade.lock') { + public function __construct($versionFileLocation, $upgradeConfigFile, array $dbParams=null, $lockFile='upgrade.lock') { //setup configuration parameters for database connectivity. - $dbParams = array( - 'host' => constant(__CLASS__ .'-DB_CONNECT_HOST'), - 'port' => constant(__CLASS__ .'-DB_CONNECT_PORT'), - 'dbname' => constant(__CLASS__ .'-DB_CONNECT_DBNAME'), - 'user' => constant(__CLASS__ .'-DB_CONNECT_USER'), - 'password' => constant(__CLASS__ .'-DB_CONNECT_PASSWORD') - ); + if(!is_array($dbParams) || !count($dbParams)) { + $prefix = preg_replace('/-/', '_', $this->get_project()); + $dbParams = array( + 'host' => constant($prefix .'-DB_CONNECT_HOST'), + 'port' => constant($prefix .'-DB_CONNECT_PORT'), + 'dbname' => constant($prefix .'-DB_CONNECT_DBNAME'), + 'user' => constant($prefix .'-DB_CONNECT_USER'), + 'password' => constant($prefix .'-DB_CONNECT_PASSWORD') + ); + } $this->config['DBPARAMS'] = $dbParams; //Check for some required constants. $requisiteConstants = array('LIBDIR'); @@ -95,8 +100,8 @@ $this->config['DB_PRIMARYKEY'] = 'version_id'; $this->sequenceName = $this->config['DB_TABLE'] .'_'. $this->config['DB_PRIMARYKEY'] .'_seq'; - if(!defined('DBTYPE')) { - throw new exception(__METHOD__ .": required constant 'DBTYPE' not set"); + if(defined('DBTYPE')) { + $this->dbType = constant('DBTYPE'); } if(!file_exists($upgradeConfigFile) || !is_readable($upgradeConfigFile)) { @@ -110,18 +115,17 @@ } $this->set_version_file_location($versionFileLocation); - if(!defined(__CLASS__ .'-RWDIR') || !is_dir(constant(__CLASS__ .'-RWDIR')) || !is_readable(constant(__CLASS__ .'-RWDIR')) || !is_writable(constant(__CLASS__ .'-RWDIR'))) { - throw new exception(__METHOD__ .": missing RWDIR (". constant(__CLASS__ .'-RWDIR') .") or isn't readable/writable"); + $rwDir = dirname(__FILE__) .'/../rw'; + if(defined(__CLASS__ .'-RWDIR')) { + $rwDir = constant(__CLASS__ .'-RWDIR'); } - else { - $this->config['RWDIR'] = constant(__CLASS__ .'-RWDIR'); - } + $this->config['RWDIR'] = $rwDir; if(is_null($lockFile) || !strlen($lockFile)) { $lockFile = 'upgrade.lock'; } $this->lockfile = $this->config['RWDIR'] .'/'. $lockFile; - $this->db = new cs_phpDB(constant('DBTYPE')); + $this->db = new cs_phpDB($this->dbType); try { $this->db->connect($this->config['DBPARAMS']); } @@ -137,7 +141,7 @@ $this->check_internal_upgrades(); try { - $loggerDb = new cs_phpDB(constant('DBTYPE')); + $loggerDb = new cs_phpDB($this->dbType); $loggerDb->connect($this->config['DBPARAMS'], true); $this->logsObj = new cs_webdblogger($loggerDb, "Upgrade ". $this->projectName, false); } Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-09-10 17:39:07 UTC (rev 149) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-09-21 04:40:36 UTC (rev 150) @@ -26,11 +26,11 @@ //-------------------------------------------------------------------------- private function create_dbconn() { $dbParams = array( - 'host' => constant('DB_PG_HOST'), - 'dbname' => constant('DB_PG_DBNAME'), - 'user' => constant('DB_PG_DBUSER'), - 'password' => constant('DB_PG_DBPASS'), - 'port' => constant('DB_PG_PORT') + 'host' => constant('cs_webapplibs-DB_CONNECT_HOST'), + 'dbname' => constant('cs_webapplibs-DB_CONNECT_DBNAME'), + 'user' => constant('cs_webapplibs-DB_CONNECT_USER'), + 'password' => constant('cs_webapplibs-DB_CONNECT_PASSWORD'), + 'port' => constant('cs_webapplibs-DB_CONNECT_PORT') ); $db = new cs_phpDB(constant('DBTYPE')); $db->connect($dbParams); @@ -55,7 +55,7 @@ } catch(exception $e) { //force an error. - $this->assertTrue(false, "Error while dropping (". $name .")::: ". $e->getMessage()); + //$this->assertTrue(false, "Error while dropping (". $name .")::: ". $e->getMessage()); } } }//end remove_tables() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |