[Tm-svn] SF.net SVN: tigermouse: [197] lib
Status: Alpha
Brought to you by:
strongier
From: <str...@us...> - 2008-02-26 21:55:13
|
Revision: 197 http://tigermouse.svn.sourceforge.net/tigermouse/?rev=197&view=rev Author: strongier Date: 2008-02-26 13:55:19 -0800 (Tue, 26 Feb 2008) Log Message: ----------- Cleanup in lib/model classes Modified Paths: -------------- lib/model/active-record/ActiveRecord.class.php lib/model/active-record/test/ActiveRecord.test.php lib/model/data-source/SQLDataSource.class.php lib/model/db-adapter/DBAdapter.class.php lib/model/sql/MicrosoftSQLDialect.class.php lib/model/sql/MySQLDialect.class.php lib/model/sql/SQL92Dialect.class.php lib/model/sql/SQLDialect.class.php lib/model/table-gateway/test/TableGateway.test.php lib/translation/WikiTranslator.class.php Added Paths: ----------- lib/access/AuthService.class.php lib/access/IAuthorizable.interface.php lib/model/db-adapter/DBFactory.class.php Removed Paths: ------------- lib/model/db-adapter/ADOdbAdapter.class.php lib/model/db-adapter/PDOAdapter.class.php lib/model/db-adapter/PEARDBAdapter.class.php Added: lib/access/AuthService.class.php =================================================================== --- lib/access/AuthService.class.php (rev 0) +++ lib/access/AuthService.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -0,0 +1,80 @@ +<?php + +final class AuthService { + + + + public static function hash($data) { + // this function generated pretty good hash, so even weak passwords + // are harder to decrypt in case of data leak + return md5(crc32($data) . $data . '12345'); + } + + + + public static function getCurrentUserId() { + if (array_key_exists('AuthService', $_SESSION)) { + return $_SESSION['AuthService']; + } + if (array_key_exists('AuthService_ln', $_COOKIE) and array_key_exists('AuthService_pw', $_COOKIE)) { + if ($userId = self::authenticate($_COOKIE['AuthService_ln'], $_COOKIE['AuthService_pw'], true)) { + $_SESSION['AuthService'] = $userId; + return $userId; + } + } + return null; + } + + + + public static function getCurrentUser() { + $u = new User(); + if ($id = self::getCurrentUserId()) { + $u->loadById($id); + } + return $u; + } + + + + public static function authenticate($login, $password, $hashed = false) { + $u = new User(); + $out = $u->loadByFieldValue('login', $login); + if ($u->password == ($hashed ? $password : self::hash($password))) { + return $u->getPrimaryKeyValue(); + } + return null; + } + + + + public static function login($id) { + $u = new User(); + $u->loadById($id); + $_SESSION['AuthService'] = $id; + $expiry = time() + 3600 * 24 * 60; + setcookie('AuthService_ln', $u->login, $expiry); + setcookie('AuthService_pw', $u->password, $expiry); + } + + + + public static function logout() { + unset($_SESSION['AuthService']); + setcookie('AuthService_ln', null); + setcookie('AuthService_pw', null); + unset($_COOKIE['AuthService_ln']); + unset($_COOKIE['AuthService_pw']); + } + + + + public static function isAdmin() { + return self::getCurrentUser()->is_admin == '1'; + } + + + +} // class AuthService + +?> \ No newline at end of file Added: lib/access/IAuthorizable.interface.php =================================================================== --- lib/access/IAuthorizable.interface.php (rev 0) +++ lib/access/IAuthorizable.interface.php 2008-02-26 21:55:19 UTC (rev 197) @@ -0,0 +1,29 @@ +<?php + +interface IAuthorizable { + + + + /** + * Returns unique identifier + * + * Distinctive identifier MUST be unique per class. + * @return int + */ + public function getDistinctiveId(); + + + + /** + * Return array of access modes + * + * Example modes are 'read', 'write', 'delete', 'create', etc. + * @return array + */ + public function getAccessModes(); + + + +} // interface IAuthorizable + +?> \ No newline at end of file Modified: lib/model/active-record/ActiveRecord.class.php =================================================================== --- lib/model/active-record/ActiveRecord.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/active-record/ActiveRecord.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -6,20 +6,24 @@ * Persistent object stored as a record in database table. * Handles 1-to-many and many-to-many relations. * - * @version DR1.6 + * @version DR1.8 */ abstract class ActiveRecord implements IteratorAggregate { + public static $createTableFromMap = true; + protected $tableName; protected $primaryKey = 'id'; protected $sequenceName = ''; protected $data; + protected $columns = array(); protected $modified = false; protected $dbAdapter; + protected $db = 'default'; protected $hasMany = array(); // array(field => array(className, foreignKey in this class)) protected $properties = array(); @@ -35,6 +39,42 @@ public function __construct() { $this->data = new ArrayObject(); $this->dbAdapter = $this->buildDBAdapter(); + // experimental support for table maps + // does not work with PDO < 1.2.0 +/* + $mapFile = 'var/cache/active-record/' . md5(get_class($this)); + if (!file_exists($mapFile)) { + try { + $this->dbAdapter->execute("SELECT * FROM {$this->tableName} LIMIT 1"); + } catch (Exception $e) { + throw new Exception("table '{$this->tableName}' not found while rebuilding map file"); + } + $meta = $this->dbAdapter->getMeta(); + if ($meta) { + file_put_contents($mapFile, serialize($meta)); + foreach ($meta as $m) { + $this->columns[$m['name']] = $m; + } + } + } elseif (self::$createTableFromMap) { + try { + $this->dbAdapter->execute("SELECT * FROM {$this->tableName} LIMIT 1"); + } catch (Exception $e) { + $dialect = $this->dbAdapter->getDialect(); + $meta = unserialize(file_get_contents($mapFile)); + $out = array(); + foreach ($meta as $m) { + $name = $m['name']; + $type = ($name == $this->primaryKey) + ? $dialect->getPrimaryKeyDefinition(true) + : $m['native_type']; + $out[] = "\t$name\t$type"; + } + $sql = "CREATE TABLE {$this->tableName} (\n" . implode(",\n", $out) . "\n)"; + $this->dbAdapter->execute($sql); + } + } +*/ } @@ -49,7 +89,7 @@ * @return DBAdapter */ protected function buildDBAdapter() { - return DBFactory::getAdapter(); + return DBFactory::getAdapter($this->db); } Modified: lib/model/active-record/test/ActiveRecord.test.php =================================================================== --- lib/model/active-record/test/ActiveRecord.test.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/active-record/test/ActiveRecord.test.php 2008-02-26 21:55:19 UTC (rev 197) @@ -7,7 +7,6 @@ require '../../sql/SQLDialect.class.php'; require '../../sql/SQL92Dialect.class.php'; require '../../db-adapter/DBAdapter.class.php'; -require '../../db-adapter/PDOAdapter.class.php'; require '../ActiveRecord.class.php'; require '../OneToManyRelation.class.php'; require '../ManyToManyRelation.class.php'; @@ -15,7 +14,7 @@ $sqliteFile = '../../../../var/sqlite/test.sqlite'; $pdo = new PDO('sqlite:' . $sqliteFile); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -$db = new PDOAdapter($pdo, new SQL92Dialect()); +$db = new DBAdapter($pdo, new SQL92Dialect()); class MyActiveRecord extends ActiveRecord { Modified: lib/model/data-source/SQLDataSource.class.php =================================================================== --- lib/model/data-source/SQLDataSource.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/data-source/SQLDataSource.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -21,7 +21,7 @@ - public function fetch() { + public function fetch() { $this->adapter->execute($this->getSQL()); return $this->adapter->getIterator(); } Deleted: lib/model/db-adapter/ADOdbAdapter.class.php =================================================================== --- lib/model/db-adapter/ADOdbAdapter.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/db-adapter/ADOdbAdapter.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -1,68 +0,0 @@ -<?php - -/** - * Database access adapter for ADOdb library - * - * @note CURRENT IMPLEMENTATION DOES NOT SUPPORT READING LAST INSERT ID FROM SEQUENCE - * @version DR1.4.2 - */ -class ADOdbAdapter extends DBAdapter { - - - - protected $ado; - protected $dialect; - protected $result; - - - - public function __construct(ADOConnection $ado, SQLDialect $dialect) { - $this->ado = $ado; - $this->dialect = $dialect; - $this->result = new ArrayObject(); - } - - - - public function execute($sql, $sequenceName = null) { - $this->result = new ArrayObject(); - $sql = trim($sql); - if (preg_match('/^SELECT/i', $sql)) { - $out = $this->ado->Execute($sql); - if ($out) { - while (!$out->EOF) { - $this->result[] = $out->fields; - $out->MoveNext(); - } - $out->Close(); - return true; - } - return false; - } - $out = $this->ado->Execute($sql); - if (!$out) { - return false; - } - if (!$sequenceName or !preg_match('/^INSERT/i', $sql)) { - return true; - } - return $this->pdo->Insert_ID(); - } - - - - public function getIterator() { - return $this->result->getIterator(); - } - - - - public function getDialect() { - return $this->dialect; - } - - - -} // class ADOdbAdapter - -?> \ No newline at end of file Modified: lib/model/db-adapter/DBAdapter.class.php =================================================================== --- lib/model/db-adapter/DBAdapter.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/db-adapter/DBAdapter.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -1,13 +1,61 @@ <?php -abstract class DBAdapter implements IteratorAggregate{ +/** + * Database access adapter for PDO library + * + * @version DR1.8 + */ +class DBAdapter implements IteratorAggregate { - abstract public function execute($sql, $sequenceName = null); + protected $pdo; + protected $dialect; + protected $result; + protected $meta; + protected $doRequestMeta; + public function __construct(PDO $pdo, SQLDialect $dialect, $doRequestMeta = false) { + $this->pdo = $pdo; + $this->dialect = $dialect; + $this->doRequestMeta = $doRequestMeta; + $this->result = new ArrayObject(); + } + + + + public function execute($sql, $sequenceName = null) { + $sql = trim($sql); + if (preg_match('/^SELECT/i', $sql)) { + $out = $this->pdo->query($sql); + if ($out instanceof PDOStatement) { + $this->result = new ArrayObject($out->fetchAll(PDO::FETCH_ASSOC)); + if ($this->doRequestMeta) { + foreach ($this->result as $k => $v) { + $this->meta[$v] = $out->getColumnMeta($k); + } + } + $out->closeCursor(); + } else { + $this->result = new ArrayObject(); + } + return true; + } + $this->meta = null; + $out = $this->pdo->exec($sql); + if ($out === false) { + return false; + } + if (!$sequenceName or !preg_match('/^INSERT/i', $sql)) { + return true; + } + return $this->pdo->lastInsertId($sequenceName); + } + + + public function getResult() { return $this->result; } @@ -15,15 +63,39 @@ public function getIterator() { - throw new Exception('overwrite this method'); + return new ArrayIterator($this->result); } - abstract public function getDialect(); + public function getDialect() { + return $this->dialect; + } +/* + public function getMeta() { +// return $this->meta; +return array( + array( + 'name' => 'id', + 'native_type' => 'integer', + ), + array( + 'name' => 'name', + 'native_type' => 'varchar', + ), + array( + 'name' => 'phone', + 'native_type' => 'varchar', + ) +); + } +*/ + + + } // class DBAdapter ?> \ No newline at end of file Added: lib/model/db-adapter/DBFactory.class.php =================================================================== --- lib/model/db-adapter/DBFactory.class.php (rev 0) +++ lib/model/db-adapter/DBFactory.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -0,0 +1,95 @@ +<?php + +/** + * Provides configured database access adapter + * + * Use <code>DBFactory::getAdapter()</code> to get DBAdapter. + * There is only one instance of DBAdapter created. + * + * @version DR1.8 + */ +final class DBFactory { + + + + public static $iniFile = '/var/db/live.ini'; + public static $defaultDb = 'default'; + private static $definitions = array(); + private static $connections = array(); + + + + private function __construct() { + + } + + + + protected static function init() { + if (!file_exists($fn = self::$iniFile)) { + throw new Exception("Database ini file '$fn' not found"); + } + $f = file(self::$iniFile); + $sections = array(); + $db = null; + foreach ($f as $ln) { + if (preg_match('/^\[.*\]$/', $ln)) { + $db = trim($ln, "[] \n\t"); + } elseif ($db and $p = strpos($ln, '=')) { + $k = trim(substr($ln, 0, $p)); + $v = trim(substr($ln, $p + 1)); + $sections[$db][$k] = $v; + } + } + self::$definitions = $sections; + } + + + + /** + * Returns instance of DBAdapter + * + * @return DBAdapter + */ + protected static function buildConnection($name) { + if (!array_key_exists('dsn', self::$definitions[$name])) { + throw new Exception("could not find dsn for entry '$name' in '" . self::$iniFile . "'"); + } + $dsn = @self::$definitions[$name]['dsn']; + $user = @self::$definitions[$name]['user']; + $pass = @self::$definitions[$name]['pass']; + try { + $pdo = new PDO($dsn, $user, $pass); + $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } catch (Exception $e) { + die($e->getMessage()); + } + return new DBAdapter($pdo, new SQL92Dialect()); + } + + + + /** + * Returns instance of DBAdapter, creates it when needed + * + * @return DBAdapter + */ + public static function getAdapter($name = null) { + if (empty(self::$connections)) { + self::init(); + } + $name or ($name = self::$defaultDb); + if (!array_key_exists($name, self::$definitions)) { + throw new Exception("Could not find definition for '$name' in '" . self::$iniFile . "'"); + } + if (!array_key_exists($name, self::$connections)) { + self::$connections[$name] = self::buildConnection($name); + } + return self::$connections[$name]; + } + + + +} // class DBFactory + +?> \ No newline at end of file Deleted: lib/model/db-adapter/PDOAdapter.class.php =================================================================== --- lib/model/db-adapter/PDOAdapter.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/db-adapter/PDOAdapter.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -1,64 +0,0 @@ -<?php - -/** - * Database access adapter for PDO library - * - * @version DR1.4.2 - */ -class PDOAdapter extends DBAdapter { - - - - protected $pdo; - protected $dialect; - protected $result; - - - - public function __construct(PDO $pdo, SQLDialect $dialect) { - $this->pdo = $pdo; - $this->dialect = $dialect; - $this->result = new ArrayObject(); - } - - - - public function execute($sql, $sequenceName = null) { - $sql = trim($sql); - if (preg_match('/^SELECT/i', $sql)) { - $out = $this->pdo->query($sql); - if ($out instanceof PDOStatement) { - $this->result = new ArrayObject($out->fetchAll(PDO::FETCH_ASSOC)); - $out->closeCursor(); - } else { - $this->result = new ArrayObject(); - } - return true; - } - $out = $this->pdo->exec($sql); - if ($out === false) { - return false; - } - if (!$sequenceName or !preg_match('/^INSERT/i', $sql)) { - return true; - } - return $this->pdo->lastInsertId($sequenceName); - } - - - - public function getIterator() { - return new ArrayIterator($this->result); - } - - - - public function getDialect() { - return $this->dialect; - } - - - -} // class PDOAdapter - -?> \ No newline at end of file Deleted: lib/model/db-adapter/PEARDBAdapter.class.php =================================================================== --- lib/model/db-adapter/PEARDBAdapter.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/db-adapter/PEARDBAdapter.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -1,65 +0,0 @@ -<?php - -/** - * Database access adapter for PEAR::DB library - * - * @note this class has not been tested with PostgreSQL RDBMS - * - * @version DR1.4.2 - */ -class PEARDBAdapter extends DBAdapter { - - - - protected $connection; - protected $dialect; - protected $result; - - - - public function __construct(MDB2_Driver_Common $connection, SQLDialect $dialect) { - $this->connection = $connection; - $this->dialect = $dialect; - $this->result = new ArrayObject(); - } - - - - public function execute($sql, $sequenceName = null) { - $sql = trim($sql); - if (preg_match('/^SELECT/i', $sql)) { - $out = $this->connection->query($sql); - if (PEAR::isError($out)) { - $this->result = new ArrayObject(); - } else { - $this->result = new ArrayObject($out->fetchAll(MDB2_FETCHMODE_ASSOC)); - } - return true; - } - $out = $this->connection->query($sql); - if (PEAR::isError($out)) { - return false; - } - if (!$sequenceName or !preg_match('/^INSERT/i', $sql)) { - return true; - } - return $this->connection->lastInsertID(); - } - - - - public function getIterator() { - return new ArrayIterator($this->result); - } - - - - public function getDialect() { - return $this->dialect; - } - - - -} // class PEARDBAdapter - -?> \ No newline at end of file Modified: lib/model/sql/MicrosoftSQLDialect.class.php =================================================================== --- lib/model/sql/MicrosoftSQLDialect.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/sql/MicrosoftSQLDialect.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -9,6 +9,12 @@ + public function escape($s) { + return pg_escape_string($s); + } + + + public function getTrue() { return 'true'; } Modified: lib/model/sql/MySQLDialect.class.php =================================================================== --- lib/model/sql/MySQLDialect.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/sql/MySQLDialect.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -9,6 +9,12 @@ + public function escape($s) { + return mysqli_real_escape_string($s); + } + + + public function getTrue() { return '1'; } Modified: lib/model/sql/SQL92Dialect.class.php =================================================================== --- lib/model/sql/SQL92Dialect.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/sql/SQL92Dialect.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -11,6 +11,12 @@ + public function escape($s) { + return pg_escape_string($s); + } + + + public function getTrue() { return 'true'; } @@ -29,6 +35,14 @@ + public function getPrimaryKeyDefinition($autoincrement) { + return $autoincrement + ? 'integer primary key autoincrement' + : 'integer primary key'; + } + + + public function getSQL($sql, $order, $descending, $offset, $limit) { if ($order) { $asc = $descending ? 'DESC' : 'ASC'; Modified: lib/model/sql/SQLDialect.class.php =================================================================== --- lib/model/sql/SQLDialect.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/sql/SQLDialect.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -12,6 +12,10 @@ + abstract public function escape($s); + + + abstract public function getTrue(); @@ -24,6 +28,10 @@ + abstract public function getPrimaryKeyDefinition($autoincrement); + + + /** * Reformats SELECT querry * @@ -48,7 +56,7 @@ $keys[] = $q . $key . $q; $vals[] = ($value === null) ? 'NULL' - : "'$value'"; + : '\'' . $this->escape($value) . '\''; } $keysList = implode(', ', $keys); $valsList = implode(', ', $vals); @@ -63,7 +71,7 @@ foreach ($record as $key => $value) { $updates[] = ($value === null) ? $q . $key . $q . '= NULL' - : $q . $key . $q . ' = \'' . $value . '\''; + : $q . $key . $q . ' = \'' . $this->escape($value) . '\''; } $updatesList = implode(', ', $updates); return "UPDATE $tableName SET $updatesList WHERE $primaryKey = '$keyValue'"; @@ -75,7 +83,7 @@ $q = $this->getQuotes(); $tableName = $q . $tableName . $q; $key = $q . $key . $q; - return "DELETE FROM $tableName WHERE $key = '$keyValue'"; + return "DELETE FROM $tableName WHERE $key = '" . $this->escape($keyValue) . '\''; } Modified: lib/model/table-gateway/test/TableGateway.test.php =================================================================== --- lib/model/table-gateway/test/TableGateway.test.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/model/table-gateway/test/TableGateway.test.php 2008-02-26 21:55:19 UTC (rev 197) @@ -7,13 +7,12 @@ require '../../sql/SQLDialect.class.php'; require '../../sql/SQL92Dialect.class.php'; require '../../db-adapter/DBAdapter.class.php'; -require '../../db-adapter/PDOAdapter.class.php'; require '../TableGateway.class.php'; $sqliteFile = '../../../../var/sqlite/test.sqlite'; $pdo = new PDO('sqlite:' . $sqliteFile); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -$db = new PDOAdapter($pdo, new SQL92Dialect()); +$db = new DBAdapter($pdo, new SQL92Dialect()); try { $db->execute("DROP TABLE employees"); } catch (Exception $e) { }; Modified: lib/translation/WikiTranslator.class.php =================================================================== --- lib/translation/WikiTranslator.class.php 2008-02-26 21:52:56 UTC (rev 196) +++ lib/translation/WikiTranslator.class.php 2008-02-26 21:55:19 UTC (rev 197) @@ -82,7 +82,7 @@ foreach (explode("\n", $value) as $ln) { // unset mode if empty line given and proceed to next line if ($ln == '') { - $this->mode = null; + $this->setMode(new WikiTranslatorTextMode()); continue; } $mode = null; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |