Thread: [Cs-webapplibs-commits] SF.net SVN: cs-webapplibs:[155] trunk/0.3 (Page 2)
Status: Beta
Brought to you by:
crazedsanity
From: <cra...@us...> - 2009-10-29 03:28:46
|
Revision: 155 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=155&view=rev Author: crazedsanity Date: 2009-10-29 03:28:38 +0000 (Thu, 29 Oct 2009) Log Message: ----------- Initial work for a generic data linker (database-oriented). NOTE::: mysql schema not checked for correctness. Modified Paths: -------------- trunk/0.3/setup/schema.mysql.sql trunk/0.3/setup/schema.pgsql.sql trunk/0.3/tests/testOfCSWebAppLibs.php Added Paths: ----------- trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php trunk/0.3/abstract/cs_gdlObject.abstract.class.php trunk/0.3/abstract/cs_gdlPath.abstract.class.php trunk/0.3/cs_genericDataLinker.class.php Copied: trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php (from rev 154, trunk/0.3/abstract/cs_phpDB.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php 2009-10-29 03:28:38 UTC (rev 155) @@ -0,0 +1,89 @@ +<?php +/* + * Created on Jan 29, 2009 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_gdlAttribAbstract extends cs_gdlPathAbstract { + + + const table='cswal_gdl_attribute_table'; + const tableSeq = 'cswal_gdl_attribute_table_attribute_id_seq'; + + + + //------------------------------------------------------------------------- + public function create_attrib($path, $data, $type=null) { + + $objectId = $this->get_object_id_from_path($path); + + $insertString = ""; + $attribs = array(); + if(is_array($data) && count($data)) { + foreach($data as $n=>$v) { + $n = $this->translate_attrib_name($n); + $attribs[$n] = $v; + } + } + elseif(!is_null($type)) { + $key = $this->translate_attrib_name($type); + $attribs = array($key => $data); + } + else { + throw new exception(__METHOD__ .": data was not array and no type set"); + } + + if(!is_array($attribs) || !count($attribs)) { + throw new exception(__METHOD__ .": failed to create an array of attributes... ". $this->gfObj->debug_print(func_get_args(),0)); + } + + $attribs['object_id'] = $objectId; + $insertString = $this->gfObj->string_from_array($attribs, 'insert'); + + + if(!strlen($insertString)) { + throw new exception(__METHOD__ .": invalid insert string (". $insertString .")"); + } + $sql = "INSERT INTO ". self::attrTable ." ". $insertString; + + try { + $retval = $this->db->run_insert($sql, self::attrTableSeq); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to perform insert::: ". $e->getMessage() .' ---- '. $sql); + } + + return($retval); + }//end create_attrib() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function translate_attrib_name($name) { + $retval = null; + foreach($this->validTypes as $type) { + if(preg_match('/^'. $type .'/', $name)) { + $retval = 'a_'. $type; + break; + } + } + + if(is_null($retval) || !strlen($retval)) { + $this->gfObj->debug_print(__METHOD__ .": name was (". $name ."), retval=(". $retval .")",1); + throw new exception(__METHOD__ .": invalid attribute name (". $name .")"); + } + + return($retval); + }//end translate_attrib_name() + //------------------------------------------------------------------------- + +} +?> \ No newline at end of file Copied: trunk/0.3/abstract/cs_gdlObject.abstract.class.php (from rev 154, trunk/0.3/abstract/cs_phpDB.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_gdlObject.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_gdlObject.abstract.class.php 2009-10-29 03:28:38 UTC (rev 155) @@ -0,0 +1,130 @@ +<?php +/* + * Created on Jan 29, 2009 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_gdlObjectAbstract extends cs_webapplibsAbstract { + + + const table='cswal_gdl_object_table'; + const tableSeq = 'cswal_gdl_object_table_object_id_seq'; + + //------------------------------------------------------------------------- + public function get_object_id_from_path($path) { + $sql = "SELECT object_id FROM ". self::table ." WHERE object_path='". + $this->clean_path($path) ."'"; + + try { + $data = $this->db->run_query($sql); + + if(is_array($data) && count($data) == 1) { + $retval = $data['object_id']; + } + else { + throw new exception(__METHOD__ .": invalid data for path (". $this->clean_path($path) .")::: ". $this->gfObj->debug_var_dump($data,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": error retrieving path::: ". $e->getMessage()); + } + + return($retval); + }//end get_object_id_from_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function create_object($name, $data=null, $type=null) { + $sql = "INSERT INTO ". self::table ." (object_name) VALUES ('". + $this->gfObj->cleanString($this->clean_path($name), 'sql_insert') ."')"; + try { + $retval = $this->db->run_insert($sql, self::tableSeq); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to perform insert::: ". $e->getMessage()); + } + + if(!is_null($data)) { + throw new exception(__METHOD__ .": can't create data for objects yet"); + } + return($retval); + }//end create_object() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function build_object_id_list(array $objects) { + $this->gfObj->switch_force_sql_quotes(1); + $sql = "SELECT * FROM ". self::table ." WHERE object_name IN (". + $this->gfObj->string_from_array($objects, null, ',', 'sql') .")"; + $this->gfObj->switch_force_sql_quotes(0); + + $retval = array(); + try { + $retval = $this->db->run_query($sql, 'object_name', 'object_id'); + if(!is_array($retval)) { + $retval = array(); + } + } + catch(exception $e) { + //throw new exception(__METHOD__ .": failed to retrieve list"); + } + + return($retval); + }//end build_object_id_list() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function build_object_name_list(array $objectIds) { + $this->gfObj->switch_force_sql_quotes(1); + $sql = "SELECT * FROM ". self::table ." WHERE object_id IN (". + $this->gfObj->string_from_array($objectIds, null, ',', 'sql') .")"; + $this->gfObj->switch_force_sql_quotes(0); + + try { + $retval = $this->db->run_query($sql, 'object_id', 'object_name'); + if(!is_array($retval)) { + $retval = array(); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to retrieve list::: ". $e->getMessage()); + } + + return($retval); + }//end build_object_id_list() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function create_objects_enmasse(array $objectList) { + $retval = 0; + foreach($objectList as $name) { + try { + $this->create_object($name); + $retval++; + } + catch(exception $e) { + //nothing to see here, move along. + } + } + return($retval); + }//end create_objects_enmasse() + //------------------------------------------------------------------------- + + +} +?> \ No newline at end of file Copied: trunk/0.3/abstract/cs_gdlPath.abstract.class.php (from rev 154, trunk/0.3/abstract/cs_phpDB.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_gdlPath.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_gdlPath.abstract.class.php 2009-10-29 03:28:38 UTC (rev 155) @@ -0,0 +1,121 @@ +<?php +/* + * Created on Jan 29, 2009 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_gdlPathAbstract extends cs_gdlObjectAbstract { + + + const table='cswal_gdl_path_table'; + const tableSeq = 'cswal_gdl_path_table_path_id_seq'; + + + + + + //------------------------------------------------------------------------- + public function create_path($path) { + $idList = $this->create_path_objects($path); + $pathIdList = $this->create_id_path($idList); + + $sql = "INSERT INTO ". self::table ." (path_id_list) VALUES ('". $pathIdList ."')"; + + try { + $insertedId = $this->db->run_insert($sql, self::tableSeq); + $retval = $pathIdList; + } + catch(exception $e) { + throw new exception(__METHOD__ .": unable to create path::: ". $e->getMessage()); + } + + return($retval); + }//end create_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function clean_path($path, $appendBase=true) { + if(strlen($path)) { + if($appendBase === true && !is_null($this->basePath)) { + $path = $this->basePath .'/'. $path; + } + $newPath = preg_replace('/\/{2,}/', '/', $path); + + if(!strlen($newPath)) { + throw new exception(__METHOD__ .": new path is zero-length (". $newPath ."), old path=(". func_get_arg(0) .")"); + } + } + else { + throw new exception(__METHOD__ .": no valid path given (". $path .")"); + } + + return($newPath); + }//end clean_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function set_base_path($path) { + if(is_null($path) || !strlen($path)) { + $this->basePath = null; + } + else { + $this->basePath = $this->clean_path($path,false); + } + }//end set_base_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function explode_path($path, $appendBase=true) { + $path = $this->clean_path($path, $appendBase); + $path = preg_replace('/^\//', '', $path); + $path = preg_replace('/\/$/', '', $path); + + return(explode('/', $path)); + }//end explode_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function create_id_path(array $idList) { + $retval = ':'. $this->gfObj->string_from_array($idList, null, '::') .':'; + return($retval); + }//end create_id_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function get_text_path_from_id_path($idPath) { + + $idList = explode('::', preg_replace('/^:/', '', preg_replace('/:$/', '', $idPath))); + + $nameList = $this->build_object_name_list($idList); + $this->gfObj->debug_var_dump($nameList,1); + + $retval = "/"; + foreach($nameList as $id=>$name) { + $retval = $this->gfObj->create_list($retval, $name, '/'); + } + + $retval = $this->clean_path($retval,false); + + return($retval); + }//end get_text_path_from_id_path() + //------------------------------------------------------------------------- + +} +?> \ No newline at end of file Added: trunk/0.3/cs_genericDataLinker.class.php =================================================================== --- trunk/0.3/cs_genericDataLinker.class.php (rev 0) +++ trunk/0.3/cs_genericDataLinker.class.php 2009-10-29 03:28:38 UTC (rev 155) @@ -0,0 +1,101 @@ +<?php +/* + * Created on Oct 27, 2009 + * + * THE IDEA::: + * 1.) Unix/Linux-like paths lead to an attribute. + * 2.) Multiple paths can lead to the same attribute. + * 3.) An attribute can be linked to its original path. + * 4.) Each "directory" in a path is an object with an ID. + * 5.) Paths themselves are only stored on attributes: intermediate paths may be valid if all objects + * for that path are also valid (i.e. if "/one/two/three" is valid, so is "/two/one/three" and "/three/two/one"). + * 6.) Database... + * a.) finding an attribute referencing a single object should be straightforward and fast. + * b.) objects are unique to avoid excess duplicate pathways + * c.) using id paths with each number wrapped in colons is simple (i.e. ":3342:", ":3342::3::3:" + * + * The idea here is to have a class that generically links data together (in a + * database). It is not meant to be a super clean or speedy system, instead meant + * as a way of describing relationships between various pieces of data. + * + * Once a path is created (list object_id's, separated by '::'), it should always have an attribute. + * + * + * 1::2::3 -> select * from <bla> WHERE path = '2' OR path like '2::%' OR path like '%::2' + * -OR- + * :1::2::3: -> select * from <bla> WHERE path like '%:2:%' + * + * If an attribute is created with a small path (like "/test") and the id is 1, the attribute shows ":1:" + * --> if the id is 7720218, then the attribute shows ":7720218:" + * + * + * SVN INFORMATION::: + * ------------------- + * Last Author::::::::: $Author$ + * Current Revision:::: $Revision$ + * Repository Location: $HeadURL$ + * Last Updated:::::::: $Date$ + */ + + + +class cs_genericDataLinker extends cs_gdlAttribAbstract { + + const attrTable='cswal_gdl_attribute_table'; + const attrTableSeq='cswal_gdl_attribute_table_attribute_id_seq'; + + protected $validTypes = array('text', 'int', 'dec', 'bool'); + protected $gfObj; + protected $basePath=null; + + public $db; + + //------------------------------------------------------------------------- + public function __construct(cs_phpDB $db) { + + parent::__construct($db); + if(!$db->is_connected()) { + throw new exception(__METHOD__ .": database not connected"); + } + $this->db = $db; + $this->gfObj = new cs_globalFunctions; + }//end __construct() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function create_path_objects($path) { + $newPath = $this->clean_path($path); + $newPath = preg_replace('/^\//', '', $newPath); + + //break it into bits. + $bits = explode('/', $newPath); + + $myList = $this->build_object_id_list($bits); + if(count($myList) !== count($bits)) { + $createThese = array(); + foreach($bits as $name) { + if(!isset($myList[$name])) { + $createThese[] = $name; + } + } + $this->create_objects_enmasse($createThese); + $myList = $this->build_object_id_list($bits); + } + + $retval = array(); + foreach($bits as $name) { + $retval[$name] = $myList[$name]; + } + + if(is_null($retval) || !is_array($retval) || !count($retval)) { + throw new exception(__METHOD__ .": failed to build path objects... ". $retval); + } + + return($retval); + }//end create_path_objects() + //------------------------------------------------------------------------- +} + +?> Property changes on: trunk/0.3/cs_genericDataLinker.class.php ___________________________________________________________________ Added: svn:keywords + Author Revision HeadURL Date Modified: trunk/0.3/setup/schema.mysql.sql =================================================================== --- trunk/0.3/setup/schema.mysql.sql 2009-09-29 16:12:49 UTC (rev 154) +++ trunk/0.3/setup/schema.mysql.sql 2009-10-29 03:28:38 UTC (rev 155) @@ -166,7 +166,35 @@ UNIQUE KEY `project_name` (`project_name`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + -- +-- Table for cs_genericDataLinker{}. +-- +CREATE TABLE `cswal_gdl_object_table` ( + `object_id` int(11) NOT NULL PRIMARY KEY auto_increment, + `object_name` text NOT NULL UNIQUE +) ENGINE=InnoDB; + + +CREATE TABLE `cswal_gdl_path_table` ( + `path_id` int(11) NOT NULL PRIMARY KEY auto_increment, + `path_id_list` text NOT NULL +) ENGINE=InnoDB; + +-- +-- Store attributes here. +-- NOTE: fields prefixed with "a_" to avoid clashes with reserved words. +-- +CREATE TABLE `cswal_gdl_attribute_table` ( + `attribute_id` serial NOT NULL PRIMARY KEY auto_increment, + `object_path` text NOT NULL, + `a_text` text DEFAULT NULL, + `a_int` integer DEFAULT NULL, + `a_dec` decimal(10,2) DEFAULT NULL, + `a_bool` boolean DEFAULT NULL +) ENGINE=InnoDB; + +-- -- Constraints for dumped tables -- Modified: trunk/0.3/setup/schema.pgsql.sql =================================================================== --- trunk/0.3/setup/schema.pgsql.sql 2009-09-29 16:12:49 UTC (rev 154) +++ trunk/0.3/setup/schema.pgsql.sql 2009-10-29 03:28:38 UTC (rev 155) @@ -120,3 +120,29 @@ ); +-- +-- Table for cs_genericDataLinker{}. +-- +CREATE TABLE cswal_gdl_object_table ( + object_id serial NOT NULL PRIMARY KEY, + object_name text NOT NULL UNIQUE +); + + +CREATE TABLE cswal_gdl_path_table ( + path_id serial NOT NULL PRIMARY KEY, + path_id_list text NOT NULL +); + +-- +-- Store attributes here. +-- NOTE: fields prefixed with "a_" to avoid clashes with reserved words. +-- +CREATE TABLE cswal_gdl_attribute_table ( + attribute_id serial NOT NULL PRIMARY KEY, + object_path text NOT NULL, + a_text text DEFAULT NULL, + a_int integer DEFAULT NULL, + a_dec decimal(10,2) DEFAULT NULL, + a_bool boolean DEFAULT NULL +); Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-09-29 16:12:49 UTC (rev 154) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-10-29 03:28:38 UTC (rev 155) @@ -11,13 +11,15 @@ * $LastChangedRevision$ */ - class testOfCSWebAppLibs extends UnitTestCase { //-------------------------------------------------------------------------- function __construct() { $this->gfObj = new cs_globalFunctions; $this->gfObj->debugPrintOpt=1; + if(!defined('CS_UNITTEST')) { + throw new exception(__METHOD__ .": FATAL: constant 'CS_UNITTEST' not set, can't do testing safely"); + } }//end __construct() //-------------------------------------------------------------------------- @@ -45,7 +47,8 @@ $tableList = array( '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' + 'cswal_log_attribute_table', 'cswal_log_table', 'cswal_session_store_table', + 'cswal_gdl_object_table', 'cswal_gdl_attribute_table', 'cswal_gdl_path_table' ); $db = $this->create_dbconn(); @@ -199,6 +202,250 @@ //-------------------------------------------------------------------------- + function test_genericDataLinker() { + + $x = new gdlTester($this->create_dbconn()); + + //test objects & paths first. + { + $myPath = '/character/sheet///Tetra Tealeaf'; + + $this->assertEqual(array('character', 'sheet', 'Tetra Tealeaf'), $x->explode_path($myPath)); + $x->set_base_path('/testing'); + $this->assertEqual('/testing/character/sheet/Tetra Tealeaf', $x->clean_path($myPath)); + $this->assertEqual(array('testing', 'character', 'sheet', 'Tetra Tealeaf'), $x->explode_path($myPath)); + $x->set_base_path(null); + $this->assertNotEqual(array('testing', 'character', 'sheet', 'Tetra Tealeaf'), $x->explode_path($myPath)); + $this->assertEqual(array('character', 'sheet', 'Tetra Tealeaf'), $x->explode_path($myPath)); + $this->assertEqual('/character/sheet/Tetra Tealeaf', $x->clean_path($myPath)); + + //now create some objects. + $pathBits = array(); + foreach($x->explode_path($myPath) as $name) { + $pathBits[$x->create_object($name)] = $name; + } + $newPathIdList = $x->create_path($myPath); + $myPathIdList = ':'. $this->gfObj->string_from_array(array_keys($pathBits), null, '::') .':'; + $this->assertEqual($newPathIdList, $myPathIdList); + + $newId = $x->create_object('testing'); + $t = array_keys($pathBits); + $t = array_pop($t); + $lastPathId = $t; + $this->assertEqual($newId, ($lastPathId +1)); + + $oldBits = $pathBits; + $pathBits = array(); + $pathBits[$newId] = 'testing'; + foreach($oldBits as $id=>$name) { + $pathBits[$id] = $name; + } + + $newPathIdList = $x->create_path('/testing/'. $myPath); + $myPathIdList = ':'. $this->gfObj->string_from_array(array_flip($pathBits), null, '::') .':'; + $this->assertEqual($newPathIdList, $myPathIdList); + } + + + /*/basic tests for building text-based paths vs. id-based paths. + { + $myPath = '/character/sheet/Tetra Tealeaf'; + + + $idList = $x->createPathObjects($myPath); + + $testObjectIdList = explode('/', preg_replace('/^\//', '', $myPath)); + $this->assertEqual($idList, $x->build_object_id_list($testObjectIdList)); + + $idList2 = $x->create_path($myPath); + $this->assertEqual($x->create_id_path(array_values($idList)), $idList2); + + $this->assertEqual($myPath, $x->get_text_path_from_id_path($x->create_id_path($idList))); + $this->gfObj->debug_var_dump($x->get_text_path_from_id_path($x->create_id_path($idList))); + + $this->gfObj->debug_var_dump($idList); + $this->gfObj->debug_var_dump($idList2); + + $this->assertEqual(':1::2::3:', $idList2); + $this->assertEqual($idList2, ':'. $this->gfObj->string_from_array($idList, null, '::') .':'); + + $this->assertEqual(':1::2::3:', $x->create_id_path($idList)); + + $this->assertEqual(':1:', $x->create_id_path(array(1))); + $this->assertEqual(':000010:', $x->create_id_path(array('000010'))); + + } + + + // now REALLY test paths. + { + #$gdl = new gdlTester($this->create_dbconn()); + + $myBasePath = '/character/sheet/Xander Cage'; + $x->set_base_path($myBasePath); + + //now add something that should be BENEATH that path. + $idList = $x->create_path('attributes/str'); + + $this->gfObj->debug_var_dump($idList); + } + #*/ + + + + + /*/test some basics first. + $translations = array( + 'good' => array( + 'a_int' => array('int', 'integer', 'integraIsACarNotAnArgument'), + 'a_dec' => array('dec', 'decimal', 'decemberIsAMonth'), + 'a_bool' => array('bool', 'boolean', 'boolJustLooksLikeSomethingJiggly'), + 'a_text' => array('text', 'textual', 'textPaperJustLooksPink') + ), + 'bad' => array( + 'a_int' => array('num', 'a_int', 'nittedStuff'), + 'a_dec' => array('dce', 'a_dec', 'dceStuff'), + 'a_bool' => array('bolo', 'a_bool', 'boloMeansBeOnLookOut'), + 'a_text' => array('txt', 'a_text', 'txtIsABadAbbreviation') + ) + ); + + foreach($translations as $goodBad=>$matchesArray) { + foreach($matchesArray as $matchThis => $tryThese) { + foreach($tryThese as $k) { + try { + $this->assertEqual($matchThis, $x->translate_attrib_name($k)); + } + catch(exception $e) { + if($goodBad == 'good') { + $this->assertFalse(true, "test (". $k .") should have been good, but was bad::: ". $e->getMessage()); + } + } + } + } + } + $testData = array( + 'skills/Appraise/cc' => array('bool' => true), + 'skills/Appraise/mod' => array('int' => 3), + 'skills/Appraise/ab_mod' => array('int' => 3), + 'skills/Appraise/rank' => array('int' => 3), + 'skills/Appraise/misc_mod' => array('int' => 3), + 'skills/Appraise/notes' => array('text' => "Lorem ipsum dolor sit amet, consectetur adipiscing elit."), + 'skills/Appraise/test' => array( + 'text' => "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + 'bool' => true, + 'dec' => 0.03 + ), + ); + + + $myBasePath = '/characters/Tetra Tealeaf/'; + $x->set_base_path($myBasePath); + foreach($testData as $path=>$subData) { + $this->assertEqual($myBasePath . $path, $x->clean_path($path)); + $this->assertTrue(is_numeric($x->create_object($path, $subData))); + } + + //get each individual item about the skill 'Appraise' individually. + $x->get_object_attribs('skills/Appraise/cc', 'bool'); + $x->get_object_attribs('skills/Appraise/mod', 'int'); + $x->get_object_attribs('skills/Appraise/ab_mod', 'int'); + $x->get_object_attribs('skills/Appraise/rank', 'int'); + $x->get_object_attribs('skills/Appraise/misc_mod', 'int'); + $x->get_object_attribs('skills/Appraise/notes', 'text'); + $x->get_object_attribs('skills/Appraise/test', array('text', 'bool', 'dec')); + $returnVal = array( + 'text' => "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + 'bool' => true, + 'dec' => 0.03 + ); + + + //another way to retrieve it, without caring about what types are returned::: + $returnVal = $x->get_all_object_attribs('skills/Appraise', false); + $returnVal = array( + 'cc' => array( + 'test' => null, + 'bool' => true, + 'int' => null, + 'dec' => null + ), + 'mod' => array( + 'test' => null, + 'bool' => null, + 'int' => 10, + 'dec' => null + ), + 'ab_mod' => array( + 'test' => null, + 'bool' => null, + 'int' => 3, + 'dec' => null + ), + 'rank' => array( + 'test' => null, + 'bool' => null, + 'int' => 6, + 'dec' => null + ), + 'misc_mod' => array( + 'test' => null, + 'bool' => null, + 'int' => 1, + 'dec' => null + ), + 'notes' => array( + 'test' => "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + 'bool' => null, + 'int' => null, + 'dec' => null + ), + 'test' => array( + 'text' => "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + 'bool' => true, + 'int' => null, + 'dec' => 0.03 + ) + ); + + //a better way to retrieve that data: + $returnVal = $x->get_all_object_attribs('skills/Appraise', false); + $returnVal = array( + 'cc' => true, + 'mod' => 10, + 'ab_mod' => 3, + 'rank' => 6, + 'misc_mod' => 1, + 'notes' => "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + 'test' => array( + 'text' => "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + 'bool' => true, + 'dec' => 0.03 + ) + ); + + //if we don't want all that junk in test, we can specify what to get for EACH one: + $types = array( + 'cc' => "bool", + 'test' => "dec" + ); + $returnVal = $x->get_all_object_attribs('skills/Appraise', false, $types); + $returnVal = array( + 'cc' => true, + 'mod' => 10, + 'ab_mod' => 3, + 'rank' => 6, + 'misc_mod' => 1, + 'notes' => "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + 'test' => 0.03 + ); + #*/ + }//end test_genericDataLinker() + //-------------------------------------------------------------------------- + + + + //-------------------------------------------------------------------------- private function do_tokenTest(array $tokenData, $uid, $checksum) { if($this->assertTrue(is_array($tokenData)) && $this->assertTrue(is_numeric($uid)) && $this->assertTrue(strlen($checksum))) { @@ -213,6 +460,7 @@ }//end do_tokenTest() //-------------------------------------------------------------------------- + } @@ -226,4 +474,17 @@ return($this->create_hash_string($tokenId, $uid, $checksum, $hash)); } } + +class gdlTester extends cs_genericDataLinker { + public $isTest = true; + + public function __construct($db) { + parent::__construct($db); + } + + public function createPathObjects($path) { + return($this->create_path_objects($path)); + } +} + ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2009-11-09 18:48:36
|
Revision: 157 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=157&view=rev Author: crazedsanity Date: 2009-11-09 18:48:26 +0000 (Mon, 09 Nov 2009) Log Message: ----------- Minor changes. /abstract/cs_gdlPath.abstract.class.php: * create_path(): -- returns the pathIdList if available, otherwise creates the path. * get_text_path_from_id_path() [RENAMED to get_path_from_idlist()] * get_path_from_idlist() [NEW, RENAMED FROM get_text_path_from_id_path()] -- removed call to debug_var_dump(). /setup/schema.pgsql.sql: * make cswal_gdl_path_table.path_id_list UNIQUE. /setup/schema.mysql.sql: * make cswal_gdl_path_table.path_id_list UNIQUE. /tests/testOfCSWebAppLibs.php: * added more tests for get_path_from_idlist(). Modified Paths: -------------- trunk/0.3/abstract/cs_gdlPath.abstract.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/abstract/cs_gdlPath.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_gdlPath.abstract.class.php 2009-11-09 17:25:37 UTC (rev 156) +++ trunk/0.3/abstract/cs_gdlPath.abstract.class.php 2009-11-09 18:48:26 UTC (rev 157) @@ -26,14 +26,20 @@ $idList = $this->create_path_objects($path); $pathIdList = $this->create_id_path($idList); - $sql = "INSERT INTO ". self::table ." (path_id_list) VALUES ('". $pathIdList ."')"; - - try { - $insertedId = $this->db->run_insert($sql, self::tableSeq); + if($this->get_path_from_idlist($pathIdList)) { $retval = $pathIdList; } - catch(exception $e) { - throw new exception(__METHOD__ .": unable to create path::: ". $e->getMessage()); + else { + + $sql = "INSERT INTO ". self::table ." (path_id_list) VALUES ('". $pathIdList ."')"; + + try { + $insertedId = $this->db->run_insert($sql, self::tableSeq); + $retval = $pathIdList; + } + catch(exception $e) { + throw new exception(__METHOD__ .": unable to create path::: ". $e->getMessage()); + } } return($retval); @@ -99,12 +105,11 @@ //------------------------------------------------------------------------- - public function get_text_path_from_id_path($idPath) { + public function get_path_from_idlist($idPath) { $idList = explode('::', preg_replace('/^:/', '', preg_replace('/:$/', '', $idPath))); $nameList = $this->build_object_name_list($idList); - $this->gfObj->debug_var_dump($nameList,1); $retval = "/"; foreach($nameList as $id=>$name) { Modified: trunk/0.3/setup/schema.mysql.sql =================================================================== --- trunk/0.3/setup/schema.mysql.sql 2009-11-09 17:25:37 UTC (rev 156) +++ trunk/0.3/setup/schema.mysql.sql 2009-11-09 18:48:26 UTC (rev 157) @@ -178,7 +178,7 @@ CREATE TABLE `cswal_gdl_path_table` ( `path_id` int(11) NOT NULL PRIMARY KEY auto_increment, - `path_id_list` text NOT NULL + `path_id_list` text NOT NULL UNIQUE ) ENGINE=InnoDB; -- Modified: trunk/0.3/setup/schema.pgsql.sql =================================================================== --- trunk/0.3/setup/schema.pgsql.sql 2009-11-09 17:25:37 UTC (rev 156) +++ trunk/0.3/setup/schema.pgsql.sql 2009-11-09 18:48:26 UTC (rev 157) @@ -131,7 +131,7 @@ CREATE TABLE cswal_gdl_path_table ( path_id serial NOT NULL PRIMARY KEY, - path_id_list text NOT NULL + path_id_list text NOT NULL UNIQUE ); -- Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2009-11-09 17:25:37 UTC (rev 156) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2009-11-09 18:48:26 UTC (rev 157) @@ -244,6 +244,18 @@ $newPathIdList = $x->create_path('/testing/'. $myPath); $myPathIdList = ':'. $this->gfObj->string_from_array(array_flip($pathBits), null, '::') .':'; $this->assertEqual($newPathIdList, $myPathIdList); + + $this->assertEqual($newPathIdList, $x->create_path('/testing/'. $myPath)); + + $myRearrangedPath = array_reverse($pathBits, true); + $rPathIdList = ':'. $this->gfObj->string_from_array(array_flip($myRearrangedPath), null, '::') .':'; + $rPath = '/'. $this->gfObj->string_from_array($myRearrangedPath, null, '/'); + $this->assertEqual($x->create_path($rPath), $rPathIdList); + + $this->assertEqual($x->get_path_from_idlist($x->create_path($rPath)), $x->get_path_from_idlist($rPathIdList)); + $this->assertEqual($x->get_path_from_idlist($x->create_path($rPath)), $x->get_path_from_idlist($rPathIdList)); + $this->assertEqual($x->get_path_from_idlist($x->create_path($rPath)), $x->get_path_from_idlist($rPathIdList)); + $this->assertEqual($x->get_path_from_idlist($x->create_path($rPath)), $x->get_path_from_idlist($rPathIdList)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-05-13 18:16:16
|
Revision: 160 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=160&view=rev Author: crazedsanity Date: 2010-05-13 18:16:07 +0000 (Thu, 13 May 2010) Log Message: ----------- Stop passing some variables by reference to avoid some PHP errors (pass-by-reference isn't really supported like that anymore). Modified Paths: -------------- trunk/0.3/cs_siteConfig.class.php trunk/0.3/cs_webdbupgrade.class.php Modified: trunk/0.3/cs_siteConfig.class.php =================================================================== --- trunk/0.3/cs_siteConfig.class.php 2010-03-09 19:08:59 UTC (rev 159) +++ trunk/0.3/cs_siteConfig.class.php 2010-05-13 18:16:07 UTC (rev 160) @@ -259,7 +259,7 @@ $this->isInitialized=true; if(count($this->setGlobalArrays)) { - $globA2p = new cs_arrayToPath(&$GLOBALS); + $globA2p = new cs_arrayToPath($GLOBALS); foreach($this->setGlobalArrays as $configPath=>$globalsPath) { if($this->a2p->get_data($configPath)) { $setMe = array(); Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2010-03-09 19:08:59 UTC (rev 159) +++ trunk/0.3/cs_webdbupgrade.class.php 2010-05-13 18:16:07 UTC (rev 160) @@ -858,7 +858,7 @@ $this->tempXmlConfig = array(); } try { - $myA2p = new cs_arrayToPath(&$this->tempXmlConfig); + $myA2p = new cs_arrayToPath($this->tempXmlConfig); } catch(exception $e) { $this->do_log(__METHOD__ .': encountered exception: '. $e->getMessage()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-06-15 02:12:32
|
Revision: 166 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=166&view=rev Author: crazedsanity Date: 2010-06-15 02:12:26 +0000 (Tue, 15 Jun 2010) Log Message: ----------- Remove generic data linker. Removed Paths: ------------- trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php trunk/0.3/abstract/cs_gdlObject.abstract.class.php trunk/0.3/abstract/cs_gdlPath.abstract.class.php trunk/0.3/cs_genericDataLinker.class.php Deleted: trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php 2010-06-15 02:10:54 UTC (rev 165) +++ trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php 2010-06-15 02:12:26 UTC (rev 166) @@ -1,89 +0,0 @@ -<?php -/* - * Created on Jan 29, 2009 - * - * FILE INFORMATION: - * - * $HeadURL$ - * $Id$ - * $LastChangedDate$ - * $LastChangedBy$ - * $LastChangedRevision$ - */ - -abstract class cs_gdlAttribAbstract extends cs_gdlPathAbstract { - - - const table='cswal_gdl_attribute_table'; - const tableSeq = 'cswal_gdl_attribute_table_attribute_id_seq'; - - - - //------------------------------------------------------------------------- - public function create_attrib($path, $data, $type=null) { - - $objectId = $this->get_object_id_from_path($path); - - $insertString = ""; - $attribs = array(); - if(is_array($data) && count($data)) { - foreach($data as $n=>$v) { - $n = $this->translate_attrib_name($n); - $attribs[$n] = $v; - } - } - elseif(!is_null($type)) { - $key = $this->translate_attrib_name($type); - $attribs = array($key => $data); - } - else { - throw new exception(__METHOD__ .": data was not array and no type set"); - } - - if(!is_array($attribs) || !count($attribs)) { - throw new exception(__METHOD__ .": failed to create an array of attributes... ". $this->gfObj->debug_print(func_get_args(),0)); - } - - $attribs['object_id'] = $objectId; - $insertString = $this->gfObj->string_from_array($attribs, 'insert'); - - - if(!strlen($insertString)) { - throw new exception(__METHOD__ .": invalid insert string (". $insertString .")"); - } - $sql = "INSERT INTO ". self::attrTable ." ". $insertString; - - try { - $retval = $this->db->run_insert($sql, self::attrTableSeq); - } - catch(exception $e) { - throw new exception(__METHOD__ .": failed to perform insert::: ". $e->getMessage() .' ---- '. $sql); - } - - return($retval); - }//end create_attrib() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function translate_attrib_name($name) { - $retval = null; - foreach($this->validTypes as $type) { - if(preg_match('/^'. $type .'/', $name)) { - $retval = 'a_'. $type; - break; - } - } - - if(is_null($retval) || !strlen($retval)) { - $this->gfObj->debug_print(__METHOD__ .": name was (". $name ."), retval=(". $retval .")",1); - throw new exception(__METHOD__ .": invalid attribute name (". $name .")"); - } - - return($retval); - }//end translate_attrib_name() - //------------------------------------------------------------------------- - -} -?> \ No newline at end of file Deleted: trunk/0.3/abstract/cs_gdlObject.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_gdlObject.abstract.class.php 2010-06-15 02:10:54 UTC (rev 165) +++ trunk/0.3/abstract/cs_gdlObject.abstract.class.php 2010-06-15 02:12:26 UTC (rev 166) @@ -1,130 +0,0 @@ -<?php -/* - * Created on Jan 29, 2009 - * - * FILE INFORMATION: - * - * $HeadURL$ - * $Id$ - * $LastChangedDate$ - * $LastChangedBy$ - * $LastChangedRevision$ - */ - -abstract class cs_gdlObjectAbstract extends cs_webapplibsAbstract { - - - const table='cswal_gdl_object_table'; - const tableSeq = 'cswal_gdl_object_table_object_id_seq'; - - //------------------------------------------------------------------------- - public function get_object_id_from_path($path) { - $sql = "SELECT object_id FROM ". self::table ." WHERE object_path='". - $this->clean_path($path) ."'"; - - try { - $data = $this->db->run_query($sql); - - if(is_array($data) && count($data) == 1) { - $retval = $data['object_id']; - } - else { - throw new exception(__METHOD__ .": invalid data for path (". $this->clean_path($path) .")::: ". $this->gfObj->debug_var_dump($data,0)); - } - } - catch(exception $e) { - throw new exception(__METHOD__ .": error retrieving path::: ". $e->getMessage()); - } - - return($retval); - }//end get_object_id_from_path() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function create_object($name, $data=null, $type=null) { - $sql = "INSERT INTO ". self::table ." (object_name) VALUES ('". - $this->gfObj->cleanString($this->clean_path($name), 'sql_insert') ."')"; - try { - $retval = $this->db->run_insert($sql, self::tableSeq); - } - catch(exception $e) { - throw new exception(__METHOD__ .": failed to perform insert::: ". $e->getMessage()); - } - - if(!is_null($data)) { - throw new exception(__METHOD__ .": can't create data for objects yet"); - } - return($retval); - }//end create_object() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function build_object_id_list(array $objects) { - $this->gfObj->switch_force_sql_quotes(1); - $sql = "SELECT * FROM ". self::table ." WHERE object_name IN (". - $this->gfObj->string_from_array($objects, null, ',', 'sql') .")"; - $this->gfObj->switch_force_sql_quotes(0); - - $retval = array(); - try { - $retval = $this->db->run_query($sql, 'object_name', 'object_id'); - if(!is_array($retval)) { - $retval = array(); - } - } - catch(exception $e) { - //throw new exception(__METHOD__ .": failed to retrieve list"); - } - - return($retval); - }//end build_object_id_list() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function build_object_name_list(array $objectIds) { - $this->gfObj->switch_force_sql_quotes(1); - $sql = "SELECT * FROM ". self::table ." WHERE object_id IN (". - $this->gfObj->string_from_array($objectIds, null, ',', 'sql') .")"; - $this->gfObj->switch_force_sql_quotes(0); - - try { - $retval = $this->db->run_query($sql, 'object_id', 'object_name'); - if(!is_array($retval)) { - $retval = array(); - } - } - catch(exception $e) { - throw new exception(__METHOD__ .": failed to retrieve list::: ". $e->getMessage()); - } - - return($retval); - }//end build_object_id_list() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function create_objects_enmasse(array $objectList) { - $retval = 0; - foreach($objectList as $name) { - try { - $this->create_object($name); - $retval++; - } - catch(exception $e) { - //nothing to see here, move along. - } - } - return($retval); - }//end create_objects_enmasse() - //------------------------------------------------------------------------- - - -} -?> \ No newline at end of file Deleted: trunk/0.3/abstract/cs_gdlPath.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_gdlPath.abstract.class.php 2010-06-15 02:10:54 UTC (rev 165) +++ trunk/0.3/abstract/cs_gdlPath.abstract.class.php 2010-06-15 02:12:26 UTC (rev 166) @@ -1,126 +0,0 @@ -<?php -/* - * Created on Jan 29, 2009 - * - * FILE INFORMATION: - * - * $HeadURL$ - * $Id$ - * $LastChangedDate$ - * $LastChangedBy$ - * $LastChangedRevision$ - */ - -abstract class cs_gdlPathAbstract extends cs_gdlObjectAbstract { - - - const table='cswal_gdl_path_table'; - const tableSeq = 'cswal_gdl_path_table_path_id_seq'; - - - - - - //------------------------------------------------------------------------- - public function create_path($path) { - $idList = $this->create_path_objects($path); - $pathIdList = $this->create_id_path($idList); - - if($this->get_path_from_idlist($pathIdList)) { - $retval = $pathIdList; - } - else { - - $sql = "INSERT INTO ". self::table ." (path_id_list) VALUES ('". $pathIdList ."')"; - - try { - $insertedId = $this->db->run_insert($sql, self::tableSeq); - $retval = $pathIdList; - } - catch(exception $e) { - throw new exception(__METHOD__ .": unable to create path::: ". $e->getMessage()); - } - } - - return($retval); - }//end create_path() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function clean_path($path, $appendBase=true) { - if(strlen($path)) { - if($appendBase === true && !is_null($this->basePath)) { - $path = $this->basePath .'/'. $path; - } - $newPath = preg_replace('/\/{2,}/', '/', $path); - - if(!strlen($newPath)) { - throw new exception(__METHOD__ .": new path is zero-length (". $newPath ."), old path=(". func_get_arg(0) .")"); - } - } - else { - throw new exception(__METHOD__ .": no valid path given (". $path .")"); - } - - return($newPath); - }//end clean_path() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function set_base_path($path) { - if(is_null($path) || !strlen($path)) { - $this->basePath = null; - } - else { - $this->basePath = $this->clean_path($path,false); - } - }//end set_base_path() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function explode_path($path, $appendBase=true) { - $path = $this->clean_path($path, $appendBase); - $path = preg_replace('/^\//', '', $path); - $path = preg_replace('/\/$/', '', $path); - - return(explode('/', $path)); - }//end explode_path() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function create_id_path(array $idList) { - $retval = ':'. $this->gfObj->string_from_array($idList, null, '::') .':'; - return($retval); - }//end create_id_path() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function get_path_from_idlist($idPath) { - - $idList = explode('::', preg_replace('/^:/', '', preg_replace('/:$/', '', $idPath))); - - $nameList = $this->build_object_name_list($idList); - - $retval = "/"; - foreach($nameList as $id=>$name) { - $retval = $this->gfObj->create_list($retval, $name, '/'); - } - - $retval = $this->clean_path($retval,false); - - return($retval); - }//end get_text_path_from_id_path() - //------------------------------------------------------------------------- - -} -?> \ No newline at end of file Deleted: trunk/0.3/cs_genericDataLinker.class.php =================================================================== --- trunk/0.3/cs_genericDataLinker.class.php 2010-06-15 02:10:54 UTC (rev 165) +++ trunk/0.3/cs_genericDataLinker.class.php 2010-06-15 02:12:26 UTC (rev 166) @@ -1,101 +0,0 @@ -<?php -/* - * Created on Oct 27, 2009 - * - * THE IDEA::: - * 1.) Unix/Linux-like paths lead to an attribute. - * 2.) Multiple paths can lead to the same attribute. - * 3.) An attribute can be linked to its original path. - * 4.) Each "directory" in a path is an object with an ID. - * 5.) Paths themselves are only stored on attributes: intermediate paths may be valid if all objects - * for that path are also valid (i.e. if "/one/two/three" is valid, so is "/two/one/three" and "/three/two/one"). - * 6.) Database... - * a.) finding an attribute referencing a single object should be straightforward and fast. - * b.) objects are unique to avoid excess duplicate pathways - * c.) using id paths with each number wrapped in colons is simple (i.e. ":3342:", ":3342::3::3:" - * - * The idea here is to have a class that generically links data together (in a - * database). It is not meant to be a super clean or speedy system, instead meant - * as a way of describing relationships between various pieces of data. - * - * Once a path is created (list object_id's, separated by '::'), it should always have an attribute. - * - * - * 1::2::3 -> select * from <bla> WHERE path = '2' OR path like '2::%' OR path like '%::2' - * -OR- - * :1::2::3: -> select * from <bla> WHERE path like '%:2:%' - * - * If an attribute is created with a small path (like "/test") and the id is 1, the attribute shows ":1:" - * --> if the id is 7720218, then the attribute shows ":7720218:" - * - * - * SVN INFORMATION::: - * ------------------- - * Last Author::::::::: $Author$ - * Current Revision:::: $Revision$ - * Repository Location: $HeadURL$ - * Last Updated:::::::: $Date$ - */ - - - -class cs_genericDataLinker extends cs_gdlAttribAbstract { - - const attrTable='cswal_gdl_attribute_table'; - const attrTableSeq='cswal_gdl_attribute_table_attribute_id_seq'; - - protected $validTypes = array('text', 'int', 'dec', 'bool'); - protected $gfObj; - protected $basePath=null; - - public $db; - - //------------------------------------------------------------------------- - public function __construct(cs_phpDB $db) { - - parent::__construct($db); - if(!$db->is_connected()) { - throw new exception(__METHOD__ .": database not connected"); - } - $this->db = $db; - $this->gfObj = new cs_globalFunctions; - }//end __construct() - //------------------------------------------------------------------------- - - - - //------------------------------------------------------------------------- - public function create_path_objects($path) { - $newPath = $this->clean_path($path); - $newPath = preg_replace('/^\//', '', $newPath); - - //break it into bits. - $bits = explode('/', $newPath); - - $myList = $this->build_object_id_list($bits); - if(count($myList) !== count($bits)) { - $createThese = array(); - foreach($bits as $name) { - if(!isset($myList[$name])) { - $createThese[] = $name; - } - } - $this->create_objects_enmasse($createThese); - $myList = $this->build_object_id_list($bits); - } - - $retval = array(); - foreach($bits as $name) { - $retval[$name] = $myList[$name]; - } - - if(is_null($retval) || !is_array($retval) || !count($retval)) { - throw new exception(__METHOD__ .": failed to build path objects... ". $retval); - } - - return($retval); - }//end create_path_objects() - //------------------------------------------------------------------------- -} - -?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-06-15 02:16:18
|
Revision: 168 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=168&view=rev Author: crazedsanity Date: 2010-06-15 02:16:11 +0000 (Tue, 15 Jun 2010) Log Message: ----------- The beginnings of a generic permissions system. Added Paths: ----------- trunk/0.3/abstract/cs_genericGroup.abstract.class.php trunk/0.3/abstract/cs_genericPermission.abstract.class.php trunk/0.3/abstract/cs_genericPermissionGroup.abstract.class.php trunk/0.3/docs/example_genericPermission.php trunk/0.3/setup/genericPermissions.pgsql.sql Copied: trunk/0.3/abstract/cs_genericGroup.abstract.class.php (from rev 162, trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_genericGroup.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_genericGroup.abstract.class.php 2010-06-15 02:16:11 UTC (rev 168) @@ -0,0 +1,96 @@ +<?php + +/* + * Created on June 03, 2010 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_genericGroupAbstract extends cs_genericPermissionAbstract { + + /** Table name used to store groups. */ + const groupTable = "cswal_group_table"; + + /** Sequence for groups table. */ + const groupSeq = "cswal_group_table_group_id_seq"; + + //============================================================================ + public abstract function __construct(cs_phpDB $db) { + parent::__construct($db); + }//end __construct() + //============================================================================ + + + + //============================================================================ + protected function clean_group_name($groupName) { + try { + $retval = $this->clean_permission_name($groupName); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to clean group name (". $groupName .")"); + } + return($retval); + }//end clean_group_name() + //============================================================================ + + + + //============================================================================ + public function create_group($groupName) { + try { + $groupName = $this->clean_group_name($groupName); + $sql = "INSERT INTO ". self::groupTable ." (group_name) VALUES ('". $groupName ."')"; + $newId = $this->db->run_insert($sql, self::groupSeq); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to create group (". $groupName ."), DETAILS::: ". $e->getMessage()); + } + return($newId); + }//end create_group() + //============================================================================ + + + + //============================================================================ + public function get_group($groupName) { + try { + $groupName = $this->clean_group_name($groupName); + $sql = "SELECT * FROM ". self::groupTable ." WHERE group_name='". $groupName ."'"; + $retval = $this->db->run_query($sql); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to locate group (". $groupName ."), DETAILS::: ". $e->getMessage()); + } + return($retval); + }//end get_group() + //============================================================================ + + + + //============================================================================ + public function get_group_by_id($groupId) { + try { + if(!is_null($groupId) && is_numeric($groupId)) { + $sql = "SELECT * FROM ". self::groupTable ." WHERE group_id='". $groupId ."'"; + $retval = $this->db->run_query($sql); + } + else { + throw new exception(__METHOD__ .":: invalid group ID (". $groupId .")"); + } + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to locate group ID (". $groupId ."), DETAILS::: ". $e->getMessage()); + } + return($retval); + }//end get_group_by_id() + //============================================================================ + +} +?> Copied: trunk/0.3/abstract/cs_genericPermission.abstract.class.php (from rev 162, trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_genericPermission.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_genericPermission.abstract.class.php 2010-06-15 02:16:11 UTC (rev 168) @@ -0,0 +1,122 @@ +<?php +/* + * Created on June 03, 2010 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_genericPermissionAbstract extends cs_webapplibsAbstract { + + /** Database object. */ + public $db; + + /** cs_globalFunctions object, for cleaning strings & such. */ + public $gfObj; + + /** Table name used to store permissions. */ + const permTable = "cswal_permission_table"; + + /** Sequence for permissions table. */ + const permSeq = "cswal_permission_table_permission_id"; + + //============================================================================ + public abstract function __construct(cs_phpDB $db) { + $this->db = $db; + $this->gfObj = new cs_globalFunctions; + }//end __construct() + //============================================================================ + + + + //============================================================================ + protected function clean_permission_name($name) { + if(!is_null($name) && is_string($name) && strlen($name)) { + $name = $this->gfObj->cleanString(strtolower($name), 'email'); + } + else { + throw new exception(__METHOD__ .":: invalid string (". $name .")"); + } + }//end clean_permission_name() + //============================================================================ + + + + //============================================================================ + public function create_permission($name) { + try{ + $name = $this->clean_permission_name($name); + $sql = "INSERT INTO ". self::permTable ." (permission_name) VALUES ('". $name ."')"; + $newId = $this->db->run_insert($sql, self::permSeq); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to create new record, DETAILS::: ". $e->getMessage()); + } + + return($newId); + }//end create_permission() + //============================================================================ + + + + //============================================================================ + public function get_permission($name) { + try { + $name = $this->clean_permission_name($name); + $sql = "SELECT * FROM ". self::permTable ." WHERE permission_name='". $name ."'"; + $retval = $this->db->run_query($sql); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: error while locating permission '". $name ."', DETAILS::: ". $e->getMessage()); + } + + return($retval); + }//end get_permission() + //============================================================================ + + + + //============================================================================ + public function get_permission_by_id($permId) { + try { + if(!is_null($permId) && is_numeric($permId)) { + $sql = "SELECT * FROM ". self::permTable ." WHERE permission_id='". $permId ."'"; + $retval = $this->db->run_query($sql); + } + else { + throw new exception(__METHOD__ .":: invalid permission ID (". $permId .")"); + } + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: error while locating permission '". $permId ."', DETAILS::: ". $e->getMessage()); + } + + return($retval); + }//end get_permission_by_id() + //============================================================================ + + + + //============================================================================ + /** + * Build the schema for permissions. + */ + private function build_schema() { + try { + $result = $this->db->run_sql_file(dirname(__FILE__) .'/../setup/genericPermissions.pgsql.sql'); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to create schema, DETAILS::: ". $e->getMessage()); + } + if($result !== true) { + throw new exception(__METHOD__ .":: failed to create schema (no details)"); + } + }//end build_schema() + //============================================================================ +} +?> Copied: trunk/0.3/abstract/cs_genericPermissionGroup.abstract.class.php (from rev 162, trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_genericPermissionGroup.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_genericPermissionGroup.abstract.class.php 2010-06-15 02:16:11 UTC (rev 168) @@ -0,0 +1,96 @@ +<?php + +/* + * Created on June 14, 2010 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_genericPermissionGroupAbstract extends cs_genericGroupAbstract { + + /** Table name used to store permission groups. */ + const permGroupTable = "cswal_permission_group_table"; + + /** Sequence for permission_group table. */ + const groupSeq = "cswal_permission_group_table_permission_group_id_seq"; + + //============================================================================ + public abstract function __construct(cs_phpDB $db) { + parent::__construct($db); + }//end __construct() + //============================================================================ + + + + //============================================================================ + protected function clean_perm_group_name($permGroupName) { + try { + $retval = $this->clean_group_name($permGroupName); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to clean group name (". $groupName .")"); + } + return($retval); + }//end clean_perm_group_name() + //============================================================================ + + + + //============================================================================ + public function create_group($groupName) { + try { + $groupName = $this->clean_group_name($groupName); + $sql = "INSERT INTO ". self::groupTable ." (group_name) VALUES ('". $groupName ."')"; + $newId = $this->db->run_insert($sql, self::groupSeq); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to create group (". $groupName ."), DETAILS::: ". $e->getMessage()); + } + return($newId); + }//end create_group() + //============================================================================ + + + + //============================================================================ + public function get_group($groupName) { + try { + $groupName = $this->clean_group_name($groupName); + $sql = "SELECT * FROM ". self::groupTable ." WHERE group_name='". $groupName ."'"; + $retval = $this->db->run_query($sql); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to locate group (". $groupName ."), DETAILS::: ". $e->getMessage()); + } + return($retval); + }//end get_group() + //============================================================================ + + + + //============================================================================ + public function get_group_by_id($groupId) { + try { + if(!is_null($groupId) && is_numeric($groupId)) { + $sql = "SELECT * FROM ". self::groupTable ." WHERE group_id='". $groupId ."'"; + $retval = $this->db->run_query($sql); + } + else { + throw new exception(__METHOD__ .":: invalid group ID (". $groupId .")"); + } + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to locate group ID (". $groupId ."), DETAILS::: ". $e->getMessage()); + } + return($retval); + }//end get_group_by_id() + //============================================================================ + +} +?> Added: trunk/0.3/docs/example_genericPermission.php =================================================================== --- trunk/0.3/docs/example_genericPermission.php (rev 0) +++ trunk/0.3/docs/example_genericPermission.php 2010-06-15 02:16:11 UTC (rev 168) @@ -0,0 +1,53 @@ +<?php + +//instantiate the permission object with a database & the proper UID. +$permObj = new cs_genericUserPermission($page->db, $_SESSION['uid']); + + +//Creating Permissions/Groups +{ + //create a group. + $permObj->create_group("blogs"); + + //define default permissions for the group. + //NOTE::: the "false" entries can be technically excluded, as the default is false. + $perms = array( + 'view' => true, + 'create' => true, + 'edit' => true, + 'set_timestamp' => true, + 'update_timestamp' => false, + 'delete_entry' => false, + 'set_draft' => true, + 'update_to_draft' => false + ); + $permObj->set_group_perms("blogs", $perms); + + //set specific permissions for a user. + //NOTE::: if the group or permission doesn't exist, this will throw an exception. + $permObj->set_user_perm("blogs", "update_timestamp"); +} + + +//Checking Permissions/Groups +{ + //get a list of permissions... + $perms = $permObj->get_user_permissions(); + + //check if the user is part of a group... in this case, the "blogs" group. + $isGroupMember = $permObj->check_group_membership("blogs"); + + //Pull all available permissions for a group... again, the "blogs" group. + $allBlogsPerms = $permObj->get_group_perms("blogs"); + + //check permissions for a specific "group" (or "object")... in this case, "can the user create a blog?" + $hasPermission = $permObj->check_permission("blogs", "create"); + + + //a more advanced check, involving membership in multiple cascading groups (unimplemented)... "can the user administratively view blogs?" + //NOTE::: the code in this method would have to allow an unlimited number of arguments (minimum 2), where the last one is the permission name. + #$permObj->check_cascading_permission("admin", "blogs", "view"); +} + + +?> Property changes on: trunk/0.3/docs/example_genericPermission.php ___________________________________________________________________ Added: svn:mime-type + text/plain Added: trunk/0.3/setup/genericPermissions.pgsql.sql =================================================================== --- trunk/0.3/setup/genericPermissions.pgsql.sql (rev 0) +++ trunk/0.3/setup/genericPermissions.pgsql.sql 2010-06-15 02:16:11 UTC (rev 168) @@ -0,0 +1,58 @@ + +-- +-- Permission table +-- Specific permissions: these are words used by the code to determine if the user has the appropriate permission. +-- +CREATE TABLE cswal_permission_table ( + permission_id serial NOT NULL PRIMARY KEY, + permission_name text NOT NULL UNIQUE +); + + +-- +-- Group table +-- Enumerates a list of permissions for a specific group: i.e. for "blog", this could list "create", "edit", and "delete" (among others). +-- +CREATE TABLE cswal_group_table ( + group_id serial NOT NULL PRIMARY KEY, + group_name text NOT NULL UNIQUE +); + +-- +-- Permission + Group table +-- Enumerates permissions for a given group: any permissions not specifically entered are denied. +-- +CREATE TABLE cswal_permission_group_table ( + permission_group_id serial NOT NULL PRIMARY KEY, + permission_id integer NOT NULL REFERENCES cswal_permission_table(permission_id), + group_id integer NOT NULL REFERENCES cswal_group_table(group_id), + allowed boolean NOT NULL DEFAULT false, + description text +); + +-- +-- User + Group table +-- Assigns a user to one or more groups. +-- NOTE::: the "user_id" column should be (manually) foreign-keyed to an existing user table. +-- +CREATE TABLE cswal_user_group_table ( + user_group_id serial NOT NULL PRIMARY KEY, + user_id integer NOT NULL, + group_id integer NOT NULL REFERENCES cswal_group_table(group_id) +); + + +-- +-- User + Permission table +-- Give users specific permissions, overriding default and/or assigned group permissions. +-- +CREATE TABLE cswal_user_permission_table ( + user_permission_id serial NOT NULL PRIMARY KEY, + user_id integer NOT NULL, + group_id integer NOT NULL REFERENCES cswal_group_table(group_id), + permission_id integer NOT NULL REFERENCES cswal_permission_table(permission_id), + allowed boolean NOT NULL DEFAULT false +); + + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-06-21 14:30:04
|
Revision: 169 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=169&view=rev Author: crazedsanity Date: 2010-06-21 14:29:53 +0000 (Mon, 21 Jun 2010) Log Message: ----------- Add generic permissions system, fix an error with upgrade system, documentation. /docs/README.txt: * added some documentation for CS Generic Permissions. /setup/genericPermissions.pgsql.sql: * no permission table anymore * group_table has an admin (group_admin) column * no more permission_group table * added FKey to user_group table * added object table with *nix-like permissions. * added list of example permissions... /tests/testOfCSWebAppLibs.php: * remove_tables(): -- added tables for the permissions stuff. * renamed "test_genericDataLinker()" to "tst_genericDataLinker()" so it would not run (planning on resurrecting the generic data linker). * commented-out the extra "gdlTester" class. /abstract/cs_genericPermissionGroup.abstract.class.php [DELETED] /abstract/cs_genericPermission.abstract.class.php [DELETED] /abstract/cs_genericUserGroup.abstract.class.php [NEW,COPIED]: * updated some internal vars & such for new class name. /abstract/cs_genericGroup.abstract.class.php: * extends cs_webapplibsAbstract /abstract/cs_group.abstract.class.php [NEW,COPIED]: * updated some internal vars & such for new class name. /cs_genericPermission.class.php: * MAIN::: -- extends cs_genericUserGroup. -- rename internal vars to reference the object table. * __construct(): -- call parent constructor -- setup keys array for permissions. * clean_permission_name() [DELETED]: -- handled in another class... * _sanityCheck() [NEW]: -- checks to make sure internal things are good. * parse_permission_string() [NEW]: -- parses a string like "rwxrw-r--" into the appropriate column names. * build_permission_string() [NEW]: -- create a string like "rwxrw-r--" (reverse of parse_permission_string()). * create_object() [NEW]: -- same as calling create_permission(). * create_permission(): -- revamped to use the object table. * get_object() [NEW]: -- like calling get_permission() * get_permission(): -- updated to use the permission table. * get_object_by_id() [NEW]: -- just like calling get_permission_by_id(). * get_permission_by_id(): -- like the name implies. /cs_webdbupgrade.class.php: * get_database_version(): -- return data after table loaded (thanks to unit testing). Modified Paths: -------------- trunk/0.3/abstract/cs_genericGroup.abstract.class.php trunk/0.3/cs_webdbupgrade.class.php trunk/0.3/docs/README.txt trunk/0.3/setup/genericPermissions.pgsql.sql trunk/0.3/tests/testOfCSWebAppLibs.php Added Paths: ----------- trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php trunk/0.3/abstract/cs_group.abstract.class.php trunk/0.3/cs_genericPermission.class.php Removed Paths: ------------- trunk/0.3/abstract/cs_genericPermission.abstract.class.php trunk/0.3/abstract/cs_genericPermissionGroup.abstract.class.php Modified: trunk/0.3/abstract/cs_genericGroup.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_genericGroup.abstract.class.php 2010-06-15 02:16:11 UTC (rev 168) +++ trunk/0.3/abstract/cs_genericGroup.abstract.class.php 2010-06-21 14:29:53 UTC (rev 169) @@ -12,7 +12,7 @@ * $LastChangedRevision$ */ -abstract class cs_genericGroupAbstract extends cs_genericPermissionAbstract { +abstract class cs_genericGroupAbstract extends cs_webapplibsAbstract { /** Table name used to store groups. */ const groupTable = "cswal_group_table"; Deleted: trunk/0.3/abstract/cs_genericPermission.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_genericPermission.abstract.class.php 2010-06-15 02:16:11 UTC (rev 168) +++ trunk/0.3/abstract/cs_genericPermission.abstract.class.php 2010-06-21 14:29:53 UTC (rev 169) @@ -1,122 +0,0 @@ -<?php -/* - * Created on June 03, 2010 - * - * FILE INFORMATION: - * - * $HeadURL$ - * $Id$ - * $LastChangedDate$ - * $LastChangedBy$ - * $LastChangedRevision$ - */ - -abstract class cs_genericPermissionAbstract extends cs_webapplibsAbstract { - - /** Database object. */ - public $db; - - /** cs_globalFunctions object, for cleaning strings & such. */ - public $gfObj; - - /** Table name used to store permissions. */ - const permTable = "cswal_permission_table"; - - /** Sequence for permissions table. */ - const permSeq = "cswal_permission_table_permission_id"; - - //============================================================================ - public abstract function __construct(cs_phpDB $db) { - $this->db = $db; - $this->gfObj = new cs_globalFunctions; - }//end __construct() - //============================================================================ - - - - //============================================================================ - protected function clean_permission_name($name) { - if(!is_null($name) && is_string($name) && strlen($name)) { - $name = $this->gfObj->cleanString(strtolower($name), 'email'); - } - else { - throw new exception(__METHOD__ .":: invalid string (". $name .")"); - } - }//end clean_permission_name() - //============================================================================ - - - - //============================================================================ - public function create_permission($name) { - try{ - $name = $this->clean_permission_name($name); - $sql = "INSERT INTO ". self::permTable ." (permission_name) VALUES ('". $name ."')"; - $newId = $this->db->run_insert($sql, self::permSeq); - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to create new record, DETAILS::: ". $e->getMessage()); - } - - return($newId); - }//end create_permission() - //============================================================================ - - - - //============================================================================ - public function get_permission($name) { - try { - $name = $this->clean_permission_name($name); - $sql = "SELECT * FROM ". self::permTable ." WHERE permission_name='". $name ."'"; - $retval = $this->db->run_query($sql); - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: error while locating permission '". $name ."', DETAILS::: ". $e->getMessage()); - } - - return($retval); - }//end get_permission() - //============================================================================ - - - - //============================================================================ - public function get_permission_by_id($permId) { - try { - if(!is_null($permId) && is_numeric($permId)) { - $sql = "SELECT * FROM ". self::permTable ." WHERE permission_id='". $permId ."'"; - $retval = $this->db->run_query($sql); - } - else { - throw new exception(__METHOD__ .":: invalid permission ID (". $permId .")"); - } - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: error while locating permission '". $permId ."', DETAILS::: ". $e->getMessage()); - } - - return($retval); - }//end get_permission_by_id() - //============================================================================ - - - - //============================================================================ - /** - * Build the schema for permissions. - */ - private function build_schema() { - try { - $result = $this->db->run_sql_file(dirname(__FILE__) .'/../setup/genericPermissions.pgsql.sql'); - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to create schema, DETAILS::: ". $e->getMessage()); - } - if($result !== true) { - throw new exception(__METHOD__ .":: failed to create schema (no details)"); - } - }//end build_schema() - //============================================================================ -} -?> Deleted: trunk/0.3/abstract/cs_genericPermissionGroup.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_genericPermissionGroup.abstract.class.php 2010-06-15 02:16:11 UTC (rev 168) +++ trunk/0.3/abstract/cs_genericPermissionGroup.abstract.class.php 2010-06-21 14:29:53 UTC (rev 169) @@ -1,96 +0,0 @@ -<?php - -/* - * Created on June 14, 2010 - * - * FILE INFORMATION: - * - * $HeadURL$ - * $Id$ - * $LastChangedDate$ - * $LastChangedBy$ - * $LastChangedRevision$ - */ - -abstract class cs_genericPermissionGroupAbstract extends cs_genericGroupAbstract { - - /** Table name used to store permission groups. */ - const permGroupTable = "cswal_permission_group_table"; - - /** Sequence for permission_group table. */ - const groupSeq = "cswal_permission_group_table_permission_group_id_seq"; - - //============================================================================ - public abstract function __construct(cs_phpDB $db) { - parent::__construct($db); - }//end __construct() - //============================================================================ - - - - //============================================================================ - protected function clean_perm_group_name($permGroupName) { - try { - $retval = $this->clean_group_name($permGroupName); - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to clean group name (". $groupName .")"); - } - return($retval); - }//end clean_perm_group_name() - //============================================================================ - - - - //============================================================================ - public function create_group($groupName) { - try { - $groupName = $this->clean_group_name($groupName); - $sql = "INSERT INTO ". self::groupTable ." (group_name) VALUES ('". $groupName ."')"; - $newId = $this->db->run_insert($sql, self::groupSeq); - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to create group (". $groupName ."), DETAILS::: ". $e->getMessage()); - } - return($newId); - }//end create_group() - //============================================================================ - - - - //============================================================================ - public function get_group($groupName) { - try { - $groupName = $this->clean_group_name($groupName); - $sql = "SELECT * FROM ". self::groupTable ." WHERE group_name='". $groupName ."'"; - $retval = $this->db->run_query($sql); - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to locate group (". $groupName ."), DETAILS::: ". $e->getMessage()); - } - return($retval); - }//end get_group() - //============================================================================ - - - - //============================================================================ - public function get_group_by_id($groupId) { - try { - if(!is_null($groupId) && is_numeric($groupId)) { - $sql = "SELECT * FROM ". self::groupTable ." WHERE group_id='". $groupId ."'"; - $retval = $this->db->run_query($sql); - } - else { - throw new exception(__METHOD__ .":: invalid group ID (". $groupId .")"); - } - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to locate group ID (". $groupId ."), DETAILS::: ". $e->getMessage()); - } - return($retval); - }//end get_group_by_id() - //============================================================================ - -} -?> Copied: trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php (from rev 168, trunk/0.3/abstract/cs_genericGroup.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php 2010-06-21 14:29:53 UTC (rev 169) @@ -0,0 +1,71 @@ +<?php + +/* + * Created on June 18, 2010 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_genericUserGroupAbstract extends cs_genericGroupAbstract { + + /** Table name used to store user_group records. */ + const ugTable = "cswal_user_group_table"; + + /** Sequence for user_group table. */ + const ugSeq = "cswal_user_group_table_user_group_id_seq"; + + //============================================================================ + public abstract function __construct(cs_phpDB $db) { + parent::__construct($db); + }//end __construct() + //============================================================================ + + + + //============================================================================ + public function create_user_group($userId, $groupId) { + if(is_numeric($userId) && is_numeric($groupId) && $userId >= 0 && $groupId >= 0) { + try { + $sql = "INSERT INTO ". self::ugTable ." (user_id, group_id) VALUES (". $userId .", ". $groupId .")"; + $newId = $this->db->run_insert($sql, self::ugSeq); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to create group (". $groupName ."), DETAILS::: ". $e->getMessage()); + } + } + else { + throw new exception(__METHOD__ .":: invalid or non-numeric user_id (". $userId .") or group_id (". $groupId .")"); + } + return($newId); + }//end create_group() + //============================================================================ + + + + //============================================================================ + public function get_user_groups($userId) { + if(is_numeric($userId) && $userId >= 0) { + try { + $sql = "SELECT ug.*, g.group_name FROM ". self::ugTable ." AS ug INNER " + ."JOIN ". parent::groupTable ." as g WHERE user_id=". $userId; + $retval = $this->db->run_query($sql); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to locate group (". $groupName ."), DETAILS::: ". $e->getMessage()); + } + } + else { + throw new exception(__METHOD__ .":: invalid or non-numeric user_id (". $userId .")"); + } + return($retval); + }//end get_group() + //============================================================================ + +} +?> Copied: trunk/0.3/abstract/cs_group.abstract.class.php (from rev 168, trunk/0.3/abstract/cs_genericPermission.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_group.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_group.abstract.class.php 2010-06-21 14:29:53 UTC (rev 169) @@ -0,0 +1,122 @@ +<?php +/* + * Created on June 18, 2010 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +class cs_groupAbstract extends cs_webapplibsAbstract { + + /** Database object. */ + public $db; + + /** cs_globalFunctions object, for cleaning strings & such. */ + public $gfObj; + + /** Table name used to store groups. */ + const groupTable = "cswal_group_table"; + + /** Sequence for groups table. */ + const groupSeq = "cswal_group_table_group_id"; + + //============================================================================ + public abstract function __construct(cs_phpDB $db) { + $this->db = $db; + $this->gfObj = new cs_globalFunctions; + }//end __construct() + //============================================================================ + + + + //============================================================================ + protected function clean_group_name($name) { + if(!is_null($name) && is_string($name) && strlen($name)) { + $name = $this->gfObj->cleanString(strtolower($name), 'email'); + } + else { + throw new exception(__METHOD__ .":: invalid string (". $name .")"); + } + }//end clean_group_name() + //============================================================================ + + + + //============================================================================ + public function create_group($name) { + try{ + $name = $this->clean_group_name($name); + $sql = "INSERT INTO ". self::groupTable ." (group_name) VALUES ('". $name ."')"; + $newId = $this->db->run_insert($sql, self::gropuSeq); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to create new record, DETAILS::: ". $e->getMessage()); + } + + return($newId); + }//end create_group() + //============================================================================ + + + + //============================================================================ + public function get_group($name) { + try { + $name = $this->clean_group_name($name); + $sql = "SELECT * FROM ". self::groupTable ." WHERE group_name='". $name ."'"; + $retval = $this->db->run_query($sql); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: error while locating group '". $name ."', DETAILS::: ". $e->getMessage()); + } + + return($retval); + }//end get_group() + //============================================================================ + + + + //============================================================================ + public function get_group_by_id($groupId) { + try { + if(!is_null($groupId) && is_numeric($groupId)) { + $sql = "SELECT * FROM ". self::groupTable ." WHERE group_id='". $groupId ."'"; + $retval = $this->db->run_query($sql); + } + else { + throw new exception(__METHOD__ .":: invalid group ID (". $groupId .")"); + } + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: error while locating group '". $groupId ."', DETAILS::: ". $e->getMessage()); + } + + return($retval); + }//end get_group_by_id() + //============================================================================ + + + + //============================================================================ + /** + * Build the schema for the generic permissions system. + */ + private function build_schema() { + try { + $result = $this->db->run_sql_file(dirname(__FILE__) .'/../setup/genericPermissions.pgsql.sql'); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to create schema, DETAILS::: ". $e->getMessage()); + } + if($result !== true) { + throw new exception(__METHOD__ .":: failed to create schema (no details)"); + } + }//end build_schema() + //============================================================================ +} +?> Copied: trunk/0.3/cs_genericPermission.class.php (from rev 168, trunk/0.3/abstract/cs_genericPermission.abstract.class.php) =================================================================== --- trunk/0.3/cs_genericPermission.class.php (rev 0) +++ trunk/0.3/cs_genericPermission.class.php 2010-06-21 14:29:53 UTC (rev 169) @@ -0,0 +1,204 @@ +<?php +/* + * Created on June 03, 2010 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +class cs_genericPermission extends cs_genericUserGroupAbstract { + + /** Database object. */ + public $db; + + /** cs_globalFunctions object, for cleaning strings & such. */ + public $gfObj; + + /** Table name used to store permissions. */ + const objTable = "cswal_object_table"; + + /** Sequence for permissions table. */ + const objSeq = "cswal_object_table_object_id"; + + /** List of valid keys... */ + protected $keys = array(); + + //============================================================================ + public abstract function __construct(cs_phpDB $db) { + $this->db = $db; + parent::__construct($db); + $this->gfObj = new cs_globalFunctions; + $this->keys = array( + 0 => 'u_r', + 1 => 'u_w', + 2 => 'u_x', + 3 => 'g_r', + 4 => 'g_w', + 5 => 'g_x', + 6 => 'o_r', + 7 => 'o_w', + 8 => 'o_x' + ); + }//end __construct() + //============================================================================ + + + + //============================================================================ + /** + * Checks internals to make sure all is okay; throws an exception on fail. + */ + private function _sanityCheck() { + if(!is_array($this->keys) || count($this->keys) != 9) { + throw new exception(__METHOD__ .":: internal error, no keys"); + } + }//end _sanityCheck() + //============================================================================ + + + + //============================================================================ + protected function parse_permission_string($string) { + $this->_sanityCheck(); + if(is_string($string) && strlen($string) == 9) { + $retval = array(); + //handle it like an array. + for($x=0;$x<strlen($string);$x++) { + $myVal = false; + if($string[$x] !== '-') + $myVal = true; + } + $key = $this->keys[$x]; + $retval[$key] = $myVal; + } + } + else { + throw new exception(__METHOD__ .":: invalid permission string (". $string ."), non-string or not 9 characters long (example: 'rwxrw-rw-')"); + } + return($retval); + }//end parse_permission_string() + //============================================================================ + + + + //============================================================================ + protected function build_permission_string(array $perms) { + $this->_sanityCheck(); + if(is_array($perms) && count($perms) == count($this->keys)) { + $retval = ""; + foreach($this->keys as $dbColName) { + if(isset($perms[$dbColName])) { + //get the last character of the column name. + $permChar = substring($dbColName, -1); + if($perms[$dbColName] === false) { + $permChar = '-'; + } + $retval .= $permChar; + } + else { + throw new exception(__METHOD__ .":: missing permission index (". $dbColName .")"); + } + } + } + else { + throw new exception(__METHOD__ .":: invalid permission set."); + } + return($retval); + }//end build_permission_string(); + //============================================================================ + + + + //============================================================================ + public function create_object($name, $userId, $groupId, $permString) { + return($this->create_permission($name, $userId, $groupId, $permString)); + }//end create_object() + //============================================================================ + + + + //============================================================================ + public function create_permission($name, $userId, $groupId, $permString) { + if(is_string($name) && strlen($name) && is_numeric($userId) && $userId >= 0 && is_numeric($groupId) && $groupId >= 0) { + try{ + $insertArr = $this->parse_permission_string($permString); + $insertArr['object_name'] = $this->gfObj->cleanString($name, 'sql', 0); + $insertArr['user_id'] = $userId; + $insertArr['group_id'] = $groupId; + + $insertSql = $this->gfObj->string_from_array($insertArr, 'insert'); + $sql = "INSERT INTO ". self::objTable ." ". $insertSql; + $newId = $this->db->run_insert($sql, self::objSeq); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to create new record, DETAILS::: ". $e->getMessage()); + } + } + else { + throw new exception(__METHOD__ .":: invalid argument(s)"); + } + + return($newId); + }//end create_permission() + //============================================================================ + + + + //============================================================================ + public function get_object($name) { + return($this->get_permission($name)); + }//end get_object() + //============================================================================ + + + + //============================================================================ + public function get_permission($name) { + try { + $name = $this->clean_permission_name($name); + $sql = "SELECT * FROM ". self::objTable ." WHERE permission_name='". $name ."'"; + $retval = $this->db->run_query($sql); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: error while locating permission '". $name ."', DETAILS::: ". $e->getMessage()); + } + + return($retval); + }//end get_permission() + //============================================================================ + + + + //============================================================================ + public function get_object_by_id($objectId) { + return($this->get_permission_by_id($objectId); + }//end get_object_by_id() + //============================================================================ + + + + //============================================================================ + public function get_permission_by_id($permId) { + try { + if(!is_null($permId) && is_numeric($permId)) { + $sql = "SELECT * FROM ". self::objTable ." WHERE object_id='". $permId ."'"; + $retval = $this->db->run_query($sql); + } + else { + throw new exception(__METHOD__ .":: invalid permission ID (". $permId .")"); + } + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: error while locating permission '". $permId ."', DETAILS::: ". $e->getMessage()); + } + + return($retval); + }//end get_permission_by_id() + //============================================================================ +} +?> Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2010-06-15 02:16:11 UTC (rev 168) +++ trunk/0.3/cs_webdbupgrade.class.php 2010-06-21 14:29:53 UTC (rev 169) @@ -542,6 +542,11 @@ //now try the SQL... $numrows = $this->db->exec($sql); $dberror = $this->db->errorMsg(); + + //retrieve the data... + $data = $this->db->farray_fieldnames(); + $this->databaseVersion = $data['version_string']; + $retval = $this->parse_version_string($data['version_string']); } else { $this->error_handler(__METHOD__ .": no table in database, failed to create one... ORIGINAL " . Modified: trunk/0.3/docs/README.txt =================================================================== --- trunk/0.3/docs/README.txt 2010-06-15 02:16:11 UTC (rev 168) +++ trunk/0.3/docs/README.txt 2010-06-21 14:29:53 UTC (rev 169) @@ -90,4 +90,32 @@ NO::: --> stop upgrade process. --> HALT - --> (continues as before) \ No newline at end of file + --> (continues as before) + + +=== CS Generic Permissions === + +This permissions system is built to be flexible enough to be used in virtually any application for any purpose. The "permissions" are stored in a way that basically mimics *nix filesystem permissions. The code must know what the object is for which the user is asking permission. That object has the following traits: + * Object Name: the name of the item that is being assigned permissions. + -- Examples: + ++ A URL (i.e. "/authenticated" would only be accessible to the owner + group members) + ++ A Blog (i.e. "/blog/harryjohnson" would be readable to everyone, but only writeable by user "harryjohnson") + ++ A File (i.e. "/{WEBROOT}/files/hiddenData.sqlite" might only be allowed access by a certain user) + ++ Executing a special script: (i.e. "/bin/importFiles.pl", run script using a web interface) + * User ID: indicates what user owns this object. + * Group ID: indicates a group that users must be part of (if not owner) to be assigned these permissions + * Permission Bits: + -- Each permission is a true/false value. The name is in the form "{x}_{y}" + ++ "{x}": u/g/o (User/Group/Owner) + ++ "{y}": r/w/x (Read/Write/eXecute) + -- Full Explanation: + ++ "u_r": User's read permission; indicates if the owner can "read" (view) it. + ++ "u_w": User's write permission; indicates if the owner can write (create/update) the object. + ++ "u_x": User's execute permission; this rarely applies, and usage would vary greatly depending upon the object & associated code. + ++ "g_r": Group read permission; users assigned to the associated group can/cannot "read" (view) it. + ++ "g_w": Group write permission; users assigned to the associated group can/cannot write (create/update) the object. + ++ "g_x": Group execute permission; users assigned to the associated group are bound by this value (usage depends on code). + ++ "o_r": Other read permission; users that are not owners or members of the group can/cannot "read" (view) it + ++ "o_w": Other write permission; users that are not owners or members of the group can/cannot write (create/update) the object. + ++ "o_x": Other execute permission; users that are... you get the idea. + Modified: trunk/0.3/setup/genericPermissions.pgsql.sql =================================================================== --- trunk/0.3/setup/genericPermissions.pgsql.sql 2010-06-15 02:16:11 UTC (rev 168) +++ trunk/0.3/setup/genericPermissions.pgsql.sql 2010-06-21 14:29:53 UTC (rev 169) @@ -1,58 +1,60 @@ +BEGIN; -- --- Permission table --- Specific permissions: these are words used by the code to determine if the user has the appropriate permission. --- -CREATE TABLE cswal_permission_table ( - permission_id serial NOT NULL PRIMARY KEY, - permission_name text NOT NULL UNIQUE -); - - --- -- Group table -- Enumerates a list of permissions for a specific group: i.e. for "blog", this could list "create", "edit", and "delete" (among others). -- CREATE TABLE cswal_group_table ( group_id serial NOT NULL PRIMARY KEY, - group_name text NOT NULL UNIQUE + group_name text NOT NULL UNIQUE, + group_admin integer NOT NULL REFERENCES cs_authtentication_table(uid) ); -- --- Permission + Group table --- Enumerates permissions for a given group: any permissions not specifically entered are denied. --- -CREATE TABLE cswal_permission_group_table ( - permission_group_id serial NOT NULL PRIMARY KEY, - permission_id integer NOT NULL REFERENCES cswal_permission_table(permission_id), - group_id integer NOT NULL REFERENCES cswal_group_table(group_id), - allowed boolean NOT NULL DEFAULT false, - description text -); - --- -- User + Group table -- Assigns a user to one or more groups. --- NOTE::: the "user_id" column should be (manually) foreign-keyed to an existing user table. +-- NOTE::: the "user_id" table should be updated to match your database schema. -- CREATE TABLE cswal_user_group_table ( user_group_id serial NOT NULL PRIMARY KEY, - user_id integer NOT NULL, + user_id integer NOT NULL REFERENCES cs_authentication_table(uid), group_id integer NOT NULL REFERENCES cswal_group_table(group_id) ); -- --- User + Permission table --- Give users specific permissions, overriding default and/or assigned group permissions. +-- Object table +-- Contains unique list of objects along with the owner, default group, & user/group/other permissions (like *nix filesystem permissions) +-- The permissions for user/group/other could be converted to octal (i.e. "rwxrwxrwx" == "777"), but it isn't as straightforward to read. +-- NOTE::: the "user_id" table should be updated to match your database schema. -- -CREATE TABLE cswal_user_permission_table ( - user_permission_id serial NOT NULL PRIMARY KEY, - user_id integer NOT NULL, +CREATE TABLE cswal_object_table ( + object_id serial NOT NULL PRIMARY KEY, + object_name text NOT NULL UNIQUE, + user_id integer NOT NULL REFERENCES cs_authentication_table(uid), group_id integer NOT NULL REFERENCES cswal_group_table(group_id), - permission_id integer NOT NULL REFERENCES cswal_permission_table(permission_id), - allowed boolean NOT NULL DEFAULT false + u_r boolean NOT NULL DEFAULT TRUE, + u_w boolean NOT NULL DEFAULT TRUE, + u_x boolean NOT NULL DEFAULT FALSE, + g_r boolean NOT NULL DEFAULT TRUE, + g_w boolean NOT NULL DEFAULT FALSE, + g_x boolean NOT NULL DEFAULT FALSE, + o_r boolean NOT NULL DEFAULT TRUE, + o_w boolean NOT NULL DEFAULT FALSE, + o_x boolean NOT NULL DEFAULT FALSE ); +INSERT INTO cswal_group_table (group_name) VALUES ('www'); +INSERT INTO cswal_group_table (group_name) VALUES ('blogs'); +INSERT INTO cswal_group_table (group_name) VALUES ('admin'); +INSERT INTO cswal_object_table + (object_name,user_id, group_id) + VALUES + ('/', 101, 1); + +INSERT INTO cswal_object_table + (object_name, user_id, group_id, g_r, g_w) + VALUES + ('/member', 101, 2, true, true); Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2010-06-15 02:16:11 UTC (rev 168) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2010-06-21 14:29:53 UTC (rev 169) @@ -48,7 +48,8 @@ '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', - 'cswal_gdl_object_table', 'cswal_gdl_attribute_table', 'cswal_gdl_path_table' + 'cswal_gdl_object_table', 'cswal_gdl_attribute_table', 'cswal_gdl_path_table', + 'cswal_object_table', 'cswal_user_group_table', 'cswal_group_table' ); $db = $this->create_dbconn(); @@ -202,7 +203,7 @@ //-------------------------------------------------------------------------- - function test_genericDataLinker() { + function tst_genericDataLinker() { $x = new gdlTester($this->create_dbconn()); @@ -458,6 +459,13 @@ //-------------------------------------------------------------------------- + public function test_genericPermissions() { + }//end test_genericPermissions() + //-------------------------------------------------------------------------- + + + + //-------------------------------------------------------------------------- private function do_tokenTest(array $tokenData, $uid, $checksum) { if($this->assertTrue(is_array($tokenData)) && $this->assertTrue(is_numeric($uid)) && $this->assertTrue(strlen($checksum))) { @@ -487,6 +495,7 @@ } } +/* class gdlTester extends cs_genericDataLinker { public $isTest = true; @@ -498,5 +507,6 @@ return($this->create_path_objects($path)); } } +//*/ ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-06-21 14:42:00
|
Revision: 170 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=170&view=rev Author: crazedsanity Date: 2010-06-21 14:41:53 +0000 (Mon, 21 Jun 2010) Log Message: ----------- Resurrect cs_genericDataLinker, fix some unit tests (uncomment them, fix method references). Modified Paths: -------------- trunk/0.3/tests/testOfCSWebAppLibs.php Added Paths: ----------- trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php trunk/0.3/abstract/cs_gdlObject.abstract.class.php trunk/0.3/abstract/cs_gdlPath.abstract.class.php trunk/0.3/cs_genericDataLinker.class.php Copied: trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php (from rev 165, trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_gdlAttrib.abstract.class.php 2010-06-21 14:41:53 UTC (rev 170) @@ -0,0 +1,89 @@ +<?php +/* + * Created on Jan 29, 2009 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_gdlAttribAbstract extends cs_gdlPathAbstract { + + + const table='cswal_gdl_attribute_table'; + const tableSeq = 'cswal_gdl_attribute_table_attribute_id_seq'; + + + + //------------------------------------------------------------------------- + public function create_attrib($path, $data, $type=null) { + + $objectId = $this->get_object_id_from_path($path); + + $insertString = ""; + $attribs = array(); + if(is_array($data) && count($data)) { + foreach($data as $n=>$v) { + $n = $this->translate_attrib_name($n); + $attribs[$n] = $v; + } + } + elseif(!is_null($type)) { + $key = $this->translate_attrib_name($type); + $attribs = array($key => $data); + } + else { + throw new exception(__METHOD__ .": data was not array and no type set"); + } + + if(!is_array($attribs) || !count($attribs)) { + throw new exception(__METHOD__ .": failed to create an array of attributes... ". $this->gfObj->debug_print(func_get_args(),0)); + } + + $attribs['object_id'] = $objectId; + $insertString = $this->gfObj->string_from_array($attribs, 'insert'); + + + if(!strlen($insertString)) { + throw new exception(__METHOD__ .": invalid insert string (". $insertString .")"); + } + $sql = "INSERT INTO ". self::attrTable ." ". $insertString; + + try { + $retval = $this->db->run_insert($sql, self::attrTableSeq); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to perform insert::: ". $e->getMessage() .' ---- '. $sql); + } + + return($retval); + }//end create_attrib() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function translate_attrib_name($name) { + $retval = null; + foreach($this->validTypes as $type) { + if(preg_match('/^'. $type .'/', $name)) { + $retval = 'a_'. $type; + break; + } + } + + if(is_null($retval) || !strlen($retval)) { + $this->gfObj->debug_print(__METHOD__ .": name was (". $name ."), retval=(". $retval .")",1); + throw new exception(__METHOD__ .": invalid attribute name (". $name .")"); + } + + return($retval); + }//end translate_attrib_name() + //------------------------------------------------------------------------- + +} +?> \ No newline at end of file Copied: trunk/0.3/abstract/cs_gdlObject.abstract.class.php (from rev 165, trunk/0.3/abstract/cs_gdlObject.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_gdlObject.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_gdlObject.abstract.class.php 2010-06-21 14:41:53 UTC (rev 170) @@ -0,0 +1,136 @@ +<?php +/* + * Created on Jan 29, 2009 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_gdlObjectAbstract extends cs_webapplibsAbstract { + + + const table='cswal_gdl_object_table'; + const tableSeq = 'cswal_gdl_object_table_object_id_seq'; + + //------------------------------------------------------------------------- + public function get_object_id_from_path($path) { + $sql = "SELECT object_id FROM ". self::table ." WHERE object_path='". + $this->clean_path($path) ."'"; + + try { + $data = $this->db->run_query($sql); + + if(is_array($data) && count($data) == 1) { + $retval = $data['object_id']; + } + else { + throw new exception(__METHOD__ .": invalid data for path (". $this->clean_path($path) .")::: ". $this->gfObj->debug_var_dump($data,0)); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": error retrieving path::: ". $e->getMessage()); + } + + return($retval); + }//end get_object_id_from_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function create_object($name, $data=null, $type=null) { + $sql = "INSERT INTO ". self::table ." (object_name) VALUES ('". + $this->gfObj->cleanString($this->clean_path($name), 'sql_insert') ."')"; + try { + $retval = $this->db->run_insert($sql, self::tableSeq); + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to perform insert::: ". $e->getMessage()); + } + + if(!is_null($data)) { + throw new exception(__METHOD__ .": can't create data for objects yet"); + } + return($retval); + }//end create_object() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function build_object_id_list(array $objects) { + $this->gfObj->switch_force_sql_quotes(1); + $sql = "SELECT * FROM ". self::table ." WHERE object_name IN (". + $this->gfObj->string_from_array($objects, null, ',', 'sql') .")"; + $this->gfObj->switch_force_sql_quotes(0); + + $retval = array(); + try { + $retval = $this->db->run_query($sql, 'object_name', 'object_id'); + if(!is_array($retval)) { + $retval = array(); + } + } + catch(exception $e) { + //throw new exception(__METHOD__ .": failed to retrieve list"); + } + + return($retval); + }//end build_object_id_list() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function build_object_name_list(array $objectIds) { + $this->gfObj->switch_force_sql_quotes(1); +//string_from_array($array,$style=NULL,$separator=NULL, $cleanString=NULL, $removeEmptyVals=FALSE) + foreach($objectIds as $i=>$myId) { + if(!strlen($myId)) { + unset($objectIds[$i]); + } + } + $sql = "SELECT * FROM ". self::table ." WHERE object_id IN (". + $this->gfObj->string_from_array($objectIds, null, ',', 'sql',true) .")"; + $this->gfObj->switch_force_sql_quotes(0); + + try { + $retval = $this->db->run_query($sql, 'object_id', 'object_name'); + if(!is_array($retval)) { + $retval = array(); + } + } + catch(exception $e) { + throw new exception(__METHOD__ .": failed to retrieve list::: ". $e->getMessage()); + } + + return($retval); + }//end build_object_id_list() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function create_objects_enmasse(array $objectList) { + $retval = 0; + foreach($objectList as $name) { + try { + $this->create_object($name); + $retval++; + } + catch(exception $e) { + //nothing to see here, move along. + } + } + return($retval); + }//end create_objects_enmasse() + //------------------------------------------------------------------------- + + +} +?> Copied: trunk/0.3/abstract/cs_gdlPath.abstract.class.php (from rev 165, trunk/0.3/abstract/cs_gdlPath.abstract.class.php) =================================================================== --- trunk/0.3/abstract/cs_gdlPath.abstract.class.php (rev 0) +++ trunk/0.3/abstract/cs_gdlPath.abstract.class.php 2010-06-21 14:41:53 UTC (rev 170) @@ -0,0 +1,126 @@ +<?php +/* + * Created on Jan 29, 2009 + * + * FILE INFORMATION: + * + * $HeadURL$ + * $Id$ + * $LastChangedDate$ + * $LastChangedBy$ + * $LastChangedRevision$ + */ + +abstract class cs_gdlPathAbstract extends cs_gdlObjectAbstract { + + + const table='cswal_gdl_path_table'; + const tableSeq = 'cswal_gdl_path_table_path_id_seq'; + + + + + + //------------------------------------------------------------------------- + public function create_path($path) { + $idList = $this->create_path_objects($path); + $pathIdList = $this->create_id_path($idList); + + if($this->get_path_from_idlist($pathIdList)) { + $retval = $pathIdList; + } + else { + + $sql = "INSERT INTO ". self::table ." (path_id_list) VALUES ('". $pathIdList ."')"; + + try { + $insertedId = $this->db->run_insert($sql, self::tableSeq); + $retval = $pathIdList; + } + catch(exception $e) { + throw new exception(__METHOD__ .": unable to create path::: ". $e->getMessage()); + } + } + + return($retval); + }//end create_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function clean_path($path, $appendBase=true) { + if(strlen($path)) { + if($appendBase === true && !is_null($this->basePath)) { + $path = $this->basePath .'/'. $path; + } + $newPath = preg_replace('/\/{2,}/', '/', $path); + + if(!strlen($newPath)) { + throw new exception(__METHOD__ .": new path is zero-length (". $newPath ."), old path=(". func_get_arg(0) .")"); + } + } + else { + throw new exception(__METHOD__ .": no valid path given (". $path .")"); + } + + return($newPath); + }//end clean_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function set_base_path($path) { + if(is_null($path) || !strlen($path)) { + $this->basePath = null; + } + else { + $this->basePath = $this->clean_path($path,false); + } + }//end set_base_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function explode_path($path, $appendBase=true) { + $path = $this->clean_path($path, $appendBase); + $path = preg_replace('/^\//', '', $path); + $path = preg_replace('/\/$/', '', $path); + + return(explode('/', $path)); + }//end explode_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function create_id_path(array $idList) { + $retval = ':'. $this->gfObj->string_from_array($idList, null, '::') .':'; + return($retval); + }//end create_id_path() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function get_path_from_idlist($idPath) { + + $idList = explode('::', preg_replace('/^:/', '', preg_replace('/:$/', '', $idPath))); + + $nameList = $this->build_object_name_list($idList); + + $retval = "/"; + foreach($nameList as $id=>$name) { + $retval = $this->gfObj->create_list($retval, $name, '/'); + } + + $retval = $this->clean_path($retval,false); + + return($retval); + }//end get_text_path_from_id_path() + //------------------------------------------------------------------------- + +} +?> \ No newline at end of file Copied: trunk/0.3/cs_genericDataLinker.class.php (from rev 165, trunk/0.3/cs_genericDataLinker.class.php) =================================================================== --- trunk/0.3/cs_genericDataLinker.class.php (rev 0) +++ trunk/0.3/cs_genericDataLinker.class.php 2010-06-21 14:41:53 UTC (rev 170) @@ -0,0 +1,101 @@ +<?php +/* + * Created on Oct 27, 2009 + * + * THE IDEA::: + * 1.) Unix/Linux-like paths lead to an attribute. + * 2.) Multiple paths can lead to the same attribute. + * 3.) An attribute can be linked to its original path. + * 4.) Each "directory" in a path is an object with an ID. + * 5.) Paths themselves are only stored on attributes: intermediate paths may be valid if all objects + * for that path are also valid (i.e. if "/one/two/three" is valid, so is "/two/one/three" and "/three/two/one"). + * 6.) Database... + * a.) finding an attribute referencing a single object should be straightforward and fast. + * b.) objects are unique to avoid excess duplicate pathways + * c.) using id paths with each number wrapped in colons is simple (i.e. ":3342:", ":3342::3::3:" + * + * The idea here is to have a class that generically links data together (in a + * database). It is not meant to be a super clean or speedy system, instead meant + * as a way of describing relationships between various pieces of data. + * + * Once a path is created (list object_id's, separated by '::'), it should always have an attribute. + * + * + * 1::2::3 -> select * from <bla> WHERE path = '2' OR path like '2::%' OR path like '%::2' + * -OR- + * :1::2::3: -> select * from <bla> WHERE path like '%:2:%' + * + * If an attribute is created with a small path (like "/test") and the id is 1, the attribute shows ":1:" + * --> if the id is 7720218, then the attribute shows ":7720218:" + * + * + * SVN INFORMATION::: + * ------------------- + * Last Author::::::::: $Author$ + * Current Revision:::: $Revision$ + * Repository Location: $HeadURL$ + * Last Updated:::::::: $Date$ + */ + + + +class cs_genericDataLinker extends cs_gdlAttribAbstract { + + const attrTable='cswal_gdl_attribute_table'; + const attrTableSeq='cswal_gdl_attribute_table_attribute_id_seq'; + + protected $validTypes = array('text', 'int', 'dec', 'bool'); + protected $gfObj; + protected $basePath=null; + + public $db; + + //------------------------------------------------------------------------- + public function __construct(cs_phpDB $db) { + + parent::__construct($db); + if(!$db->is_connected()) { + throw new exception(__METHOD__ .": database not connected"); + } + $this->db = $db; + $this->gfObj = new cs_globalFunctions; + }//end __construct() + //------------------------------------------------------------------------- + + + + //------------------------------------------------------------------------- + public function create_path_objects($path) { + $newPath = $this->clean_path($path); + $newPath = preg_replace('/^\//', '', $newPath); + + //break it into bits. + $bits = explode('/', $newPath); + + $myList = $this->build_object_id_list($bits); + if(count($myList) !== count($bits)) { + $createThese = array(); + foreach($bits as $name) { + if(!isset($myList[$name])) { + $createThese[] = $name; + } + } + $this->create_objects_enmasse($createThese); + $myList = $this->build_object_id_list($bits); + } + + $retval = array(); + foreach($bits as $name) { + @$retval[$name] = $myList[$name]; + } + + if(is_null($retval) || !is_array($retval) || !count($retval)) { + throw new exception(__METHOD__ .": failed to build path objects... ". $retval); + } + + return($retval); + }//end create_path_objects() + //------------------------------------------------------------------------- +} + +?> Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2010-06-21 14:29:53 UTC (rev 169) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2010-06-21 14:41:53 UTC (rev 170) @@ -203,7 +203,7 @@ //-------------------------------------------------------------------------- - function tst_genericDataLinker() { + function test_genericDataLinker() { $x = new gdlTester($this->create_dbconn()); @@ -260,7 +260,7 @@ } - /*/basic tests for building text-based paths vs. id-based paths. + //basic tests for building text-based paths vs. id-based paths. { $myPath = '/character/sheet/Tetra Tealeaf'; @@ -273,8 +273,8 @@ $idList2 = $x->create_path($myPath); $this->assertEqual($x->create_id_path(array_values($idList)), $idList2); - $this->assertEqual($myPath, $x->get_text_path_from_id_path($x->create_id_path($idList))); - $this->gfObj->debug_var_dump($x->get_text_path_from_id_path($x->create_id_path($idList))); + $this->assertEqual($myPath, $x->get_path_from_idlist($x->create_id_path($idList))); + $this->gfObj->debug_var_dump($x->get_path_from_idlist($x->create_id_path($idList))); $this->gfObj->debug_var_dump($idList); $this->gfObj->debug_var_dump($idList2); @@ -495,7 +495,6 @@ } } -/* class gdlTester extends cs_genericDataLinker { public $isTest = true; @@ -507,6 +506,5 @@ return($this->create_path_objects($path)); } } -//*/ ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-06-21 15:54:22
|
Revision: 172 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=172&view=rev Author: crazedsanity Date: 2010-06-21 15:54:15 +0000 (Mon, 21 Jun 2010) Log Message: ----------- More changes for unit testing. Modified Paths: -------------- trunk/0.3/abstract/cs_genericGroup.abstract.class.php trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php trunk/0.3/cs_genericPermission.class.php trunk/0.3/cs_phpDB.class.php trunk/0.3/setup/genericPermissions.pgsql.sql trunk/0.3/tests/testOfCSGenericPermissions.php Removed Paths: ------------- trunk/0.3/abstract/cs_group.abstract.class.php Modified: trunk/0.3/abstract/cs_genericGroup.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_genericGroup.abstract.class.php 2010-06-21 15:12:12 UTC (rev 171) +++ trunk/0.3/abstract/cs_genericGroup.abstract.class.php 2010-06-21 15:54:15 UTC (rev 172) @@ -1,7 +1,6 @@ <?php - /* - * Created on June 03, 2010 + * Created on June 18, 2010 * * FILE INFORMATION: * @@ -14,44 +13,51 @@ abstract class cs_genericGroupAbstract extends cs_webapplibsAbstract { + /** Database object. */ + public $db; + + /** cs_globalFunctions object, for cleaning strings & such. */ + public $gfObj; + /** Table name used to store groups. */ const groupTable = "cswal_group_table"; /** Sequence for groups table. */ - const groupSeq = "cswal_group_table_group_id_seq"; + const groupSeq = "cswal_group_table_group_id"; //============================================================================ - public abstract function __construct(cs_phpDB $db) { - parent::__construct($db); + public function __construct(cs_phpDB $db) { + $this->db = $db; + $this->gfObj = new cs_globalFunctions; }//end __construct() //============================================================================ //============================================================================ - protected function clean_group_name($groupName) { - try { - $retval = $this->clean_permission_name($groupName); + protected function clean_group_name($name) { + if(!is_null($name) && is_string($name) && strlen($name)) { + $name = $this->gfObj->cleanString(strtolower($name), 'email'); } - catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to clean group name (". $groupName .")"); + else { + throw new exception(__METHOD__ .":: invalid string (". $name .")"); } - return($retval); }//end clean_group_name() //============================================================================ //============================================================================ - public function create_group($groupName) { - try { - $groupName = $this->clean_group_name($groupName); - $sql = "INSERT INTO ". self::groupTable ." (group_name) VALUES ('". $groupName ."')"; - $newId = $this->db->run_insert($sql, self::groupSeq); + public function create_group($name) { + try{ + $name = $this->clean_group_name($name); + $sql = "INSERT INTO ". self::groupTable ." (group_name) VALUES ('". $name ."')"; + $newId = $this->db->run_insert($sql, self::gropuSeq); } catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to create group (". $groupName ."), DETAILS::: ". $e->getMessage()); + throw new exception(__METHOD__ .":: failed to create new record, DETAILS::: ". $e->getMessage()); } + return($newId); }//end create_group() //============================================================================ @@ -59,15 +65,16 @@ //============================================================================ - public function get_group($groupName) { + public function get_group($name) { try { - $groupName = $this->clean_group_name($groupName); - $sql = "SELECT * FROM ". self::groupTable ." WHERE group_name='". $groupName ."'"; + $name = $this->clean_group_name($name); + $sql = "SELECT * FROM ". self::groupTable ." WHERE group_name='". $name ."'"; $retval = $this->db->run_query($sql); } catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to locate group (". $groupName ."), DETAILS::: ". $e->getMessage()); + throw new exception(__METHOD__ .":: error while locating group '". $name ."', DETAILS::: ". $e->getMessage()); } + return($retval); }//end get_group() //============================================================================ @@ -86,11 +93,30 @@ } } catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to locate group ID (". $groupId ."), DETAILS::: ". $e->getMessage()); + throw new exception(__METHOD__ .":: error while locating group '". $groupId ."', DETAILS::: ". $e->getMessage()); } + return($retval); }//end get_group_by_id() //============================================================================ + + + //============================================================================ + /** + * Build the schema for the generic permissions system. + */ + protected function build_schema() { + try { + $result = $this->db->run_sql_file(dirname(__FILE__) .'/../setup/genericPermissions.pgsql.sql'); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to create schema, DETAILS::: ". $e->getMessage()); + } + if($result !== true) { + throw new exception(__METHOD__ .":: failed to create schema (no details)"); + } + }//end build_schema() + //============================================================================ } ?> Modified: trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php 2010-06-21 15:12:12 UTC (rev 171) +++ trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php 2010-06-21 15:54:15 UTC (rev 172) @@ -21,7 +21,7 @@ const ugSeq = "cswal_user_group_table_user_group_id_seq"; //============================================================================ - public abstract function __construct(cs_phpDB $db) { + public function __construct(cs_phpDB $db) { parent::__construct($db); }//end __construct() //============================================================================ @@ -36,7 +36,7 @@ $newId = $this->db->run_insert($sql, self::ugSeq); } catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to create group (". $groupName ."), DETAILS::: ". $e->getMessage()); + throw new exception(__METHOD__ .":: failed to create user group, DETAILS::: ". $e->getMessage()); } } else { Deleted: trunk/0.3/abstract/cs_group.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_group.abstract.class.php 2010-06-21 15:12:12 UTC (rev 171) +++ trunk/0.3/abstract/cs_group.abstract.class.php 2010-06-21 15:54:15 UTC (rev 172) @@ -1,122 +0,0 @@ -<?php -/* - * Created on June 18, 2010 - * - * FILE INFORMATION: - * - * $HeadURL$ - * $Id$ - * $LastChangedDate$ - * $LastChangedBy$ - * $LastChangedRevision$ - */ - -class cs_groupAbstract extends cs_webapplibsAbstract { - - /** Database object. */ - public $db; - - /** cs_globalFunctions object, for cleaning strings & such. */ - public $gfObj; - - /** Table name used to store groups. */ - const groupTable = "cswal_group_table"; - - /** Sequence for groups table. */ - const groupSeq = "cswal_group_table_group_id"; - - //============================================================================ - public abstract function __construct(cs_phpDB $db) { - $this->db = $db; - $this->gfObj = new cs_globalFunctions; - }//end __construct() - //============================================================================ - - - - //============================================================================ - protected function clean_group_name($name) { - if(!is_null($name) && is_string($name) && strlen($name)) { - $name = $this->gfObj->cleanString(strtolower($name), 'email'); - } - else { - throw new exception(__METHOD__ .":: invalid string (". $name .")"); - } - }//end clean_group_name() - //============================================================================ - - - - //============================================================================ - public function create_group($name) { - try{ - $name = $this->clean_group_name($name); - $sql = "INSERT INTO ". self::groupTable ." (group_name) VALUES ('". $name ."')"; - $newId = $this->db->run_insert($sql, self::gropuSeq); - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to create new record, DETAILS::: ". $e->getMessage()); - } - - return($newId); - }//end create_group() - //============================================================================ - - - - //============================================================================ - public function get_group($name) { - try { - $name = $this->clean_group_name($name); - $sql = "SELECT * FROM ". self::groupTable ." WHERE group_name='". $name ."'"; - $retval = $this->db->run_query($sql); - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: error while locating group '". $name ."', DETAILS::: ". $e->getMessage()); - } - - return($retval); - }//end get_group() - //============================================================================ - - - - //============================================================================ - public function get_group_by_id($groupId) { - try { - if(!is_null($groupId) && is_numeric($groupId)) { - $sql = "SELECT * FROM ". self::groupTable ." WHERE group_id='". $groupId ."'"; - $retval = $this->db->run_query($sql); - } - else { - throw new exception(__METHOD__ .":: invalid group ID (". $groupId .")"); - } - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: error while locating group '". $groupId ."', DETAILS::: ". $e->getMessage()); - } - - return($retval); - }//end get_group_by_id() - //============================================================================ - - - - //============================================================================ - /** - * Build the schema for the generic permissions system. - */ - private function build_schema() { - try { - $result = $this->db->run_sql_file(dirname(__FILE__) .'/../setup/genericPermissions.pgsql.sql'); - } - catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to create schema, DETAILS::: ". $e->getMessage()); - } - if($result !== true) { - throw new exception(__METHOD__ .":: failed to create schema (no details)"); - } - }//end build_schema() - //============================================================================ -} -?> Modified: trunk/0.3/cs_genericPermission.class.php =================================================================== --- trunk/0.3/cs_genericPermission.class.php 2010-06-21 15:12:12 UTC (rev 171) +++ trunk/0.3/cs_genericPermission.class.php 2010-06-21 15:54:15 UTC (rev 172) @@ -29,7 +29,7 @@ protected $keys = array(); //============================================================================ - public abstract function __construct(cs_phpDB $db) { + public function __construct(cs_phpDB $db) { $this->db = $db; parent::__construct($db); $this->gfObj = new cs_globalFunctions; @@ -70,7 +70,7 @@ //handle it like an array. for($x=0;$x<strlen($string);$x++) { $myVal = false; - if($string[$x] !== '-') + if($string[$x] !== '-') { $myVal = true; } $key = $this->keys[$x]; @@ -176,7 +176,7 @@ //============================================================================ public function get_object_by_id($objectId) { - return($this->get_permission_by_id($objectId); + return($this->get_permission_by_id($objectId)); }//end get_object_by_id() //============================================================================ Modified: trunk/0.3/cs_phpDB.class.php =================================================================== --- trunk/0.3/cs_phpDB.class.php 2010-06-21 15:12:12 UTC (rev 171) +++ trunk/0.3/cs_phpDB.class.php 2010-06-21 15:54:15 UTC (rev 172) @@ -205,14 +205,8 @@ $this->lastSQLFile = $filename; $fileContents = $fsObj->read($filename); - try { - $this->db->run_update($fileContents, true); - $this->build_cache(); - $retval = TRUE; - } - catch(exception $e) { - $retval = FALSE; - } + $this->run_update($fileContents, true); + $retval = TRUE; return($retval); }//end run_sql_file() Modified: trunk/0.3/setup/genericPermissions.pgsql.sql =================================================================== --- trunk/0.3/setup/genericPermissions.pgsql.sql 2010-06-21 15:12:12 UTC (rev 171) +++ trunk/0.3/setup/genericPermissions.pgsql.sql 2010-06-21 15:54:15 UTC (rev 172) @@ -7,7 +7,7 @@ CREATE TABLE cswal_group_table ( group_id serial NOT NULL PRIMARY KEY, group_name text NOT NULL UNIQUE, - group_admin integer NOT NULL REFERENCES cs_authtentication_table(uid) + group_admin integer REFERENCES cs_authentication_table(uid) ); -- Modified: trunk/0.3/tests/testOfCSGenericPermissions.php =================================================================== --- trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-21 15:12:12 UTC (rev 171) +++ trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-21 15:54:15 UTC (rev 172) @@ -20,6 +20,7 @@ if(!defined('CS_UNITTEST')) { throw new exception(__METHOD__ .": FATAL: constant 'CS_UNITTEST' not set, can't do testing safely"); } + $this->get_valid_users(); }//end __construct() //-------------------------------------------------------------------------- @@ -65,12 +66,40 @@ //-------------------------------------------------------------------------- + /** + * Just like the schema, this SQL will need to change to match your database in order to work. + */ + private function get_valid_users() { + $sql = "SELECT uid,username FROM cs_authentication_table ORDER BY uid"; + $db = $this->create_dbconn(); + $this->validUsers = $db->run_query($sql); + $this->gfObj->debug_print($this->validUsers); + }//end get_valid_users() + //-------------------------------------------------------------------------- + + + + //-------------------------------------------------------------------------- public function test_userGroups() { - $perm = new cs_genericPermission($this->create_dbconn()); + $perm = new _gpTester($this->create_dbconn()); + $perm->do_schema(); + + //create a group with an invalid group_id. + $perm->create_user_group($this->validUsers[0]['uid'],1); }//end test_userGroups //-------------------------------------------------------------------------- } + +class _gpTester extends cs_genericPermission { + public function __construct($db) { + parent::__construct($db); + } + + public function do_schema() { + $this->build_schema(); + } +} ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-06-21 16:00:04
|
Revision: 173 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=173&view=rev Author: crazedsanity Date: 2010-06-21 15:59:57 +0000 (Mon, 21 Jun 2010) Log Message: ----------- Fix cs_phpDB::run_sql_file() so it works, remove debug_print() from tests... Modified Paths: -------------- trunk/0.3/cs_phpDB.class.php trunk/0.3/tests/testOfCSGenericPermissions.php Modified: trunk/0.3/cs_phpDB.class.php =================================================================== --- trunk/0.3/cs_phpDB.class.php 2010-06-21 15:54:15 UTC (rev 172) +++ trunk/0.3/cs_phpDB.class.php 2010-06-21 15:59:57 UTC (rev 173) @@ -193,14 +193,7 @@ * Execute the entire contents of the given file (with absolute path) as SQL. */ public function run_sql_file($filename) { - if(!is_object($this->fsObj)) { - if(class_exists('cs_fileSystem')) { - $fsObj = new cs_fileSystem(dirname($filename)); - } - else { - throw new exception(__METHOD__ .": required library (cs_fileSystem) not found"); - } - } + $fsObj = new cs_fileSystem(dirname($filename)); $this->lastSQLFile = $filename; Modified: trunk/0.3/tests/testOfCSGenericPermissions.php =================================================================== --- trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-21 15:54:15 UTC (rev 172) +++ trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-21 15:59:57 UTC (rev 173) @@ -73,7 +73,6 @@ $sql = "SELECT uid,username FROM cs_authentication_table ORDER BY uid"; $db = $this->create_dbconn(); $this->validUsers = $db->run_query($sql); - $this->gfObj->debug_print($this->validUsers); }//end get_valid_users() //-------------------------------------------------------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-06-21 17:56:54
|
Revision: 174 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=174&view=rev Author: crazedsanity Date: 2010-06-21 17:56:47 +0000 (Mon, 21 Jun 2010) Log Message: ----------- Lots of tests, and minor changes so all the tests work. Modified Paths: -------------- trunk/0.3/abstract/cs_genericGroup.abstract.class.php trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php trunk/0.3/cs_genericPermission.class.php trunk/0.3/tests/testOfCSGenericPermissions.php trunk/0.3/tests/testOfCSWebAppLibs.php Modified: trunk/0.3/abstract/cs_genericGroup.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_genericGroup.abstract.class.php 2010-06-21 15:59:57 UTC (rev 173) +++ trunk/0.3/abstract/cs_genericGroup.abstract.class.php 2010-06-21 17:56:47 UTC (rev 174) @@ -23,7 +23,7 @@ const groupTable = "cswal_group_table"; /** Sequence for groups table. */ - const groupSeq = "cswal_group_table_group_id"; + const groupSeq = "cswal_group_table_group_id_seq"; //============================================================================ public function __construct(cs_phpDB $db) { @@ -42,6 +42,7 @@ else { throw new exception(__METHOD__ .":: invalid string (". $name .")"); } + return($name); }//end clean_group_name() //============================================================================ @@ -52,7 +53,7 @@ try{ $name = $this->clean_group_name($name); $sql = "INSERT INTO ". self::groupTable ." (group_name) VALUES ('". $name ."')"; - $newId = $this->db->run_insert($sql, self::gropuSeq); + $newId = $this->db->run_insert($sql, self::groupSeq); } catch(Exception $e) { throw new exception(__METHOD__ .":: failed to create new record, DETAILS::: ". $e->getMessage()); @@ -82,6 +83,22 @@ //============================================================================ + public function get_all_groups() { + try { + $sql = "SELECT * FROM ". self::groupTable ." ORDER BY group_name"; + $retval = $this->db->run_query($sql); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to retrieve groups, DETAILS::: ". $e->getMessage()); + } + + return($retval); + }//end get_all_groups() + //============================================================================ + + + + //============================================================================ public function get_group_by_id($groupId) { try { if(!is_null($groupId) && is_numeric($groupId)) { Modified: trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php 2010-06-21 15:59:57 UTC (rev 173) +++ trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php 2010-06-21 17:56:47 UTC (rev 174) @@ -53,8 +53,8 @@ if(is_numeric($userId) && $userId >= 0) { try { $sql = "SELECT ug.*, g.group_name FROM ". self::ugTable ." AS ug INNER " - ."JOIN ". parent::groupTable ." as g WHERE user_id=". $userId; - $retval = $this->db->run_query($sql); + ."JOIN ". parent::groupTable ." as g USING (group_id) WHERE user_id=". $userId; + $retval = $this->db->run_query($sql, 'group_id'); } catch(Exception $e) { throw new exception(__METHOD__ .":: failed to locate group (". $groupName ."), DETAILS::: ". $e->getMessage()); Modified: trunk/0.3/cs_genericPermission.class.php =================================================================== --- trunk/0.3/cs_genericPermission.class.php 2010-06-21 15:59:57 UTC (rev 173) +++ trunk/0.3/cs_genericPermission.class.php 2010-06-21 17:56:47 UTC (rev 174) @@ -23,7 +23,7 @@ const objTable = "cswal_object_table"; /** Sequence for permissions table. */ - const objSeq = "cswal_object_table_object_id"; + const objSeq = "cswal_object_table_object_id_seq"; /** List of valid keys... */ protected $keys = array(); @@ -89,13 +89,14 @@ //============================================================================ protected function build_permission_string(array $perms) { $this->_sanityCheck(); - if(is_array($perms) && count($perms) == count($this->keys)) { + if(is_array($perms) && count($perms) >= count($this->keys)) { $retval = ""; foreach($this->keys as $dbColName) { if(isset($perms[$dbColName])) { //get the last character of the column name. - $permChar = substring($dbColName, -1); - if($perms[$dbColName] === false) { + $permChar = substr($dbColName, -1); + if($perms[$dbColName] === false || !strlen($perms[$dbColName]) || $perms[$dbColName] === '-' || $perms[$dbColName] === 'f') { + $permChar = '-'; } $retval .= $permChar; @@ -125,13 +126,27 @@ //============================================================================ public function create_permission($name, $userId, $groupId, $permString) { if(is_string($name) && strlen($name) && is_numeric($userId) && $userId >= 0 && is_numeric($groupId) && $groupId >= 0) { + $cleanStringArr = array( + 'object_name' => 'sql', + 'user_id' => 'numeric', + 'group_id' => 'numeric', + 'u_r' => 'bool', + 'u_w' => 'bool', + 'u_x' => 'bool', + 'g_r' => 'bool', + 'g_w' => 'bool', + 'g_x' => 'bool', + 'o_r' => 'bool', + 'o_w' => 'bool', + 'o_x' => 'bool' + ); try{ $insertArr = $this->parse_permission_string($permString); $insertArr['object_name'] = $this->gfObj->cleanString($name, 'sql', 0); $insertArr['user_id'] = $userId; $insertArr['group_id'] = $groupId; - $insertSql = $this->gfObj->string_from_array($insertArr, 'insert'); + $insertSql = $this->gfObj->string_from_array($insertArr, 'insert', null, $cleanStringArr); $sql = "INSERT INTO ". self::objTable ." ". $insertSql; $newId = $this->db->run_insert($sql, self::objSeq); } @@ -160,8 +175,8 @@ //============================================================================ public function get_permission($name) { try { - $name = $this->clean_permission_name($name); - $sql = "SELECT * FROM ". self::objTable ." WHERE permission_name='". $name ."'"; + $name = $this->gfObj->cleanString($name, 'sql', 0); + $sql = "SELECT * FROM ". self::objTable ." WHERE object_name='". $name ."'"; $retval = $this->db->run_query($sql); } catch(Exception $e) { Modified: trunk/0.3/tests/testOfCSGenericPermissions.php =================================================================== --- trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-21 15:59:57 UTC (rev 173) +++ trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-21 17:56:47 UTC (rev 174) @@ -14,19 +14,29 @@ class testOfCSGenericPermissions extends UnitTestCase { //-------------------------------------------------------------------------- - function __construct() { + function setUp() { $this->gfObj = new cs_globalFunctions; $this->gfObj->debugPrintOpt=1; if(!defined('CS_UNITTEST')) { throw new exception(__METHOD__ .": FATAL: constant 'CS_UNITTEST' not set, can't do testing safely"); } $this->get_valid_users(); - }//end __construct() + $perm = new _gpTester($this->create_dbconn()); + $perm->do_schema(); + }//end setUp() //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- + public function tearDown() { + $this->remove_tables(); + } + //-------------------------------------------------------------------------- + + + + //-------------------------------------------------------------------------- private function create_dbconn() { $dbParams = array( 'host' => constant('cs_webapplibs-DB_CONNECT_HOST'), @@ -81,15 +91,96 @@ //-------------------------------------------------------------------------- public function test_userGroups() { $perm = new _gpTester($this->create_dbconn()); - $perm->do_schema(); - //create a group with an invalid group_id. - $perm->create_user_group($this->validUsers[0]['uid'],1); + //make sure there are groups available. + { + $groupList = $perm->get_all_groups(); + $keys = array_keys($groupList); + $myKey = $keys[0]; + + $this->assertTrue(is_array($groupList)); + $this->assertTrue(count($groupList) > 0); + + $this->assertTrue(isset($groupList[$myKey])); + $this->assertTrue(isset($groupList[$myKey]['group_name'])); + $this->assertTrue(isset($groupList[$myKey]['group_id'])); + } + + //create some groups. + { + $newGroupId = $perm->create_group(__METHOD__); + $this->assertTrue(is_numeric($newGroupId)); + + $groupList = $perm->get_all_groups(); + + foreach($groupList as $groupData) { + $this->assertEqual($perm->get_group_by_id($groupData['group_id']), $groupData); + $this->assertEqual($perm->get_group($groupData['group_name']), $groupData); + } + } + + //create & test user_group relationships. + { + $newId = $perm->create_user_group($this->validUsers[$myKey]['uid'],1); + $this->assertTrue(is_numeric($newId)); + + $ugList = $perm->get_user_groups($this->validUsers[$myKey]['uid']); + $this->assertTrue(is_array($ugList)); + $this->assertTrue(count($ugList) > 0); + $this->assertFalse(isset($ugList['group_name'])); + } }//end test_userGroups //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + public function test_permissions() { + + $perm = new _gpTester($this->create_dbconn()); + + //Test permission string parsing. + { + $myPermArr = array( + 'u_r' => 'x', + 'u_w' => 'x', + 'u_x' => 'r', + 'g_r' => '-', + 'g_w' => '-', + 'g_x' => '', + 'o_r' => '', + 'o_w' => '-', + 'o_x' => 'x' + ); + $permString = 'rwx-----x'; + + $this->assertEqual(strlen($perm->make_perm_string($myPermArr)),9); + $this->assertEqual(count($perm->parse_perm_string($permString)), 9); + $this->assertEqual($perm->make_perm_string($myPermArr), $permString); + $this->assertEqual(array_keys($perm->parse_perm_string($permString)), array_keys($myPermArr)); + $this->assertEqual($perm->make_perm_string($perm->parse_perm_string($permString)), $permString); + $this->assertEqual(array_keys($perm->parse_perm_string($perm->make_perm_string($myPermArr))), array_keys($myPermArr)); + } + + //create some permissions. + { + $userKeys = array_keys($this->validUsers); + $myUser = $this->validUsers[$userKeys[0]]; + + $usePermString = 'rwxrw-rw-'; + $usePermName = __METHOD__ .'/test1'; + $permId = $perm->create_permission($usePermName, $myUser['uid'], 1, $usePermString); + $this->assertTrue(is_numeric($permId)); + + //the method 'build_permissions_string()' should disregard extra indices in the array & build the string. + $this->assertEqual($perm->make_perm_string($perm->get_permission_by_id($permId)), $usePermString); + $this->assertEqual($perm->make_perm_string($perm->get_object_by_id($permId)), $usePermString); + $this->assertEqual($perm->make_perm_string($perm->get_permission($usePermName)), $usePermString); + $this->assertEqual($perm->make_perm_string($perm->get_object($usePermName)), $usePermString); + } + }//end test_permissions + //-------------------------------------------------------------------------- + } class _gpTester extends cs_genericPermission { @@ -100,5 +191,13 @@ public function do_schema() { $this->build_schema(); } + + public function make_perm_string(array $perms) { + return($this->build_permission_string($perms)); + } + + public function parse_perm_string($string) { + return($this->parse_permission_string($string)); + } } ?> Modified: trunk/0.3/tests/testOfCSWebAppLibs.php =================================================================== --- trunk/0.3/tests/testOfCSWebAppLibs.php 2010-06-21 15:59:57 UTC (rev 173) +++ trunk/0.3/tests/testOfCSWebAppLibs.php 2010-06-21 17:56:47 UTC (rev 174) @@ -291,7 +291,7 @@ // now REALLY test paths. { - #$gdl = new gdlTester($this->create_dbconn()); + $gdl = new gdlTester($this->create_dbconn()); $myBasePath = '/character/sheet/Xander Cage'; $x->set_base_path($myBasePath); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-06-23 13:46:04
|
Revision: 175 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=175&view=rev Author: crazedsanity Date: 2010-06-23 13:45:57 +0000 (Wed, 23 Jun 2010) Log Message: ----------- Better enumeration of permission bits + testing & removal of misleading example. /docs/example_genericPermission.php [DELETED]: * removed unnecessary (misleading) example. /tests/testOfCSGenericPermissions.php: * new tests: -- check if user is member of a group after user_group record created -- create permission by type array, enumerating user/group/other perms for sanity checking. -- test to ensure permission doesn't already exist before creating. -- check has_*_permission() for several users to mostly ensure that everything is working as intended. /abstract/cs_genericUserGroup.abstract.class.php: * get_user_groups(): -- minor comment change -- wording change on exception * is_group_member() [NEW]: -- determines if a user is member of a given groupId, instead of having to manually check user's entire group list. /cs_genericPermission.class.php: * ADDED HEADERS: -- __construct() -- parse_permission_string() -- build_permission_string() -- create_object() -- create_permission() -- get_object() -- get_permission() -- get_object_by_id() -- get_permission_by_id() * build_permission_string(): -- use evaluate_perm_value() instead of arbitrary check when deciding between "-" and the given permission bit (r/w/x) * check_permission() [NEW]: -- retrieves a permission list for the given user for the given object. * get_permission_list() [NEW]: -- returns an array of permission bits based on type (u/g/o) * evaluate_perm_value() [NEW]: -- determine if a particular bit's value is true/false (defaults to true, keeping in line with PHP's true/false evaluation). * permission_exists() [NEW]: -- true/false determination of whether or not a permission exists. -- NOTE::: this is just like using a try/catch around get_permission() where an exception means false; it is just a simpler approach. * has_read_permission() [NEW]: -- true/false whether user has read permission for the given named object. * has_write_permission() [NEW]: -- true/false if user has write permission for given named object. * has_execute_permission() [NEW]: -- true/false if user has execute permission for given named object. Modified Paths: -------------- trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php trunk/0.3/cs_genericPermission.class.php trunk/0.3/tests/testOfCSGenericPermissions.php Removed Paths: ------------- trunk/0.3/docs/example_genericPermission.php Modified: trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php 2010-06-21 17:56:47 UTC (rev 174) +++ trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php 2010-06-23 13:45:57 UTC (rev 175) @@ -57,15 +57,28 @@ $retval = $this->db->run_query($sql, 'group_id'); } catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to locate group (". $groupName ."), DETAILS::: ". $e->getMessage()); + throw new exception(__METHOD__ .":: failed to locate groups for user_id=(". $userId ."), DETAILS::: ". $e->getMessage()); } } else { throw new exception(__METHOD__ .":: invalid or non-numeric user_id (". $userId .")"); } return($retval); - }//end get_group() + }//end get_user_groups() //============================================================================ + + + //============================================================================ + public function is_group_member($userId, $groupId) { + $groupList = $this->get_user_groups($userId); + $retval = false; + if(isset($groupList[$groupId])) { + $retval = true; + } + return($retval); + }//end is_group_member() + //============================================================================ + } ?> Modified: trunk/0.3/cs_genericPermission.class.php =================================================================== --- trunk/0.3/cs_genericPermission.class.php 2010-06-21 17:56:47 UTC (rev 174) +++ trunk/0.3/cs_genericPermission.class.php 2010-06-23 13:45:57 UTC (rev 175) @@ -29,6 +29,9 @@ protected $keys = array(); //============================================================================ + /** + * Generic permission system based on *nix filesystem permissions. + */ public function __construct(cs_phpDB $db) { $this->db = $db; parent::__construct($db); @@ -63,6 +66,9 @@ //============================================================================ + /** + * Parses a string like 'rwxr-xr--' into keys for the database. + */ protected function parse_permission_string($string) { $this->_sanityCheck(); if(is_string($string) && strlen($string) == 9) { @@ -87,6 +93,9 @@ //============================================================================ + /** + * Create permission string based on an array (the opposite of parse_permission_string()) + */ protected function build_permission_string(array $perms) { $this->_sanityCheck(); if(is_array($perms) && count($perms) >= count($this->keys)) { @@ -94,9 +103,11 @@ foreach($this->keys as $dbColName) { if(isset($perms[$dbColName])) { //get the last character of the column name. - $permChar = substr($dbColName, -1); - if($perms[$dbColName] === false || !strlen($perms[$dbColName]) || $perms[$dbColName] === '-' || $perms[$dbColName] === 'f') { - + $thisPermChar = substr($dbColName, -1); + if($this->evaluate_perm_value($perms[$dbColName], $thisPermChar)) { + $permChar = substr($dbColName, -1); + } + else { $permChar = '-'; } $retval .= $permChar; @@ -116,6 +127,9 @@ //============================================================================ + /** + * Same as create_permission(). + */ public function create_object($name, $userId, $groupId, $permString) { return($this->create_permission($name, $userId, $groupId, $permString)); }//end create_object() @@ -124,6 +138,9 @@ //============================================================================ + /** + * Creates a permission object record. + */ public function create_permission($name, $userId, $groupId, $permString) { if(is_string($name) && strlen($name) && is_numeric($userId) && $userId >= 0 && is_numeric($groupId) && $groupId >= 0) { $cleanStringArr = array( @@ -165,6 +182,9 @@ //============================================================================ + /** + * Same as get_permission(). + */ public function get_object($name) { return($this->get_permission($name)); }//end get_object() @@ -173,6 +193,9 @@ //============================================================================ + /** + * Retrieves a permission object by name from the database, exception on failure. + */ public function get_permission($name) { try { $name = $this->gfObj->cleanString($name, 'sql', 0); @@ -190,6 +213,9 @@ //============================================================================ + /** + * Same as get_permission_by_id(). + */ public function get_object_by_id($objectId) { return($this->get_permission_by_id($objectId)); }//end get_object_by_id() @@ -198,6 +224,9 @@ //============================================================================ + /** + * Retrieves a permission object from the database based on an ID. + */ public function get_permission_by_id($permId) { try { if(!is_null($permId) && is_numeric($permId)) { @@ -215,5 +244,159 @@ return($retval); }//end get_permission_by_id() //============================================================================ + + + + //============================================================================ + /** + * Check available permissions... + */ + public function check_permission($objectName, $userId) { + $availablePerms = array( + 'r' => false, + 'w' => false, + 'x' => false + ); + + try { + //get the object. + $permission = $this->get_permission($objectName); + + //now figure out what permissions they have. + if($permission['user_id'] == $userId) { + //it is the owner, determine based on the permissions with the 'u_' prefix. + $availablePerms = $this->get_permission_list($permission, 'u'); + } + elseif($this->is_group_member($userId, $permission['group_id'])) { + //group member, use the 'g_' permissions. + $availablePerms = $this->get_permission_list($permission, 'g'); + } + else { + //not owner OR group member, use the 'o_' permissions + $availablePerms = $this->get_permission_list($permission, 'o'); + } + } + catch(Exception $e) { + //consider logging this... maybe based on some internal variable. + } + + return($availablePerms); + }//end check_permission() + //============================================================================ + + + + //============================================================================ + /** + * Creates an array of permission bits based on user/group/other from the given + * permission data (i.e. the return from get_permission()). + */ + protected function get_permission_list(array $permData, $type) { + $retval = array(); + if(in_array($type, array('u', 'g', 'o'))) { + foreach($this->keys as $myKey) { + if(preg_match('/'. $type .'_[rwx]$/',$myKey)) { + //chop the last character off (i.e. 'r' from 'u_r') + $myPermChar = substr($myKey, -1); + #$retval[$myPermChar] = $this->gfObj->interpret_bool($permData[$myKey], array('f', 't')); + $retval[$myPermChar] = $this->evaluate_perm_value($permData[$myKey], $type); + } + } + } + else { + throw new exception(__METHOD__ .":: invalid type (". $type ."), must be u/g/o"); + } + + return($retval); + }//end get_permission_list() + //============================================================================ + + + + //============================================================================ + /** + * Evaluate the value in a permission bit as true (allowed) or false (disallowed). + */ + protected function evaluate_perm_value($val=null) { + + if($val === '-' || $val === false || $val === 'f' || $val === 0 || $val === '0' || !strlen($val)) { + $retval = false; + } + else { + $retval = true; + } + return($retval); + }//end evaluate_perm_value + //============================================================================ + + + + //============================================================================ + /** + * Determines if a permission record exists (based on name). + */ + public function permission_exists($permName) { + try { + $info = $this->get_permission($permName); + $retval = false; + if(is_array($info)) { + $retval = true; + } + } + catch(Exception $e) { + $retval = false; + } + + return($retval); + }//end permission_exists() + //============================================================================ + + + + //============================================================================ + /** + * If user has read permission for the given named permission/object. + */ + public function has_read_permission($userId, $permName) { + $myPerms = $this->check_permission($permName, $userId); + $retval = false; + if($myPerms['r'] === true) { + $retval = true; + } + return($retval); + }//end has_read_permission() + //============================================================================ + + + + //============================================================================ + /** + * If user has write permission for the given named permission/object. + */ + public function has_write_permission($userId, $permName) { + $myPerms = $this->check_permission($permName, $userId); + $retval = false; + if($myPerms['w'] === true) { + $retval = true; + } + return($retval); + }//end has_write_permission() + //============================================================================ + + + + //============================================================================ + /** + * If user has execute permission for the given named permission/object. + */ + public function has_execute_permission($userId, $permName) { + $myPerms = $this->check_permission($permName, $userId); + $retval = false; + if($myPerms['x'] === true) { + $retval = true; + } + return($retval); + }//end has_execute_permission() + //============================================================================ } ?> Deleted: trunk/0.3/docs/example_genericPermission.php =================================================================== --- trunk/0.3/docs/example_genericPermission.php 2010-06-21 17:56:47 UTC (rev 174) +++ trunk/0.3/docs/example_genericPermission.php 2010-06-23 13:45:57 UTC (rev 175) @@ -1,53 +0,0 @@ -<?php - -//instantiate the permission object with a database & the proper UID. -$permObj = new cs_genericUserPermission($page->db, $_SESSION['uid']); - - -//Creating Permissions/Groups -{ - //create a group. - $permObj->create_group("blogs"); - - //define default permissions for the group. - //NOTE::: the "false" entries can be technically excluded, as the default is false. - $perms = array( - 'view' => true, - 'create' => true, - 'edit' => true, - 'set_timestamp' => true, - 'update_timestamp' => false, - 'delete_entry' => false, - 'set_draft' => true, - 'update_to_draft' => false - ); - $permObj->set_group_perms("blogs", $perms); - - //set specific permissions for a user. - //NOTE::: if the group or permission doesn't exist, this will throw an exception. - $permObj->set_user_perm("blogs", "update_timestamp"); -} - - -//Checking Permissions/Groups -{ - //get a list of permissions... - $perms = $permObj->get_user_permissions(); - - //check if the user is part of a group... in this case, the "blogs" group. - $isGroupMember = $permObj->check_group_membership("blogs"); - - //Pull all available permissions for a group... again, the "blogs" group. - $allBlogsPerms = $permObj->get_group_perms("blogs"); - - //check permissions for a specific "group" (or "object")... in this case, "can the user create a blog?" - $hasPermission = $permObj->check_permission("blogs", "create"); - - - //a more advanced check, involving membership in multiple cascading groups (unimplemented)... "can the user administratively view blogs?" - //NOTE::: the code in this method would have to allow an unlimited number of arguments (minimum 2), where the last one is the permission name. - #$permObj->check_cascading_permission("admin", "blogs", "view"); -} - - -?> Modified: trunk/0.3/tests/testOfCSGenericPermissions.php =================================================================== --- trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-21 17:56:47 UTC (rev 174) +++ trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-23 13:45:57 UTC (rev 175) @@ -123,6 +123,7 @@ { $newId = $perm->create_user_group($this->validUsers[$myKey]['uid'],1); $this->assertTrue(is_numeric($newId)); + $this->assertTrue($perm->is_group_member($this->validUsers[$myKey]['uid'],1)); $ugList = $perm->get_user_groups($this->validUsers[$myKey]['uid']); $this->assertTrue(is_array($ugList)); @@ -152,6 +153,23 @@ 'o_w' => '-', 'o_x' => 'x' ); + $permByType = array( + 'u' => array( + 'r' => true, + 'w' => true, + 'x' => true + ), + 'g' => array( + 'r' => false, + 'w' => false, + 'x' => false + ), + 'o' => array( + 'r' => false, + 'w' => false, + 'x' => true + ) + ); $permString = 'rwx-----x'; $this->assertEqual(strlen($perm->make_perm_string($myPermArr)),9); @@ -160,16 +178,23 @@ $this->assertEqual(array_keys($perm->parse_perm_string($permString)), array_keys($myPermArr)); $this->assertEqual($perm->make_perm_string($perm->parse_perm_string($permString)), $permString); $this->assertEqual(array_keys($perm->parse_perm_string($perm->make_perm_string($myPermArr))), array_keys($myPermArr)); + + $this->assertEqual($perm->get_perm_list($myPermArr,'u'), $permByType['u']); + $this->assertEqual($perm->get_perm_list($myPermArr,'g'), $permByType['g']); + $this->assertEqual($perm->get_perm_list($myPermArr,'o'), $permByType['o']); } //create some permissions. { $userKeys = array_keys($this->validUsers); $myUser = $this->validUsers[$userKeys[0]]; + $myUid = $myUser['uid']; - $usePermString = 'rwxrw-rw-'; + $usePermString = 'rwxrw-r--'; $usePermName = __METHOD__ .'/test1'; - $permId = $perm->create_permission($usePermName, $myUser['uid'], 1, $usePermString); + $this->assertFalse($perm->permission_exists($usePermName)); + $permId = $perm->create_permission($usePermName, $myUid, 1, $usePermString); + $this->assertTrue($perm->permission_exists($usePermName)); $this->assertTrue(is_numeric($permId)); //the method 'build_permissions_string()' should disregard extra indices in the array & build the string. @@ -177,6 +202,29 @@ $this->assertEqual($perm->make_perm_string($perm->get_object_by_id($permId)), $usePermString); $this->assertEqual($perm->make_perm_string($perm->get_permission($usePermName)), $usePermString); $this->assertEqual($perm->make_perm_string($perm->get_object($usePermName)), $usePermString); + + //check to make sure individual permission requests work as expected. + $this->assertTrue($perm->has_read_permission($myUid, $usePermName)); + $this->assertTrue($perm->has_write_permission($myUid, $usePermName)); + $this->assertTrue($perm->has_execute_permission($myUid, $usePermName)); + + //make sure "anonymous" permissions are correct. + $this->assertTrue($perm->has_read_permission(0,$usePermName)); + $this->assertFalse($perm->has_write_permission(0,$usePermName)); + $this->assertFalse($perm->has_execute_permission(0,$usePermName)); + + //put a second user into the proper user_group, then test group permissions. + $secondUser = $this->validUsers[$userKeys[1]]['uid']; + $this->assertTrue(is_numeric($perm->create_user_group($secondUser, 1))); + $this->assertTrue($perm->has_read_permission($secondUser, $usePermName)); + $this->assertTrue($perm->has_write_permission($secondUser, $usePermName)); + $this->assertFalse($perm->has_execute_permission($secondUser, $usePermName)); + + //test a THIRD user (non-zero uid), make sure they are subject to the same permissions as anonymous (uid=0) + $thirdUser = $this->validUsers[$userKeys[2]]['uid']; + $this->assertEqual($perm->has_read_permission(0,$usePermName), $perm->has_read_permission($thirdUser,$usePermName)); + $this->assertEqual($perm->has_write_permission(0,$usePermName), $perm->has_write_permission($thirdUser,$usePermName)); + $this->assertEqual($perm->has_execute_permission(0,$usePermName), $perm->has_execute_permission($thirdUser,$usePermName)); } }//end test_permissions //-------------------------------------------------------------------------- @@ -199,5 +247,9 @@ public function parse_perm_string($string) { return($this->parse_permission_string($string)); } + + public function get_perm_list(array $permData, $type) { + return($this->get_permission_list($permData, $type)); + } } ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-07-07 14:14:55
|
Revision: 177 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=177&view=rev Author: crazedsanity Date: 2010-07-07 14:14:46 +0000 (Wed, 07 Jul 2010) Log Message: ----------- Better checking, exceptions on invalid data, add queryList to cs_phpDB. /cs_phpDB.class.php: * MAIN::: -- NEW (public) VAR: $queryList=array() * __call(): -- if method is 'exec', add query to the queryList (holds last 20) * is_connected(): -- returns the value of dbLayerObj->is_connected(). /cs_webdblogger.class.php: * __construct(): -- throws an exception if the passed $db object isn't an object. /cs_webdbupgrade.class.php: * load_initial_version(): -- put calls to cs_phpDB methods into try/catch /abstract/cs_singleTableHandler.abstract.class.php: * MAIN::: -- changed members/vars to non-abstract (not valid) * __construct(): -- better checking of the database object. /db_types/cs_phpDB__pgsql.class.php: * exec(): -- simplify checking: if numRows() gives a good answer, use that; otherwise, use the output of numAffected(). /db_types/cs_phpDB__mysql.class.php: * exec(): -- simplify check as in pgsql layer. /db_types/cs_phpDB__sqlite.class.php: * exec(): -- simplify check as in pgsql layer. /tests/testOfCSGenericPermissions.php: * get_valid_users(): -- put stuff into try/catch. -- NOTE::: there's a call to cs_debug_backtrace(), which is a function that only exists locally. Modified Paths: -------------- trunk/0.3/abstract/cs_singleTableHandler.abstract.class.php trunk/0.3/cs_phpDB.class.php trunk/0.3/cs_webdblogger.class.php trunk/0.3/cs_webdbupgrade.class.php 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/tests/testOfCSGenericPermissions.php Modified: trunk/0.3/abstract/cs_singleTableHandler.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_singleTableHandler.abstract.class.php 2010-06-24 21:15:25 UTC (rev 176) +++ trunk/0.3/abstract/cs_singleTableHandler.abstract.class.php 2010-07-07 14:14:46 UTC (rev 177) @@ -13,11 +13,11 @@ abstract class cs_singleTableHandlerAbstract extends cs_webapplibsAbstract { protected $gfObj; - abstract protected $tableName; - abstract protected $seqName; - abstract protected $pkeyField; - abstract protected $cleanStringArr; - abstract protected $dbParams; + protected $tableName; + protected $seqName; + protected $pkeyField; + protected $cleanStringArr; + protected $dbParams; //------------------------------------------------------------------------- /** @@ -33,11 +33,11 @@ $this->set_version_file_location(dirname(__FILE__) . '/../VERSION'); parent::__construct(true); - if($dbObj->is_connnected()) { + if(isset($dbObj) && is_object($dbObj) && $dbObj->is_connected()) { $this->dbObj = $dbObj; } else { - throw new exception(__METHOD__ .":: database object not connected"); + throw new exception(__METHOD__ .":: database object not connected or not passed"); } if(is_string($tableName) && strlen($tableName)) { Modified: trunk/0.3/cs_phpDB.class.php =================================================================== --- trunk/0.3/cs_phpDB.class.php 2010-06-24 21:15:25 UTC (rev 176) +++ trunk/0.3/cs_phpDB.class.php 2010-07-07 14:14:46 UTC (rev 177) @@ -26,6 +26,7 @@ class cs_phpDB extends cs_webapplibsAbstract { + public $queryList=array(); private $dbLayerObj; private $dbType; public $connectParams = array(); @@ -60,6 +61,13 @@ //capture the connection parameters. $this->connectParams = $args[0]; } + elseif($methodName == 'exec') { + //update lastQuery list... should hold the last few SQL commands. + if(count($this->queryList) > 20) { + array_pop($this->queryList); + } + array_unshift($this->queryList, $args[0]); + } $retval = call_user_func_array(array($this->dbLayerObj, $methodName), $args); } else { @@ -204,6 +212,14 @@ return($retval); }//end run_sql_file() //========================================================================= + + + + //========================================================================= + public function is_connected() { + return($this->dbLayerObj->is_connected()); + }//end is_connected() + //========================================================================= } // end class phpDB ?> Modified: trunk/0.3/cs_webdblogger.class.php =================================================================== --- trunk/0.3/cs_webdblogger.class.php 2010-06-24 21:15:25 UTC (rev 176) +++ trunk/0.3/cs_webdblogger.class.php 2010-07-07 14:14:46 UTC (rev 177) @@ -86,7 +86,12 @@ */ public function __construct(cs_phpDB &$db, $logCategory=null, $checkForUpgrades=true) { //assign the database object. - $this->db = $db; + if(is_object($db) && get_class($db) == 'cs_phpDB') { + $this->db = $db; + } + else { + throw new exception(__METHOD__ .":: invalid database object"); + } $this->set_version_file_location(dirname(__FILE__) . '/VERSION'); Modified: trunk/0.3/cs_webdbupgrade.class.php =================================================================== --- trunk/0.3/cs_webdbupgrade.class.php 2010-06-24 21:15:25 UTC (rev 176) +++ trunk/0.3/cs_webdbupgrade.class.php 2010-07-07 14:14:46 UTC (rev 177) @@ -1058,12 +1058,17 @@ $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'); + try { + 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()); + } } - else { - $this->error_handler(__METHOD__ .": failed to load initial version::: ". $e->getMessage()); + catch(Exception $e) { + $this->error_handler(__METHOD__ .":: failed to load initial version due to exception, DETAILS::: ". $e->getMessage()); } return($loadRes); Modified: trunk/0.3/db_types/cs_phpDB__mysql.class.php =================================================================== --- trunk/0.3/db_types/cs_phpDB__mysql.class.php 2010-06-24 21:15:25 UTC (rev 176) +++ trunk/0.3/db_types/cs_phpDB__mysql.class.php 2010-07-07 14:14:46 UTC (rev 177) @@ -213,19 +213,18 @@ $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 + if($this->result !== false) { $numRows = $this->numRows(); - if($numRows > 0) { - $this->move_first(); + if($numRows != 0) { + $returnVal = $numRows; + if($numRows > 0) { + $this->move_first(); + } } - $returnVal = $numRows; - + else { + $returnVal = $this->numAffected(); + } } - else { - //We got something other than an update. Use numAffected - $returnVal = $this->numAffected(); - } } return($returnVal); }//end exec() Modified: trunk/0.3/db_types/cs_phpDB__pgsql.class.php =================================================================== --- trunk/0.3/db_types/cs_phpDB__pgsql.class.php 2010-06-24 21:15:25 UTC (rev 176) +++ trunk/0.3/db_types/cs_phpDB__pgsql.class.php 2010-07-07 14:14:46 UTC (rev 177) @@ -230,27 +230,25 @@ if($this->useQueryList) { $this->queryList[] = $query; } - $returnVal = false; + $returnVal = false; if(($this->get_transaction_status() != -1) && ($this->connectionID != -1)) { $this->result = @pg_query($this->connectionID, $query); 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(); + $numRows = $this->numRows(); + if($numRows != 0) { + $returnVal = $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() //========================================================================= Modified: trunk/0.3/db_types/cs_phpDB__sqlite.class.php =================================================================== --- trunk/0.3/db_types/cs_phpDB__sqlite.class.php 2010-06-24 21:15:25 UTC (rev 176) +++ trunk/0.3/db_types/cs_phpDB__sqlite.class.php 2010-07-07 14:14:46 UTC (rev 177) @@ -178,13 +178,14 @@ $this->result = @sqlite_query($this->connectionID, $query); 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(); + $numRows = $this->numRows(); + if($numRows != 0) { $returnVal = $numRows; + if($numRows > 0) { + $this->move_first(); + } } else { - //We got something other than an update. Use numAffected $returnVal = $this->numAffected(); } } Modified: trunk/0.3/tests/testOfCSGenericPermissions.php =================================================================== --- trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-24 21:15:25 UTC (rev 176) +++ trunk/0.3/tests/testOfCSGenericPermissions.php 2010-07-07 14:14:46 UTC (rev 177) @@ -81,8 +81,14 @@ */ private function get_valid_users() { $sql = "SELECT uid,username FROM cs_authentication_table ORDER BY uid"; - $db = $this->create_dbconn(); - $this->validUsers = $db->run_query($sql); + try { + $db = $this->create_dbconn(); + $this->validUsers = $db->run_query($sql); + } + catch(Exception $e) { + cs_debug_backtrace(1); + throw new exception(__METHOD__ .":: failed to retrieve any records (". $db->numRows() ."), DB OBJECT::: ". $this->gfObj->debug_print($db,0)); + } }//end get_valid_users() //-------------------------------------------------------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cra...@us...> - 2010-07-23 14:17:31
|
Revision: 180 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=180&view=rev Author: crazedsanity Date: 2010-07-23 14:17:25 +0000 (Fri, 23 Jul 2010) Log Message: ----------- Updates to single-table handling & minor bug fixes. /cs_phpDB.class.php: * run_insert(): -- fix call to numRows() (was mistyped to instead appear to access a property instead of a method. /abstract/cs_singleTableHandler.abstract.class.php: * get_single_record(): -- header updated with new functionality -- accepts an array which is passed on to get_records() to allow for complex queries. -- forcibly limit result to 1 -- NOTE::: it may be desirable to allow an ordering too, and possibly a limit + offset, and NOT force limit to 1: if more than a single record is returned, it can throw an exception (the current way will always return a single record, but might actually be lulling them into a false sense of security due to the forced limit). * get_records(): -- minor update for header * update_record(): -- extra check to ensure cs_globalFunctions::string_from_array() actually created a string (handles the situation where all items in the array have empty values and are thereby removed) Modified Paths: -------------- trunk/0.3/abstract/cs_singleTableHandler.abstract.class.php trunk/0.3/cs_phpDB.class.php Modified: trunk/0.3/abstract/cs_singleTableHandler.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_singleTableHandler.abstract.class.php 2010-07-09 16:43:30 UTC (rev 179) +++ trunk/0.3/abstract/cs_singleTableHandler.abstract.class.php 2010-07-23 14:17:25 UTC (rev 180) @@ -125,23 +125,24 @@ //------------------------------------------------------------------------- /** - * Just a simple wrapper to get_records(), no initial (id-based) record used. + * Just a simple wrapper to get_records(), guaranteed to return a single record. * - * @param $fieldname (str) field to search (for $value) - * @param $value (str) value to find (in $field) - * @param $orderBy (str) field to order by; can contain "DESC" or "ASC" - * @param $limit (int) how many records to display - * @param $offset (int) offset by this many records + * @param $filter (array) fieldname=>value list of filters. * * @RETURN (array) SUCCESS: returns single record with all fields. * @EXCEPTION FAIL: exception indicates error */ - protected function get_single_record($fieldname, $value, $orderBy=null, $limit=null, $offset=null) { - $data = $this->get_records(array($fieldname=>$value), $orderBy, $limit, $offset); + protected function get_single_record(array $filter) { + try { + $data = $this->get_records($filter, null, 1); + + $keys = array_keys($data); + $retval = $data[$keys[0]]; + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to retrieve record, DETAILS::: ". $e->getMessage()); + } - $keys = array_keys($data); - $retval = $data[$keys[0]]; - return($retval); }//end get_single_record() //------------------------------------------------------------------------- @@ -153,7 +154,7 @@ * Retrieves a number of records based on arguments. * * @$filter (array) Field=>value list of filters (i.e. 'my_id'=>1) - * @$orderBy (str) Field to order by; can contain "DESC" or "ASC". + * @$orderBy (str) Field to order by; can contain "DESC" or "ASC". * @$limit (int) How many max records to display. * @$offset (int) Offset by this number of records. * @@ -204,20 +205,27 @@ * @RETURN (int) SUCCESS: (int) is the number of records updated (should always be 1) * @EXCEPTION FAIL: exception indicates the error. */ - protected function update_record($recId, array $updates) { + protected function update_record($recId, array $updates, $removeEmptyVals=true) { if(is_numeric($recId) && $recId >= 0 && is_array($updates) && count($updates) > 0) { - $sql = 'UPDATE '. $this->tableName .' SET ' - . $this->gfObj->string_from_array($updates, 'update', null, $this->cleanStringArr, true) - .' WHERE '. $this->pkeyField .'='. $recId; - try { - $retval = $this->dbObj->run_update($sql, true); + $updateString = $this->gfObj->string_from_array($updates, 'update', null, $this->cleanStringArr, $removeEmptyVals); + if(is_null($updateString) || !strlen($updateString) || strlen($updateString) < 3) { + throw new exception(__METHOD__ .":: no update string created (". $updateSTring ."), contents::: ". $this->gfObj->debug_var_dump($updates,0)); } - catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to update record (". $recId ."), DETAILS::: ". $e->getMessage()); + else { + $sql = 'UPDATE '. $this->tableName .' SET ' + . $updateString + .' WHERE '. $this->pkeyField .'='. $recId; + try { + $retval = $this->dbObj->run_update($sql, true); +#$this->gfObj->debug_print(__METHOD__ .":: retval=(". $retval ."), SQL::: ". $sql ,1); + } + catch(Exception $e) { + throw new exception(__METHOD__ .":: failed to update record (". $recId ."), DETAILS::: ". $e->getMessage()); + } } } else { - throw new exception(__METHOD__ .":: failed to update record (". $recId ."), DETAILS::: ". $e->getMessage()); + throw new exception(__METHOD__ .":: failed to update record (". $recId ."), invalid recordId (". $recId ."), or no data in array::: ". $this->gfObj->debug_var_dump($updates,0)); } return($retval); }//end update_record() Modified: trunk/0.3/cs_phpDB.class.php =================================================================== --- trunk/0.3/cs_phpDB.class.php 2010-07-09 16:43:30 UTC (rev 179) +++ trunk/0.3/cs_phpDB.class.php 2010-07-23 14:17:25 UTC (rev 180) @@ -151,7 +151,7 @@ } else { //something broke... - throw new exception(__METHOD__ .": failed to insert, rows=(". $this->numRows .")... " + throw new exception(__METHOD__ .": failed to insert, rows=(". $this->numRows() .")... " ."ERROR::: ". $this->errorMsg() ."\n -- SQL:::: ". $sql); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |