mirror of
https://github.com/atlanticbiomedical/portal-legacy.git
synced 2025-07-02 01:47:28 -04:00
initial commit
This commit is contained in:
42
lib/symfony/addon/bridge/sfEzComponentsBridge.class.php
Executable file
42
lib/symfony/addon/bridge/sfEzComponentsBridge.class.php
Executable file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
$sf_ez_lib_dir = sfConfig::get('sf_ez_lib_dir') ? sfConfig::get('sf_ez_lib_dir').'/' : '';
|
||||
|
||||
if (file_exists($sf_ez_lib_dir.'Base/src/base.php'))
|
||||
{
|
||||
// svn installation
|
||||
require_once($sf_ez_lib_dir.'Base/src/base.php');
|
||||
}
|
||||
elseif (file_exists($sf_ez_lib_dir.'Base/base.php'))
|
||||
{
|
||||
// pear installation
|
||||
require_once($sf_ez_lib_dir.'Base/base.php');
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new sfAutoloadException('Invalid eZ component library path.');
|
||||
}
|
||||
|
||||
/**
|
||||
* This class makes easy to use ez components classes within symfony
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfEzComponentsBridge.class.php 5362 2007-10-04 06:40:04Z noel $
|
||||
*/
|
||||
class sfEzComponentsBridge
|
||||
{
|
||||
public static function autoload($class)
|
||||
{
|
||||
return ezcBase::autoload($class);
|
||||
}
|
||||
}
|
92
lib/symfony/addon/bridge/sfZendFrameworkBridge.class.php
Executable file
92
lib/symfony/addon/bridge/sfZendFrameworkBridge.class.php
Executable file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
if (sfConfig::get('sf_zend_lib_dir'))
|
||||
{
|
||||
set_include_path(sfConfig::get('sf_zend_lib_dir').PATH_SEPARATOR.get_include_path());
|
||||
}
|
||||
|
||||
sfZendFrameworkBridge::requireZendLoader();
|
||||
|
||||
/**
|
||||
* This class makes easy to use Zend Framework classes within symfony.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfZendFrameworkBridge.class.php 4752 2007-07-31 08:58:33Z fabien $
|
||||
*/
|
||||
class sfZendFrameworkBridge
|
||||
{
|
||||
public static function autoload($class)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (class_exists('Zend_Version'))
|
||||
{
|
||||
Zend_Loader::loadClass($class);
|
||||
}
|
||||
else
|
||||
{
|
||||
Zend::loadClass($class);
|
||||
}
|
||||
}
|
||||
catch (Zend_Exception $e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect and return the path to current Zend loader class.
|
||||
*
|
||||
* Starting from ZF 0.9.0 autoloading function has been moved
|
||||
* from Zend.php to Zend/Version.php class.
|
||||
* Starting from ZF 1.0.0 Zend.php class no longer exists.
|
||||
*
|
||||
* This function tries to detect whether Zend_Version exists
|
||||
* and returns its path if yes.
|
||||
* If the first step fails, the class will try to find Zend.php library
|
||||
* available in ZF <= 0.9.0 and returns its path if its exists.
|
||||
*
|
||||
* If neither Zend/Version.php nor Zend.php exists,
|
||||
* then this function will raise a sfAutoloadException exception.
|
||||
*
|
||||
* @return string Path to default Zend Loader class
|
||||
* @throws sfAutoloadException
|
||||
*
|
||||
* @author Simone Carletti <weppos@weppos.net>
|
||||
*/
|
||||
public static function requireZendLoader()
|
||||
{
|
||||
// get base path according to sf setting
|
||||
$base = sfConfig::get('sf_zend_lib_dir') ? sfConfig::get('sf_zend_lib_dir').'/' : '';
|
||||
|
||||
// first check whether Zend/Version.php exists
|
||||
// Zend/Version.php is available starting from ZF 0.9.0
|
||||
// Before ZF 0.9.0 you should call Zend.php
|
||||
// Plese note that Zend.php is still available in ZF 0.9.0
|
||||
// but it should not be called because deprecated
|
||||
if (file_exists($base.'Zend/Version.php'))
|
||||
{
|
||||
require_once($base.'Zend/Version.php');
|
||||
}
|
||||
else if (file_exists($base.'Zend.php'))
|
||||
{
|
||||
require_once($base.'Zend.php');
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new sfAutoloadException('Invalid Zend Framework library structure, unable to find Zend/Version.php (ZF >= 0.9.0) or Zend.php (ZF < 0.9.0) library');
|
||||
}
|
||||
}
|
||||
}
|
212
lib/symfony/addon/creole/database/sfCreoleDatabase.class.php
Executable file
212
lib/symfony/addon/creole/database/sfCreoleDatabase.class.php
Executable file
@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* (c) 2004-2006 Sean Kerr.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* sfCreoleDatabase provides connectivity for the Creole database abstraction
|
||||
* layer.
|
||||
*
|
||||
* <b>Optional parameters:</b>
|
||||
*
|
||||
* # <b>classpath</b> - [none] - An absolute filesystem path to the main
|
||||
* Creole class file.
|
||||
* # <b>database</b> - [none] - The database name.
|
||||
* # <b>dsn</b> - [none] - The DSN formatted connection string.
|
||||
* # <b>host</b> - [none] - The database host specifications.
|
||||
* # <b>port</b> - [none] - The database port.
|
||||
* # <b>encoding</b> - [none] - The database encoding.
|
||||
* # <b>method</b> - [normal] - How to read connection parameters.
|
||||
* Possible values are dsn, normal,
|
||||
* server, and env. The dsn method reads
|
||||
* them from the dsn parameter. The
|
||||
* normal method reads them from the
|
||||
* specified values. server reads them
|
||||
* from $_SERVER where the keys to
|
||||
* retrieve the values are what you
|
||||
* specify the value as in the settings.
|
||||
* env reads them from $_ENV and works
|
||||
* like $_SERVER.
|
||||
* # <b>no_assoc_lower</b> - [Off] - Turn off portabilty of resultset
|
||||
* field names.
|
||||
* # <b>password</b> - [none] - The database password.
|
||||
* # <b>persistent</b> - [No] - Indicates that the connection should
|
||||
* persistent.
|
||||
* # <b>phptype</b> - [none] - The type of database (mysql, pgsql,
|
||||
* etc).
|
||||
* # <b>username</b> - [none] - The database username.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage database
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @author Sean Kerr <skerr@mojavi.org>
|
||||
* @version SVN: $Id: sfCreoleDatabase.class.php 3329 2007-01-23 08:29:34Z fabien $
|
||||
*/
|
||||
class sfCreoleDatabase extends sfDatabase
|
||||
{
|
||||
/**
|
||||
* Connect to the database.
|
||||
*
|
||||
* @throws <b>sfDatabaseException</b> If a connection could not be created.
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
try
|
||||
{
|
||||
// determine how to get our settings
|
||||
$method = $this->getParameter('method', 'normal');
|
||||
|
||||
switch ($method)
|
||||
{
|
||||
case 'normal':
|
||||
// get parameters normally, and all are required
|
||||
$database = $this->getParameter('database', null);
|
||||
$hostspec = $this->getParameter('hostspec') ? $this->getParameter('hostspec') : ($this->getParameter('host') ? $this->getParameter('hostspec') : null);
|
||||
$password = $this->getParameter('password', null);
|
||||
$phptype = $this->getParameter('phptype', null);
|
||||
$username = $this->getParameter('username', null);
|
||||
$port = $this->getParameter('port', null);
|
||||
$encoding = $this->getParameter('encoding', null);
|
||||
|
||||
$dsn = array('database' => $database,
|
||||
'hostspec' => $hostspec,
|
||||
'password' => $password,
|
||||
'phptype' => $phptype,
|
||||
'username' => $username,
|
||||
'port' => $port,
|
||||
'encoding' => $encoding);
|
||||
break;
|
||||
|
||||
case 'dsn':
|
||||
$dsn = $this->getParameter('dsn');
|
||||
|
||||
if ($dsn == null)
|
||||
{
|
||||
// missing required dsn parameter
|
||||
$error = 'Database configuration specifies method "dsn", but is missing dsn parameter';
|
||||
|
||||
throw new sfDatabaseException($error);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'server':
|
||||
// construct a DSN connection string from existing $_SERVER values
|
||||
$dsn =& $this->loadDSN($_SERVER);
|
||||
|
||||
break;
|
||||
|
||||
case 'env':
|
||||
// construct a DSN connection string from existing $_ENV values
|
||||
$dsn =& $this->loadDSN($_ENV);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// who knows what the user wants...
|
||||
$error = 'Invalid CreoleDatabase parameter retrieval method "%s"';
|
||||
$error = sprintf($error, $method);
|
||||
|
||||
throw new sfDatabaseException($error);
|
||||
}
|
||||
|
||||
// get creole class path
|
||||
$classPath = $this->getParameter('classpath');
|
||||
|
||||
// include the creole file
|
||||
if ($classPath == null)
|
||||
{
|
||||
require_once('creole/Creole.php');
|
||||
}
|
||||
else
|
||||
{
|
||||
require_once($classPath);
|
||||
}
|
||||
|
||||
// set our flags
|
||||
$noAssocLower = $this->getParameter('no_assoc_lower', false);
|
||||
$persistent = $this->getParameter('persistent', false);
|
||||
$compatAssocLower = $this->getParameter('compat_assoc_lower', false);
|
||||
$compatRtrimString = $this->getParameter('compat_rtrim_string', false);
|
||||
|
||||
$flags = 0;
|
||||
$flags |= ($noAssocLower) ? Creole::NO_ASSOC_LOWER : 0;
|
||||
$flags |= ($persistent) ? Creole::PERSISTENT : 0;
|
||||
$flags |= ($compatAssocLower) ? Creole::COMPAT_ASSOC_LOWER : 0;
|
||||
$flags |= ($compatRtrimString) ? Creole::COMPAT_RTRIM_STRING : 0;
|
||||
|
||||
// do the duuuurtay work, right thurr
|
||||
if ($flags > 0)
|
||||
{
|
||||
$this->connection = Creole::getConnection($dsn, $flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connection = Creole::getConnection($dsn);
|
||||
}
|
||||
|
||||
// get our resource
|
||||
$this->resource = $this->connection->getResource();
|
||||
}
|
||||
catch (SQLException $e)
|
||||
{
|
||||
// the connection's foobar'd
|
||||
throw new sfDatabaseException($e->toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a DSN connection string from an existing array.
|
||||
*
|
||||
* @return array An associative array of connection parameters.
|
||||
*/
|
||||
protected function & loadDSN(&$array)
|
||||
{
|
||||
// determine if a dsn is set, otherwise use separate parameters
|
||||
$dsn = $this->getParameter('dsn');
|
||||
|
||||
if ($dsn == null)
|
||||
{
|
||||
// list of available parameters
|
||||
$available = array('database', 'hostspec', 'password', 'phptype', 'username', 'port');
|
||||
|
||||
$dsn = array();
|
||||
|
||||
// yes, i know variable variables are ugly, but let's avoid using
|
||||
// an array for array's sake in this single spot in the source
|
||||
foreach ($available as $parameter)
|
||||
{
|
||||
$$parameter = $this->getParameter($parameter);
|
||||
|
||||
$dsn[$parameter] = ($$parameter != null) ? $array[$$parameter] : null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$dsn = $array[$dsn];
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the shutdown procedure.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws <b>sfDatabaseException</b> If an error occurs while shutting down this database.
|
||||
*/
|
||||
public function shutdown()
|
||||
{
|
||||
if ($this->connection !== null)
|
||||
{
|
||||
@$this->connection->close();
|
||||
}
|
||||
}
|
||||
}
|
294
lib/symfony/addon/creole/drivers/sfDebugConnection.php
Executable file
294
lib/symfony/addon/creole/drivers/sfDebugConnection.php
Executable file
@ -0,0 +1,294 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Debug implementation of Connection.
|
||||
*
|
||||
* This is a Connection that implements the decorator pattern, wrapping around
|
||||
* the true Connection object (stored in $childConnection). This Connection
|
||||
* tracks information about queries executed and makes that information available
|
||||
* for debugging purposes. The information tracked is the last query executed
|
||||
* on the connection (getLastExecutedQuery()) and the total number of
|
||||
* queries executed on the connection thus far (getNumQueriesExecuted()).
|
||||
*
|
||||
* To use this debug connection, you need to register it as a new Creole
|
||||
* driver that handles all connection types. To do this, call the following
|
||||
* before calling Creole::getConnection():
|
||||
*
|
||||
* <code>
|
||||
* Creole::registerDriver('*', 'creole.drivers.debug.DebugConnection');
|
||||
* </code>
|
||||
*
|
||||
* The next call to Creole::getConnection() will return an instance of
|
||||
* DebugConnection.
|
||||
*
|
||||
* @author Michael Sims
|
||||
* @package creole.drivers.debug
|
||||
*/
|
||||
class sfDebugConnection implements Connection
|
||||
{
|
||||
/** @var Connection */
|
||||
private $childConnection = null;
|
||||
|
||||
/** @var int */
|
||||
private $numQueriesExecuted = 0;
|
||||
|
||||
/** @var string */
|
||||
private $lastExecutedQuery = '';
|
||||
|
||||
/**
|
||||
* Optional PEAR Log class; if set queries will be logged at PEAR_LOG_INFO level.
|
||||
* @var Log
|
||||
*/
|
||||
private static $logger;
|
||||
|
||||
/**
|
||||
* Sets a Logger class (e.g. PEAR Log) to use for logging.
|
||||
* The logger class must have a log() method. All messages are logged at default log level.
|
||||
* @param object $logger
|
||||
*/
|
||||
public static function setLogger($logger)
|
||||
{
|
||||
self::$logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of queries executed on this connection so far
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNumQueriesExecuted()
|
||||
{
|
||||
return $this->numQueriesExecuted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last query executed on this connection
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLastExecutedQuery()
|
||||
{
|
||||
return $this->lastExecutedQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* connect()
|
||||
*/
|
||||
public function connect($dsninfo, $flags = 0)
|
||||
{
|
||||
if (!($driver = Creole::getDriver($dsninfo['phptype'])))
|
||||
{
|
||||
throw new SQLException("No driver has been registered to handle connection type: $type");
|
||||
}
|
||||
$connectionClass = Creole::import($driver);
|
||||
$this->childConnection = new $connectionClass();
|
||||
$this->log("{sfCreole} connect(): DSN: ". var_export($dsninfo, true) . ", FLAGS: " . var_export($flags, true));
|
||||
return $this->childConnection->connect($dsninfo, $flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
return $this->childConnection->getDatabaseInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
return $this->childConnection->getIdGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::isConnected()
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return $this->childConnection->isConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement($sql)
|
||||
{
|
||||
$this->log("{sfCreole} prepareStatement(): $sql");
|
||||
$obj = $this->childConnection->prepareStatement($sql);
|
||||
$objClass = get_class($obj);
|
||||
return new $objClass($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
$obj = $this->childConnection->createStatement();
|
||||
$objClass = get_class($obj);
|
||||
return new $objClass($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
$this->log("{sfCreole} applyLimit(): $sql, offset: $offset, limit: $limit");
|
||||
return $this->childConnection->applyLimit($sql, $offset, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::close()
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->log("{sfCreole} close(): Closing connection.");
|
||||
return $this->childConnection->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeQuery()
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
$this->lastExecutedQuery = $sql;
|
||||
$this->numQueriesExecuted++;
|
||||
|
||||
$elapsedTime = 0;
|
||||
if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
|
||||
{
|
||||
$sqlTimer = sfTimerManager::getTimer('Database');
|
||||
$timer = new sfTimer();
|
||||
}
|
||||
|
||||
$retval = $this->childConnection->executeQuery($sql, $fetchmode);
|
||||
|
||||
if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
|
||||
{
|
||||
$sqlTimer->addTime();
|
||||
$elapsedTime = $timer->getElapsedTime();
|
||||
}
|
||||
|
||||
$this->log(sprintf("{sfCreole} executeQuery(): [%.2f ms] %s", $elapsedTime * 1000, $sql));
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeUpdate()
|
||||
**/
|
||||
public function executeUpdate($sql)
|
||||
{
|
||||
$this->log("{sfCreole} executeUpdate(): $sql");
|
||||
$this->lastExecutedQuery = $sql;
|
||||
$this->numQueriesExecuted++;
|
||||
return $this->childConnection->executeUpdate($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getUpdateCount()
|
||||
*/
|
||||
public function getUpdateCount()
|
||||
{
|
||||
return $this->childConnection->getUpdateCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareCall()
|
||||
**/
|
||||
public function prepareCall($sql)
|
||||
{
|
||||
$this->log("{sfCreole} prepareCall(): $sql");
|
||||
return $this->childConnection->prepareCall($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getResource()
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->childConnection->getResource();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::connect()
|
||||
*/
|
||||
public function getDSN()
|
||||
{
|
||||
return $this->childConnection->getDSN();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getFlags()
|
||||
*/
|
||||
public function getFlags()
|
||||
{
|
||||
return $this->childConnection->getFlags();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::begin()
|
||||
*/
|
||||
public function begin()
|
||||
{
|
||||
$this->log("{sfCreole} beginning transaction.");
|
||||
return $this->childConnection->begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::commit()
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$this->log("{sfCreole} committing transaction.");
|
||||
return $this->childConnection->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::rollback()
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
$this->log("{sfCreole} rolling back transaction.");
|
||||
return $this->childConnection->rollback();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::setAutoCommit()
|
||||
*/
|
||||
public function setAutoCommit($bit)
|
||||
{
|
||||
$this->log("{sfCreole} setting autocommit to: ".var_export($bit, true));
|
||||
return $this->childConnection->setAutoCommit($bit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getAutoCommit()
|
||||
*/
|
||||
public function getAutoCommit()
|
||||
{
|
||||
return $this->childConnection->getAutoCommit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Private function that logs message using specified logger (if provided).
|
||||
* @param string $msg Message to log.
|
||||
*/
|
||||
private function log($msg)
|
||||
{
|
||||
if (self::$logger)
|
||||
{
|
||||
// message on one line
|
||||
$msg = preg_replace("/\r?\n/", ' ', $msg);
|
||||
self::$logger->log($msg);
|
||||
}
|
||||
}
|
||||
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
return $this->childConnection->$method($arguments);
|
||||
}
|
||||
}
|
445
lib/symfony/addon/creole/i18n/sfMessageSource_Creole.class.php
Executable file
445
lib/symfony/addon/creole/i18n/sfMessageSource_Creole.class.php
Executable file
@ -0,0 +1,445 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* sfMessageSource_Creole class file.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the BSD License.
|
||||
*
|
||||
* Copyright(c) 2004 by Qiang Xue. All rights reserved.
|
||||
*
|
||||
* To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue}
|
||||
* The latest version of PRADO can be obtained from:
|
||||
* {@link http://prado.sourceforge.net/}
|
||||
*
|
||||
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
|
||||
* @version $Id: sfMessageSource_Creole.class.php 3245 2007-01-12 15:01:53Z fabien $
|
||||
* @package symfony
|
||||
* @subpackage i18n
|
||||
*/
|
||||
|
||||
/*
|
||||
CREATE TABLE `catalogue` (
|
||||
`cat_id` int(11) NOT NULL auto_increment,
|
||||
`name` varchar(100) NOT NULL default '',
|
||||
`source_lang` varchar(100) NOT NULL default '',
|
||||
`target_lang` varchar(100) NOT NULL default '',
|
||||
`date_created` int(11) NOT NULL default '0',
|
||||
`date_modified` int(11) NOT NULL default '0',
|
||||
`author` varchar(255) NOT NULL default '',
|
||||
PRIMARY KEY (`cat_id`)
|
||||
);
|
||||
|
||||
CREATE TABLE `trans_unit` (
|
||||
`msg_id` int(11) NOT NULL auto_increment,
|
||||
`cat_id` int(11) NOT NULL default '1',
|
||||
`source` text NOT NULL,
|
||||
`target` text NOT NULL,
|
||||
`comments` text NOT NULL,
|
||||
`date_added` int(11) NOT NULL default '0',
|
||||
`date_modified` int(11) NOT NULL default '0',
|
||||
`author` varchar(255) NOT NULL default '',
|
||||
`translated` tinyint(1) NOT NULL default '0',
|
||||
PRIMARY KEY (`msg_id`)
|
||||
);
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* sfMessageSource_Creole class.
|
||||
*
|
||||
* Retrieve the message translation from a Creole supported database.
|
||||
*
|
||||
* See the MessageSource::factory() method to instantiate this class.
|
||||
*
|
||||
* @author RoVeRT <symfony[at]rovert[dot]net>
|
||||
*/
|
||||
class sfMessageSource_Creole extends sfMessageSource
|
||||
{
|
||||
/**
|
||||
* A resource link to the database
|
||||
* @var db
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a new message source using Creole.
|
||||
* @param string Creole datasource.
|
||||
* @see MessageSource::factory();
|
||||
*/
|
||||
public function __construct($source)
|
||||
{
|
||||
$this->db = sfContext::getInstance()->getDatabaseConnection($source);
|
||||
if ($this->db == null || !$this->db instanceof Connection)
|
||||
{
|
||||
$error = 'Creole dabatase connection doesn\'t exist. Unable to open session.';
|
||||
throw new sfDatabaseException($error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor, close the database connection.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the database connection.
|
||||
* @return db database connection.
|
||||
*/
|
||||
public function connection()
|
||||
{
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of messages for a particular catalogue and cultural
|
||||
* variant.
|
||||
* @param string the catalogue name + variant
|
||||
* @return array translation messages.
|
||||
*/
|
||||
protected function &loadData($variant)
|
||||
{
|
||||
$sql = 'SELECT t.source, t.target, t.comments '.
|
||||
'FROM trans_unit t, catalogue c '.
|
||||
'WHERE c.cat_id = t.cat_id AND c.name = ? '.
|
||||
'ORDER BY msg_id ASC';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
|
||||
$rs = $stmt->executeQuery(array($variant), ResultSet::FETCHMODE_NUM);
|
||||
|
||||
$result = array();
|
||||
|
||||
$count = 0;
|
||||
while ($rs->next())
|
||||
{
|
||||
$source = $rs->getString(1);
|
||||
$result[$source][] = $rs->getString(2); //target
|
||||
$result[$source][] = $count++; //id
|
||||
$result[$source][] = $rs->getString(3); //comments
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last modified unix-time for this particular catalogue+variant.
|
||||
* We need to query the database to get the date_modified.
|
||||
*
|
||||
* @param string catalogue+variant
|
||||
* @return int last modified in unix-time format.
|
||||
*/
|
||||
protected function getLastModified($source)
|
||||
{
|
||||
$sql = 'SELECT date_modified FROM catalogue WHERE name = ?';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
|
||||
$rs = $stmt->executeQuery(array($source), ResultSet::FETCHMODE_NUM);
|
||||
|
||||
$result = $rs->next() ? $rs->getInt(1) : 0;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a particular catalogue+variant exists in the database.
|
||||
*
|
||||
* @param string catalogue+variant
|
||||
* @return boolean true if the catalogue+variant is in the database, false otherwise.
|
||||
*/
|
||||
protected function isValidSource($variant)
|
||||
{
|
||||
$sql = 'SELECT COUNT(*) FROM catalogue WHERE name = ?';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
|
||||
$rs = $stmt->executeQuery(array($variant), ResultSet::FETCHMODE_NUM);
|
||||
|
||||
$result = $rs->next() ? $rs->getInt(1) == 1 : false;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the variants of a particular catalogue.
|
||||
*
|
||||
* @param string catalogue name
|
||||
* @return array list of all variants for this catalogue.
|
||||
*/
|
||||
protected function getCatalogueList($catalogue)
|
||||
{
|
||||
$variants = explode('_', $this->culture);
|
||||
|
||||
$catalogues = array($catalogue);
|
||||
|
||||
$variant = null;
|
||||
|
||||
for ($i = 0, $max = count($variants); $i < $max; $i++)
|
||||
{
|
||||
if (strlen($variants[$i]) > 0)
|
||||
{
|
||||
$variant .= ($variant) ? '_'.$variants[$i] : $variants[$i];
|
||||
$catalogues[] = $catalogue.'.'.$variant;
|
||||
}
|
||||
}
|
||||
|
||||
return array_reverse($catalogues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve catalogue details, array($cat_id, $variant, $count).
|
||||
*
|
||||
* @param string catalogue
|
||||
* @return array catalogue details, array($cat_id, $variant, $count).
|
||||
*/
|
||||
protected function getCatalogueDetails($catalogue = 'messages')
|
||||
{
|
||||
if (empty($catalogue))
|
||||
{
|
||||
$catalogue = 'messages';
|
||||
}
|
||||
|
||||
$variant = $catalogue.'.'.$this->culture;
|
||||
|
||||
$name = $this->getSource($variant);
|
||||
|
||||
$sql = 'SELECT cat_id FROM catalogue WHERE name = ?';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
|
||||
$rs = $stmt->executeQuery(array($name), ResultSet::FETCHMODE_NUM);
|
||||
|
||||
if ($rs->getRecordCount() != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$rs->next();
|
||||
|
||||
$cat_id = $rs->getInt(1);
|
||||
|
||||
//first get the catalogue ID
|
||||
$sql = 'SELECT count(msg_id) FROM trans_unit WHERE cat_id = ?';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
|
||||
$rs = $stmt->executeQuery(array($cat_id), ResultSet::FETCHMODE_NUM);
|
||||
|
||||
$rs->next();
|
||||
$count = $rs->getInt(1);
|
||||
|
||||
return array($cat_id, $variant, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the catalogue last modified time.
|
||||
*
|
||||
* @return boolean true if updated, false otherwise.
|
||||
*/
|
||||
protected function updateCatalogueTime($cat_id, $variant)
|
||||
{
|
||||
$time = time();
|
||||
|
||||
$sql = 'UPDATE catalogue SET date_modified = ? WHERE cat_id = ?';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
|
||||
$result = $stmt->executeUpdate(array($time, $cat_id));
|
||||
|
||||
if (!empty($this->cache))
|
||||
{
|
||||
$this->cache->clean($variant, $this->culture);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the list of untranslated blocks to the translation source.
|
||||
* If the translation was not found, you should add those
|
||||
* strings to the translation source via the <b>append()</b> method.
|
||||
*
|
||||
* @param string the catalogue to add to
|
||||
* @return boolean true if saved successfuly, false otherwise.
|
||||
*/
|
||||
function save($catalogue='messages')
|
||||
{
|
||||
$messages = $this->untranslated;
|
||||
|
||||
if (count($messages) <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$details = $this->getCatalogueDetails($catalogue);
|
||||
|
||||
if ($details)
|
||||
{
|
||||
list($cat_id, $variant, $count) = $details;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($cat_id <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$inserted = 0;
|
||||
|
||||
$time = time();
|
||||
|
||||
try
|
||||
{
|
||||
$sql = 'SELECT msg_id FROM trans_unit WHERE source = ?';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
|
||||
foreach($messages as $key => $message)
|
||||
{
|
||||
$rs = $stmt->executeQuery(array($message), ResultSet::FETCHMODE_NUM);
|
||||
if ($rs->next())
|
||||
{
|
||||
unset($messages[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->db->begin();
|
||||
|
||||
$sql = 'INSERT INTO trans_unit (cat_id, source, target, comments, date_added, date_modified) VALUES (?, ?, ?, ?, ?, ?)';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
|
||||
foreach ($messages as $message)
|
||||
{
|
||||
$stmt->executeUpdate(array($cat_id, $message, '', '', $time, $time));
|
||||
++$inserted;
|
||||
}
|
||||
|
||||
$this->db->commit();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$this->db->rollback();
|
||||
}
|
||||
|
||||
if ($inserted > 0)
|
||||
{
|
||||
$this->updateCatalogueTime($cat_id, $variant);
|
||||
}
|
||||
|
||||
return $inserted > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a particular message from the specified catalogue.
|
||||
*
|
||||
* @param string the source message to delete.
|
||||
* @param string the catalogue to delete from.
|
||||
* @return boolean true if deleted, false otherwise.
|
||||
*/
|
||||
function delete($message, $catalogue='messages')
|
||||
{
|
||||
$details = $this->getCatalogueDetails($catalogue);
|
||||
|
||||
if ($details)
|
||||
{
|
||||
list($cat_id, $variant, $count) = $details;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$deleted = false;
|
||||
|
||||
$sql = 'DELETE FROM trans_unit WHERE cat_id = ? AND source = ?';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
|
||||
$rows = $stmt->executeUpdate(array($cat_id, $message));
|
||||
|
||||
if ($rows == 1)
|
||||
{
|
||||
$deleted = $this->updateCatalogueTime($cat_id, $variant);
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the translation.
|
||||
*
|
||||
* @param string the source string.
|
||||
* @param string the new translation string.
|
||||
* @param string comments
|
||||
* @param string the catalogue of the translation.
|
||||
* @return boolean true if translation was updated, false otherwise.
|
||||
*/
|
||||
function update($text, $target, $comments, $catalogue='messages')
|
||||
{
|
||||
$details = $this->getCatalogueDetails($catalogue);
|
||||
if ($details)
|
||||
{
|
||||
list($cat_id, $variant, $count) = $details;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$time = time();
|
||||
|
||||
$sql = 'UPDATE trans_unit SET target = ?, comments = ?, date_modified = ? WHERE cat_id = ? AND source = ?';
|
||||
|
||||
$updated = false;
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
|
||||
$rows = $stmt->executeUpdate(array($target, $comments, $time, $cat_id, $text));
|
||||
|
||||
if ($rows == 1)
|
||||
{
|
||||
$updated = $this->updateCatalogueTime($cat_id, $variant);
|
||||
}
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of catalogue as key and all it variants as value.
|
||||
*
|
||||
* @return array list of catalogues
|
||||
*/
|
||||
function catalogues()
|
||||
{
|
||||
$sql = 'SELECT name FROM catalogue ORDER BY name';
|
||||
|
||||
$rs = $this->db->executeQuery($sql, ResultSet::FETCHMODE_NUM);
|
||||
|
||||
$result = array();
|
||||
while ($rs->next())
|
||||
{
|
||||
$details = explode('.', $rs->getString(1));
|
||||
if (!isset($details[1]))
|
||||
{
|
||||
$details[1] = null;
|
||||
}
|
||||
|
||||
$result[] = $details;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
307
lib/symfony/addon/creole/storage/sfCreoleSessionStorage.class.php
Executable file
307
lib/symfony/addon/creole/storage/sfCreoleSessionStorage.class.php
Executable file
@ -0,0 +1,307 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004, 2005 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* (c) 2004, 2005 Sean Kerr.
|
||||
*
|
||||
* The original version the file is based on is licensed under the LGPL, but a special license was granted.
|
||||
* Please see the licenses/LICENSE.Agavi file
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides support for session storage using a CreoleDb database abstraction layer.
|
||||
*
|
||||
* <b>Required parameters:</b>
|
||||
*
|
||||
* # <b>db_table</b> - [none] - The database table in which session data will be
|
||||
* stored.
|
||||
*
|
||||
* <b>Optional parameters:</b>
|
||||
*
|
||||
* # <b>database</b> - [default] - The database connection to use
|
||||
* (see databases.ini).
|
||||
* # <b>db_id_col</b> - [sess_id] - The database column in which the
|
||||
* session id will be stored.
|
||||
* # <b>db_data_col</b> - [sess_data] - The database column in which the
|
||||
* session data will be stored.
|
||||
* # <b>db_time_col</b> - [sess_time] - The database column in which the
|
||||
* session timestamp will be stored.
|
||||
* # <b>session_name</b> - [Agavi] - The name of the session.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage storage
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @author Sean Kerr <skerr@mojavi.org>
|
||||
* @author Veikko Mäkinen <mail@veikkomakinen.com>
|
||||
* @version SVN: $Id: sfCreoleSessionStorage.class.php 2995 2006-12-09 18:01:32Z fabien $
|
||||
*/
|
||||
class sfCreoleSessionStorage extends sfSessionStorage
|
||||
{
|
||||
/**
|
||||
* Creole Database Connection
|
||||
* @var Connection
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* Initialize this Storage.
|
||||
*
|
||||
* @param Context A Context instance.
|
||||
* @param array An associative array of initialization parameters.
|
||||
*
|
||||
* @return bool true, if initialization completes successfully, otherwise
|
||||
* false.
|
||||
*
|
||||
* @throws <b>InitializationException</b> If an error occurs while
|
||||
* initializing this Storage.
|
||||
*/
|
||||
public function initialize($context, $parameters = null)
|
||||
{
|
||||
// disable auto_start
|
||||
$parameters['auto_start'] = false;
|
||||
|
||||
// initialize the parent
|
||||
parent::initialize($context, $parameters);
|
||||
|
||||
if (!$this->getParameterHolder()->has('db_table'))
|
||||
{
|
||||
// missing required 'db_table' parameter
|
||||
$error = 'Factory configuration file is missing required "db_table" parameter for the Storage category';
|
||||
|
||||
throw new sfInitializationException($error);
|
||||
}
|
||||
|
||||
// use this object as the session handler
|
||||
session_set_save_handler(array($this, 'sessionOpen'),
|
||||
array($this, 'sessionClose'),
|
||||
array($this, 'sessionRead'),
|
||||
array($this, 'sessionWrite'),
|
||||
array($this, 'sessionDestroy'),
|
||||
array($this, 'sessionGC'));
|
||||
|
||||
// start our session
|
||||
session_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a session.
|
||||
*
|
||||
* @return bool true, if the session was closed, otherwise false.
|
||||
*/
|
||||
public function sessionClose()
|
||||
{
|
||||
// do nothing
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a session.
|
||||
*
|
||||
* @param string A session ID.
|
||||
*
|
||||
* @return bool true, if the session was destroyed, otherwise an exception
|
||||
* is thrown.
|
||||
*
|
||||
* @throws <b>DatabaseException</b> If the session cannot be destroyed.
|
||||
*/
|
||||
public function sessionDestroy($id)
|
||||
{
|
||||
// get table/column
|
||||
$db_table = $this->getParameterHolder()->get('db_table');
|
||||
$db_id_col = $this->getParameterHolder()->get('db_id_col', 'sess_id');
|
||||
|
||||
// delete the record associated with this id
|
||||
$sql = 'DELETE FROM ' . $db_table . ' WHERE ' . $db_id_col . '=?';
|
||||
|
||||
try
|
||||
{
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
$stmt->setString(1, $id);
|
||||
$stmt->executeUpdate();
|
||||
}
|
||||
catch (SQLException $e) {
|
||||
$error = 'Creole SQLException was thrown when trying to manipulate session data. ';
|
||||
$error .= 'Message: ' . $e->getMessage();
|
||||
throw new sfDatabaseException($error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup old sessions.
|
||||
*
|
||||
* @param int The lifetime of a session.
|
||||
*
|
||||
* @return bool true, if old sessions have been cleaned, otherwise an
|
||||
* exception is thrown.
|
||||
*
|
||||
* @throws <b>DatabaseException</b> If any old sessions cannot be cleaned.
|
||||
*/
|
||||
public function sessionGC($lifetime)
|
||||
{
|
||||
// determine deletable session time
|
||||
$time = time() - $lifetime;
|
||||
|
||||
// get table/column
|
||||
$db_table = $this->getParameterHolder()->get('db_table');
|
||||
$db_time_col = $this->getParameterHolder()->get('db_time_col', 'sess_time');
|
||||
|
||||
// delete the record associated with this id
|
||||
$sql = 'DELETE FROM ' . $db_table . ' ' .
|
||||
'WHERE ' . $db_time_col . ' < ' . $time;
|
||||
|
||||
try
|
||||
{
|
||||
$this->db->executeQuery($sql);
|
||||
return true;
|
||||
}
|
||||
catch (SQLException $e)
|
||||
{
|
||||
$error = 'Creole SQLException was thrown when trying to manipulate session data. ';
|
||||
$error .= 'Message: ' . $e->getMessage();
|
||||
throw new sfDatabaseException($error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a session.
|
||||
*
|
||||
* @param string
|
||||
* @param string
|
||||
*
|
||||
* @return bool true, if the session was opened, otherwise an exception is
|
||||
* thrown.
|
||||
*
|
||||
* @throws <b>DatabaseException</b> If a connection with the database does
|
||||
* not exist or cannot be created.
|
||||
*/
|
||||
public function sessionOpen($path, $name)
|
||||
{
|
||||
// what database are we using?
|
||||
$database = $this->getParameterHolder()->get('database', 'default');
|
||||
|
||||
// autoload propel propely if we're reusing the propel connection for session storage
|
||||
if ($this->getContext()->getDatabaseManager()->getDatabase($database) instanceof sfPropelDatabase && !Propel::isInit())
|
||||
{
|
||||
$error = 'Creole dabatase connection is the same as the propel database connection, but could not be initialized.';
|
||||
throw new sfDatabaseException($error);
|
||||
}
|
||||
|
||||
$this->db = $this->getContext()->getDatabaseConnection($database);
|
||||
if ($this->db == null || !$this->db instanceof Connection)
|
||||
{
|
||||
$error = 'Creole dabatase connection doesn\'t exist. Unable to open session.';
|
||||
throw new sfDatabaseException($error);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a session.
|
||||
*
|
||||
* @param string A session ID.
|
||||
*
|
||||
* @return bool true, if the session was read, otherwise an exception is
|
||||
* thrown.
|
||||
*
|
||||
* @throws <b>DatabaseException</b> If the session cannot be read.
|
||||
*/
|
||||
public function sessionRead($id)
|
||||
{
|
||||
// get table/columns
|
||||
$db_table = $this->getParameterHolder()->get('db_table');
|
||||
$db_data_col = $this->getParameterHolder()->get('db_data_col', 'sess_data');
|
||||
$db_id_col = $this->getParameterHolder()->get('db_id_col', 'sess_id');
|
||||
$db_time_col = $this->getParameterHolder()->get('db_time_col', 'sess_time');
|
||||
|
||||
try
|
||||
{
|
||||
$sql = 'SELECT ' . $db_data_col . ' FROM ' . $db_table . ' WHERE ' . $db_id_col . '=?';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
$stmt->setString(1, $id);
|
||||
|
||||
$dbRes = $stmt->executeQuery(ResultSet::FETCHMODE_NUM);
|
||||
|
||||
if ($dbRes->next())
|
||||
{
|
||||
$data = $dbRes->getString(1);
|
||||
return $data;
|
||||
}
|
||||
else
|
||||
{
|
||||
// session does not exist, create it
|
||||
$sql = 'INSERT INTO ' . $db_table . '('.$db_id_col.','.$db_data_col.','.$db_time_col;
|
||||
$sql .= ') VALUES (?,?,?)';
|
||||
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
$stmt->setString(1, $id);
|
||||
$stmt->setString(2, '');
|
||||
$stmt->setInt(3, time());
|
||||
$stmt->executeUpdate();
|
||||
return '';
|
||||
}
|
||||
}
|
||||
catch (SQLException $e)
|
||||
{
|
||||
$error = 'Creole SQLException was thrown when trying to manipulate session data. ';
|
||||
$error .= 'Message: ' . $e->getMessage();
|
||||
throw new sfDatabaseException($error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write session data.
|
||||
*
|
||||
* @param string A session ID.
|
||||
* @param string A serialized chunk of session data.
|
||||
*
|
||||
* @return bool true, if the session was written, otherwise an exception is
|
||||
* thrown.
|
||||
*
|
||||
* @throws <b>DatabaseException</b> If the session data cannot be written.
|
||||
*/
|
||||
public function sessionWrite($id, $data)
|
||||
{
|
||||
// get table/column
|
||||
$db_table = $this->getParameterHolder()->get('db_table');
|
||||
$db_data_col = $this->getParameterHolder()->get('db_data_col', 'sess_data');
|
||||
$db_id_col = $this->getParameterHolder()->get('db_id_col', 'sess_id');
|
||||
$db_time_col = $this->getParameterHolder()->get('db_time_col', 'sess_time');
|
||||
|
||||
$sql = 'UPDATE ' . $db_table . ' SET ' . $db_data_col . '=?, ' . $db_time_col . ' = ' . time() .
|
||||
' WHERE ' . $db_id_col . '=?';
|
||||
|
||||
try
|
||||
{
|
||||
$stmt = $this->db->prepareStatement($sql);
|
||||
$stmt->setString(1, $data);
|
||||
$stmt->setString(2, $id);
|
||||
$stmt->executeUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
catch (SQLException $e)
|
||||
{
|
||||
$error = 'Creole SQLException was thrown when trying to manipulate session data. ';
|
||||
$error .= 'Message: ' . $e->getMessage();
|
||||
throw new sfDatabaseException($error);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the shutdown procedure.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
61
lib/symfony/addon/propel/builder/SfExtensionObjectBuilder.php
Executable file
61
lib/symfony/addon/propel/builder/SfExtensionObjectBuilder.php
Executable file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
require_once 'propel/engine/builder/om/php5/PHP5ExtensionObjectBuilder.php';
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: SfExtensionObjectBuilder.php 2624 2006-11-07 09:34:59Z fabien $
|
||||
*/
|
||||
class SfExtensionObjectBuilder extends PHP5ExtensionObjectBuilder
|
||||
{
|
||||
protected function addIncludes(&$script)
|
||||
{
|
||||
if (!DataModelBuilder::getBuildProperty('builderAddIncludes'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parent::addIncludes($script);
|
||||
}
|
||||
|
||||
protected function addClassOpen(&$script)
|
||||
{
|
||||
$table = $this->getTable();
|
||||
$tableName = $table->getName();
|
||||
$tableDesc = $table->getDescription();
|
||||
|
||||
$baseClassname = $this->getObjectBuilder()->getClassname();
|
||||
|
||||
$script .= "
|
||||
/**
|
||||
* Subclass for representing a row from the '$tableName' table.
|
||||
*
|
||||
* $tableDesc
|
||||
*
|
||||
* @package ".$this->getPackage()."
|
||||
*/
|
||||
class ".$this->getClassname()." extends $baseClassname
|
||||
{";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes class.
|
||||
* @param string &$script The script will be modified in this method.
|
||||
*/
|
||||
protected function addClassClose(&$script)
|
||||
{
|
||||
$script .= "
|
||||
}
|
||||
";
|
||||
}
|
||||
}
|
65
lib/symfony/addon/propel/builder/SfExtensionPeerBuilder.php
Executable file
65
lib/symfony/addon/propel/builder/SfExtensionPeerBuilder.php
Executable file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
require_once 'propel/engine/builder/om/php5/PHP5ExtensionPeerBuilder.php';
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: SfExtensionPeerBuilder.php 2624 2006-11-07 09:34:59Z fabien $
|
||||
*/
|
||||
class SfExtensionPeerBuilder extends PHP5ExtensionPeerBuilder
|
||||
{
|
||||
protected function addIncludes(&$script)
|
||||
{
|
||||
if (!DataModelBuilder::getBuildProperty('builderAddIncludes'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parent::addIncludes($script);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds class phpdoc comment and openning of class.
|
||||
* @param string &$script The script will be modified in this method.
|
||||
*/
|
||||
protected function addClassOpen(&$script)
|
||||
{
|
||||
$table = $this->getTable();
|
||||
$tableName = $table->getName();
|
||||
$tableDesc = $table->getDescription();
|
||||
|
||||
$baseClassname = $this->getPeerBuilder()->getClassname();
|
||||
|
||||
$script .= "
|
||||
/**
|
||||
* Subclass for performing query and update operations on the '$tableName' table.
|
||||
*
|
||||
* $tableDesc
|
||||
*
|
||||
* @package ".$this->getPackage()."
|
||||
*/
|
||||
class ".$this->getClassname()." extends $baseClassname
|
||||
{";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes class.
|
||||
* @param string &$script The script will be modified in this method.
|
||||
*/
|
||||
protected function addClassClose(&$script)
|
||||
{
|
||||
$script .= "
|
||||
}
|
||||
";
|
||||
}
|
||||
}
|
53
lib/symfony/addon/propel/builder/SfMapBuilderBuilder.php
Executable file
53
lib/symfony/addon/propel/builder/SfMapBuilderBuilder.php
Executable file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
require_once 'propel/engine/builder/om/php5/PHP5MapBuilderBuilder.php';
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: SfMapBuilderBuilder.php 3058 2006-12-16 17:17:26Z fabien $
|
||||
*/
|
||||
class SfMapBuilderBuilder extends PHP5MapBuilderBuilder
|
||||
{
|
||||
public function build()
|
||||
{
|
||||
if (!DataModelBuilder::getBuildProperty('builderAddComments'))
|
||||
{
|
||||
return sfToolkit::stripComments(parent::build());
|
||||
}
|
||||
|
||||
return parent::build();
|
||||
}
|
||||
|
||||
protected function addIncludes(&$script)
|
||||
{
|
||||
if (!DataModelBuilder::getBuildProperty('builderAddIncludes'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parent::addIncludes($script);
|
||||
}
|
||||
|
||||
protected function addDoBuild(&$script)
|
||||
{
|
||||
parent::addDoBuild($script);
|
||||
|
||||
// fix http://propel.phpdb.org/trac/ticket/235: Column sizes not being inserted into [table]MapBuilder->DoBuild() by PHP5MapBuilderBuilder
|
||||
$sizes = array();
|
||||
foreach ($this->getTable()->getColumns() as $col)
|
||||
{
|
||||
$sizes[$col->getPhpName()] = !$col->getSize() ? 'null' : $col->getSize();
|
||||
}
|
||||
$script = preg_replace("/\\\$tMap\->addColumn\('([^']+)', '([^']+)', '([^']+)', CreoleTypes\:\:VARCHAR, (false|true)\)/e", '"\\\$tMap->addColumn(\'$1\', \'$2\', \'$3\', CreoleTypes::VARCHAR, $4, {$sizes[\'$2\']})"', $script);
|
||||
}
|
||||
}
|
30
lib/symfony/addon/propel/builder/SfMultiExtendObjectBuilder.php
Executable file
30
lib/symfony/addon/propel/builder/SfMultiExtendObjectBuilder.php
Executable file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
require_once 'propel/engine/builder/om/php5/PHP5MultiExtendObjectBuilder.php';
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: SfMultiExtendObjectBuilder.php 1919 2006-09-01 14:41:22Z fabien $
|
||||
*/
|
||||
class SfMultiExtendObjectBuilder extends PHP5MultiExtendObjectBuilder
|
||||
{
|
||||
protected function addIncludes(&$script)
|
||||
{
|
||||
if (!DataModelBuilder::getBuildProperty('builderAddIncludes'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parent::addIncludes($script);
|
||||
}
|
||||
}
|
341
lib/symfony/addon/propel/builder/SfObjectBuilder.php
Executable file
341
lib/symfony/addon/propel/builder/SfObjectBuilder.php
Executable file
@ -0,0 +1,341 @@
|
||||
<?php
|
||||
|
||||
require_once 'propel/engine/builder/om/php5/PHP5ComplexObjectBuilder.php';
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: SfObjectBuilder.php 3493 2007-02-18 09:23:10Z fabien $
|
||||
*/
|
||||
class SfObjectBuilder extends PHP5ComplexObjectBuilder
|
||||
{
|
||||
public function build()
|
||||
{
|
||||
if (!DataModelBuilder::getBuildProperty('builderAddComments'))
|
||||
{
|
||||
return sfToolkit::stripComments(parent::build());
|
||||
}
|
||||
|
||||
return parent::build();
|
||||
}
|
||||
|
||||
protected function addIncludes(&$script)
|
||||
{
|
||||
if (!DataModelBuilder::getBuildProperty('builderAddIncludes'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parent::addIncludes($script);
|
||||
|
||||
// include the i18n classes if needed
|
||||
if ($this->getTable()->getAttribute('isI18N'))
|
||||
{
|
||||
$relatedTable = $this->getDatabase()->getTable($this->getTable()->getAttribute('i18nTable'));
|
||||
|
||||
$script .= '
|
||||
require_once \''.$this->getFilePath($this->getStubObjectBuilder()->getPackage().'.'.$relatedTable->getPhpName().'Peer').'\';
|
||||
require_once \''.$this->getFilePath($this->getStubObjectBuilder()->getPackage().'.'.$relatedTable->getPhpName()).'\';
|
||||
';
|
||||
}
|
||||
}
|
||||
|
||||
protected function addClassBody(&$script)
|
||||
{
|
||||
parent::addClassBody($script);
|
||||
|
||||
if ($this->getTable()->getAttribute('isI18N'))
|
||||
{
|
||||
if (count($this->getTable()->getPrimaryKey()) > 1)
|
||||
{
|
||||
throw new Exception('i18n support only works with a single primary key');
|
||||
}
|
||||
|
||||
$this->addCultureAccessorMethod($script);
|
||||
$this->addCultureMutatorMethod($script);
|
||||
|
||||
$this->addI18nMethods($script);
|
||||
}
|
||||
|
||||
if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
|
||||
{
|
||||
$this->addCall($script);
|
||||
}
|
||||
}
|
||||
|
||||
protected function addCall(&$script)
|
||||
{
|
||||
$script .= "
|
||||
|
||||
public function __call(\$method, \$arguments)
|
||||
{
|
||||
if (!\$callable = sfMixer::getCallable('{$this->getClassname()}:'.\$method))
|
||||
{
|
||||
throw new sfException(sprintf('Call to undefined method {$this->getClassname()}::%s', \$method));
|
||||
}
|
||||
|
||||
array_unshift(\$arguments, \$this);
|
||||
|
||||
return call_user_func_array(\$callable, \$arguments);
|
||||
}
|
||||
|
||||
";
|
||||
}
|
||||
|
||||
protected function addAttributes(&$script)
|
||||
{
|
||||
parent::addAttributes($script);
|
||||
|
||||
if ($this->getTable()->getAttribute('isI18N'))
|
||||
{
|
||||
$script .= '
|
||||
/**
|
||||
* The value for the culture field.
|
||||
* @var string
|
||||
*/
|
||||
protected $culture;
|
||||
';
|
||||
}
|
||||
}
|
||||
|
||||
protected function addCultureAccessorMethod(&$script)
|
||||
{
|
||||
$script .= '
|
||||
public function getCulture()
|
||||
{
|
||||
return $this->culture;
|
||||
}
|
||||
';
|
||||
}
|
||||
|
||||
protected function addCultureMutatorMethod(&$script)
|
||||
{
|
||||
$script .= '
|
||||
public function setCulture($culture)
|
||||
{
|
||||
$this->culture = $culture;
|
||||
}
|
||||
';
|
||||
}
|
||||
|
||||
protected function addI18nMethods(&$script)
|
||||
{
|
||||
$table = $this->getTable();
|
||||
$pks = $table->getPrimaryKey();
|
||||
$pk = $pks[0]->getPhpName();
|
||||
|
||||
foreach ($table->getReferrers() as $fk)
|
||||
{
|
||||
$tblFK = $fk->getTable();
|
||||
if ($tblFK->getName() == $table->getAttribute('i18nTable'))
|
||||
{
|
||||
$className = $tblFK->getPhpName();
|
||||
$culture = '';
|
||||
$culture_peername = '';
|
||||
foreach ($tblFK->getColumns() as $col)
|
||||
{
|
||||
if (("true" === strtolower($col->getAttribute('isCulture'))))
|
||||
{
|
||||
$culture = $col->getPhpName();
|
||||
$culture_peername = PeerBuilder::getColumnName($col, $className);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($tblFK->getColumns() as $col)
|
||||
{
|
||||
if ($col->isPrimaryKey()) continue;
|
||||
|
||||
$script .= '
|
||||
public function get'.$col->getPhpName().'()
|
||||
{
|
||||
$obj = $this->getCurrent'.$className.'();
|
||||
|
||||
return ($obj ? $obj->get'.$col->getPhpName().'() : null);
|
||||
}
|
||||
|
||||
public function set'.$col->getPhpName().'($value)
|
||||
{
|
||||
$this->getCurrent'.$className.'()->set'.$col->getPhpName().'($value);
|
||||
}
|
||||
';
|
||||
}
|
||||
|
||||
$script .= '
|
||||
protected $current_i18n = array();
|
||||
|
||||
public function getCurrent'.$className.'()
|
||||
{
|
||||
if (!isset($this->current_i18n[$this->culture]))
|
||||
{
|
||||
$obj = '.$className.'Peer::retrieveByPK($this->get'.$pk.'(), $this->culture);
|
||||
if ($obj)
|
||||
{
|
||||
$this->set'.$className.'ForCulture($obj, $this->culture);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->set'.$className.'ForCulture(new '.$className.'(), $this->culture);
|
||||
$this->current_i18n[$this->culture]->set'.$culture.'($this->culture);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->current_i18n[$this->culture];
|
||||
}
|
||||
|
||||
public function set'.$className.'ForCulture($object, $culture)
|
||||
{
|
||||
$this->current_i18n[$culture] = $object;
|
||||
$this->add'.$className.'($object);
|
||||
}
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function addDoSave(&$script)
|
||||
{
|
||||
$tmp = '';
|
||||
parent::addDoSave($tmp);
|
||||
// add autosave to i18n object even if the base object is not changed
|
||||
$tmp = preg_replace_callback('#(\$this\->(.+?)\->isModified\(\))#', array($this, 'i18nDoSaveCallback'), $tmp);
|
||||
|
||||
$script .= $tmp;
|
||||
}
|
||||
|
||||
private function i18nDoSaveCallback($matches)
|
||||
{
|
||||
$value = $matches[1];
|
||||
|
||||
// get the related class to see if it is a i18n one
|
||||
$table = $this->getTable();
|
||||
$column = null;
|
||||
foreach ($table->getForeignKeys() as $fk)
|
||||
{
|
||||
if ($matches[2] == $this->getFKVarName($fk))
|
||||
{
|
||||
$column = $fk;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$foreign_table = $this->getDatabase()->getTable($fk->getForeignTableName());
|
||||
if ($foreign_table->getAttribute('isI18N'))
|
||||
{
|
||||
$foreign_tables_i18n_table = $this->getDatabase()->getTable($foreign_table->getAttribute('i18nTable'));
|
||||
$value .= ' || $this->'.$matches[2].'->getCurrent'.$foreign_tables_i18n_table->getPhpName().'()->isModified()';
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected function addDelete(&$script)
|
||||
{
|
||||
$tmp = '';
|
||||
parent::addDelete($tmp);
|
||||
|
||||
if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
|
||||
{
|
||||
// add sfMixer call
|
||||
$pre_mixer_script = "
|
||||
|
||||
foreach (sfMixer::getCallables('{$this->getClassname()}:delete:pre') as \$callable)
|
||||
{
|
||||
\$ret = call_user_func(\$callable, \$this, \$con);
|
||||
if (\$ret)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
";
|
||||
$post_mixer_script = "
|
||||
|
||||
foreach (sfMixer::getCallables('{$this->getClassname()}:delete:post') as \$callable)
|
||||
{
|
||||
call_user_func(\$callable, \$this, \$con);
|
||||
}
|
||||
|
||||
";
|
||||
$tmp = preg_replace('/{/', '{'.$pre_mixer_script, $tmp, 1);
|
||||
$tmp = preg_replace('/}\s*$/', $post_mixer_script.' }', $tmp);
|
||||
}
|
||||
|
||||
// update current script
|
||||
$script .= $tmp;
|
||||
}
|
||||
|
||||
protected function addSave(&$script)
|
||||
{
|
||||
$tmp = '';
|
||||
parent::addSave($tmp);
|
||||
|
||||
// add support for created_(at|on) and updated_(at|on) columns
|
||||
$date_script = '';
|
||||
$updated = false;
|
||||
$created = false;
|
||||
foreach ($this->getTable()->getColumns() as $col)
|
||||
{
|
||||
$clo = strtolower($col->getName());
|
||||
|
||||
if (!$updated && in_array($clo, array('updated_at', 'updated_on')))
|
||||
{
|
||||
$updated = true;
|
||||
$date_script .= "
|
||||
if (\$this->isModified() && !\$this->isColumnModified(".$this->getColumnConstant($col)."))
|
||||
{
|
||||
\$this->set".$col->getPhpName()."(time());
|
||||
}
|
||||
";
|
||||
}
|
||||
else if (!$created && in_array($clo, array('created_at', 'created_on')))
|
||||
{
|
||||
$created = true;
|
||||
$date_script .= "
|
||||
if (\$this->isNew() && !\$this->isColumnModified(".$this->getColumnConstant($col)."))
|
||||
{
|
||||
\$this->set".$col->getPhpName()."(time());
|
||||
}
|
||||
";
|
||||
}
|
||||
}
|
||||
$tmp = preg_replace('/{/', '{'.$date_script, $tmp, 1);
|
||||
|
||||
if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
|
||||
{
|
||||
// add sfMixer call
|
||||
$pre_mixer_script = "
|
||||
|
||||
foreach (sfMixer::getCallables('{$this->getClassname()}:save:pre') as \$callable)
|
||||
{
|
||||
\$affectedRows = call_user_func(\$callable, \$this, \$con);
|
||||
if (is_int(\$affectedRows))
|
||||
{
|
||||
return \$affectedRows;
|
||||
}
|
||||
}
|
||||
|
||||
";
|
||||
$post_mixer_script = <<<EOF
|
||||
|
||||
foreach (sfMixer::getCallables('{$this->getClassname()}:save:post') as \$callable)
|
||||
{
|
||||
call_user_func(\$callable, \$this, \$con, \$affectedRows);
|
||||
}
|
||||
|
||||
EOF;
|
||||
$tmp = preg_replace('/{/', '{'.$pre_mixer_script, $tmp, 1);
|
||||
$tmp = preg_replace('/(\$con\->commit\(\);)/', '$1'.$post_mixer_script, $tmp);
|
||||
}
|
||||
|
||||
// update current script
|
||||
$script .= $tmp;
|
||||
}
|
||||
}
|
274
lib/symfony/addon/propel/builder/SfPeerBuilder.php
Executable file
274
lib/symfony/addon/propel/builder/SfPeerBuilder.php
Executable file
@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
require_once 'propel/engine/builder/om/php5/PHP5ComplexPeerBuilder.php';
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: SfPeerBuilder.php 2534 2006-10-26 17:13:50Z fabien $
|
||||
*/
|
||||
class SfPeerBuilder extends PHP5ComplexPeerBuilder
|
||||
{
|
||||
public function build()
|
||||
{
|
||||
if (!DataModelBuilder::getBuildProperty('builderAddComments'))
|
||||
{
|
||||
return sfToolkit::stripComments(parent::build());
|
||||
}
|
||||
|
||||
return parent::build();
|
||||
}
|
||||
|
||||
protected function addIncludes(&$script)
|
||||
{
|
||||
if (!DataModelBuilder::getBuildProperty('builderAddIncludes'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parent::addIncludes($script);
|
||||
}
|
||||
|
||||
protected function addSelectMethods(&$script)
|
||||
{
|
||||
parent::addSelectMethods($script);
|
||||
|
||||
if ($this->getTable()->getAttribute('isI18N'))
|
||||
{
|
||||
$this->addDoSelectWithI18n($script);
|
||||
}
|
||||
}
|
||||
|
||||
protected function addDoSelectWithI18n(&$script)
|
||||
{
|
||||
$table = $this->getTable();
|
||||
$thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table);
|
||||
$className = $table->getPhpName();
|
||||
$pks = $table->getPrimaryKey();
|
||||
$pk = PeerBuilder::getColumnName($pks[0], $className);
|
||||
|
||||
// get i18n table name and culture column name
|
||||
foreach ($table->getReferrers() as $fk)
|
||||
{
|
||||
$tblFK = $fk->getTable();
|
||||
if ($tblFK->getName() == $table->getAttribute('i18nTable'))
|
||||
{
|
||||
$i18nClassName = $tblFK->getPhpName();
|
||||
// FIXME
|
||||
$i18nPeerClassName = $i18nClassName.'Peer';
|
||||
|
||||
$i18nTable = $table->getDatabase()->getTable($tblFK->getName());
|
||||
$i18nTableObjectBuilder = OMBuilder::getNewObjectBuilder($i18nTable);
|
||||
$i18nTablePeerBuilder = OMBuilder::getNewPeerBuilder($i18nTable);
|
||||
$i18nPks = $i18nTable->getPrimaryKey();
|
||||
$i18nPk = PeerBuilder::getColumnName($i18nPks[0], $i18nClassName);
|
||||
|
||||
$culturePhpName = '';
|
||||
$cultureColumnName = '';
|
||||
foreach ($tblFK->getColumns() as $col)
|
||||
{
|
||||
if (("true" === strtolower($col->getAttribute('isCulture'))))
|
||||
{
|
||||
$culturePhpName = $col->getPhpName();
|
||||
$cultureColumnName = PeerBuilder::getColumnName($col, $i18nClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$script .= "
|
||||
|
||||
/**
|
||||
* Selects a collection of $className objects pre-filled with their i18n objects.
|
||||
*
|
||||
* @return array Array of $className objects.
|
||||
* @throws PropelException Any exceptions caught during processing will be
|
||||
* rethrown wrapped into a PropelException.
|
||||
*/
|
||||
public static function doSelectWithI18n(Criteria \$c, \$culture = null, \$con = null)
|
||||
{
|
||||
if (\$culture === null)
|
||||
{
|
||||
\$culture = sfContext::getInstance()->getUser()->getCulture();
|
||||
}
|
||||
|
||||
// Set the correct dbName if it has not been overridden
|
||||
if (\$c->getDbName() == Propel::getDefaultDB())
|
||||
{
|
||||
\$c->setDbName(self::DATABASE_NAME);
|
||||
}
|
||||
|
||||
".$this->getPeerClassname()."::addSelectColumns(\$c);
|
||||
\$startcol = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS) + 1;
|
||||
|
||||
".$i18nPeerClassName."::addSelectColumns(\$c);
|
||||
|
||||
\$c->addJoin(".$pk.", ".$i18nPk.");
|
||||
\$c->add(".$cultureColumnName.", \$culture);
|
||||
|
||||
\$rs = ".$this->basePeerClassname."::doSelect(\$c, \$con);
|
||||
\$results = array();
|
||||
|
||||
while(\$rs->next()) {
|
||||
";
|
||||
if ($table->getChildrenColumn()) {
|
||||
$script .= "
|
||||
\$omClass = ".$this->getPeerClassname()."::getOMClass(\$rs, 1);
|
||||
";
|
||||
} else {
|
||||
$script .= "
|
||||
\$omClass = ".$this->getPeerClassname()."::getOMClass();
|
||||
";
|
||||
}
|
||||
$script .= "
|
||||
\$cls = Propel::import(\$omClass);
|
||||
\$obj1 = new \$cls();
|
||||
\$obj1->hydrate(\$rs);
|
||||
\$obj1->setCulture(\$culture);
|
||||
";
|
||||
// if ($i18nTable->getChildrenColumn()) {
|
||||
$script .= "
|
||||
\$omClass = ".$i18nTablePeerBuilder->getPeerClassname()."::getOMClass(\$rs, \$startcol);
|
||||
";
|
||||
// } else {
|
||||
// $script .= "
|
||||
// \$omClass = ".$i18nTablePeerBuilder->getPeerClassname()."::getOMClass();
|
||||
//";
|
||||
// }
|
||||
|
||||
$script .= "
|
||||
\$cls = Propel::import(\$omClass);
|
||||
\$obj2 = new \$cls();
|
||||
\$obj2->hydrate(\$rs, \$startcol);
|
||||
|
||||
\$obj1->set".$i18nClassName."ForCulture(\$obj2, \$culture);
|
||||
\$obj2->set".$className."(\$obj1);
|
||||
|
||||
\$results[] = \$obj1;
|
||||
}
|
||||
return \$results;
|
||||
}
|
||||
";
|
||||
}
|
||||
|
||||
protected function addDoValidate(&$script)
|
||||
{
|
||||
$tmp = '';
|
||||
parent::addDoValidate($tmp);
|
||||
|
||||
$script .= str_replace("return {$this->basePeerClassname}::doValidate(".$this->getPeerClassname()."::DATABASE_NAME, ".$this->getPeerClassname()."::TABLE_NAME, \$columns);\n",
|
||||
"\$res = {$this->basePeerClassname}::doValidate(".$this->getPeerClassname()."::DATABASE_NAME, ".$this->getPeerClassname()."::TABLE_NAME, \$columns);\n".
|
||||
" if (\$res !== true) {\n".
|
||||
" \$request = sfContext::getInstance()->getRequest();\n".
|
||||
" foreach (\$res as \$failed) {\n".
|
||||
" \$col = ".$this->getPeerClassname()."::translateFieldname(\$failed->getColumn(), BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);\n".
|
||||
" \$request->setError(\$col, \$failed->getMessage());\n".
|
||||
" }\n".
|
||||
" }\n\n".
|
||||
" return \$res;\n", $tmp);
|
||||
}
|
||||
|
||||
protected function addDoSelectRS(&$script)
|
||||
{
|
||||
$tmp = '';
|
||||
parent::addDoSelectRS($tmp);
|
||||
|
||||
if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
|
||||
{
|
||||
$mixer_script = "
|
||||
|
||||
foreach (sfMixer::getCallables('{$this->getClassname()}:addDoSelectRS:addDoSelectRS') as \$callable)
|
||||
{
|
||||
call_user_func(\$callable, '{$this->getClassname()}', \$criteria, \$con);
|
||||
}
|
||||
|
||||
";
|
||||
$tmp = preg_replace('/{/', '{'.$mixer_script, $tmp, 1);
|
||||
}
|
||||
|
||||
$script .= $tmp;
|
||||
}
|
||||
|
||||
protected function addDoUpdate(&$script)
|
||||
{
|
||||
$tmp = '';
|
||||
parent::addDoUpdate($tmp);
|
||||
|
||||
if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
|
||||
{
|
||||
// add sfMixer call
|
||||
$pre_mixer_script = "
|
||||
|
||||
foreach (sfMixer::getCallables('{$this->getClassname()}:doUpdate:pre') as \$callable)
|
||||
{
|
||||
\$ret = call_user_func(\$callable, '{$this->getClassname()}', \$values, \$con);
|
||||
if (false !== \$ret)
|
||||
{
|
||||
return \$ret;
|
||||
}
|
||||
}
|
||||
|
||||
";
|
||||
|
||||
$post_mixer_script = "
|
||||
|
||||
foreach (sfMixer::getCallables('{$this->getClassname()}:doUpdate:post') as \$callable)
|
||||
{
|
||||
call_user_func(\$callable, '{$this->getClassname()}', \$values, \$con, \$ret);
|
||||
}
|
||||
|
||||
return \$ret;
|
||||
";
|
||||
|
||||
$tmp = preg_replace('/{/', '{'.$pre_mixer_script, $tmp, 1);
|
||||
$tmp = preg_replace("/\t\treturn ([^}]+)/", "\t\t\$ret = $1".$post_mixer_script.' ', $tmp, 1);
|
||||
}
|
||||
|
||||
$script .= $tmp;
|
||||
}
|
||||
|
||||
protected function addDoInsert(&$script)
|
||||
{
|
||||
$tmp = '';
|
||||
parent::addDoInsert($tmp);
|
||||
|
||||
if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
|
||||
{
|
||||
// add sfMixer call
|
||||
$pre_mixer_script = "
|
||||
|
||||
foreach (sfMixer::getCallables('{$this->getClassname()}:doInsert:pre') as \$callable)
|
||||
{
|
||||
\$ret = call_user_func(\$callable, '{$this->getClassname()}', \$values, \$con);
|
||||
if (false !== \$ret)
|
||||
{
|
||||
return \$ret;
|
||||
}
|
||||
}
|
||||
|
||||
";
|
||||
|
||||
$post_mixer_script = "
|
||||
foreach (sfMixer::getCallables('{$this->getClassname()}:doInsert:post') as \$callable)
|
||||
{
|
||||
call_user_func(\$callable, '{$this->getClassname()}', \$values, \$con, \$pk);
|
||||
}
|
||||
|
||||
return";
|
||||
|
||||
$tmp = preg_replace('/{/', '{'.$pre_mixer_script, $tmp, 1);
|
||||
$tmp = preg_replace("/\t\treturn/", "\t\t".$post_mixer_script, $tmp, 1);
|
||||
}
|
||||
|
||||
$script .= $tmp;
|
||||
}
|
||||
}
|
46
lib/symfony/addon/propel/database/sfPropelDataRetriever.class.php
Executable file
46
lib/symfony/addon/propel/database/sfPropelDataRetriever.class.php
Executable file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* sfGenerator is the abstract base class for all generators.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage database
|
||||
* @author Olivier Verdier <Olivier.Verdier@gmail.com>
|
||||
* @version SVN: $Id $
|
||||
*/
|
||||
class sfPropelDataRetriever
|
||||
{
|
||||
static public function retrieveObjects($class, $peerMethod = null)
|
||||
{
|
||||
if (!$classPath = sfCore::getClassPath($class.'Peer'))
|
||||
{
|
||||
throw new sfException(sprintf('Unable to find path for class "%s".', $class.'Peer'));
|
||||
}
|
||||
|
||||
require_once($classPath);
|
||||
|
||||
if (!$peerMethod)
|
||||
{
|
||||
$peerMethod = 'doSelect';
|
||||
}
|
||||
|
||||
$classPeer = $class.'Peer';
|
||||
|
||||
if (!is_callable(array($classPeer, $peerMethod)))
|
||||
{
|
||||
throw new sfException(sprintf('Peer method "%s" not found for class "%s"', $peerMethod, $classPeer));
|
||||
}
|
||||
|
||||
$objects = call_user_func(array($classPeer, $peerMethod), new Criteria());
|
||||
|
||||
return $objects;
|
||||
}
|
||||
}
|
114
lib/symfony/addon/propel/database/sfPropelDatabase.class.php
Executable file
114
lib/symfony/addon/propel/database/sfPropelDatabase.class.php
Executable file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A symfony database driver for Propel, derived from the native Creole driver.
|
||||
*
|
||||
* <b>Optional parameters:</b>
|
||||
*
|
||||
* # <b>datasource</b> - [symfony] - datasource to use for the connection
|
||||
* # <b>is_default</b> - [false] - use as default if multiple connections
|
||||
* are specified. The parameters
|
||||
* that has been flagged using this param
|
||||
* is be used when Propel is initialized
|
||||
* via sfPropelAutoload.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage database
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPropelDatabase.class.php 3493 2007-02-18 09:23:10Z fabien $
|
||||
*/
|
||||
class sfPropelDatabase extends sfCreoleDatabase
|
||||
{
|
||||
static protected
|
||||
$config = array();
|
||||
|
||||
public function initialize($parameters = null, $name = 'propel')
|
||||
{
|
||||
parent::initialize($parameters);
|
||||
|
||||
if (!$this->hasParameter('datasource'))
|
||||
{
|
||||
$this->setParameter('datasource', $name);
|
||||
}
|
||||
|
||||
$this->addConfig();
|
||||
|
||||
$is_default = $this->getParameter('is_default', false);
|
||||
|
||||
// first defined if none listed as default
|
||||
if ($is_default || count(self::$config['propel']['datasources']) == 1)
|
||||
{
|
||||
$this->setDefaultConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public function setDefaultConfig()
|
||||
{
|
||||
self::$config['propel']['datasources']['default'] = $this->getParameter('datasource');
|
||||
}
|
||||
|
||||
public function addConfig()
|
||||
{
|
||||
if ($this->hasParameter('host'))
|
||||
{
|
||||
$this->setParameter('hostspec', $this->getParameter('host'));
|
||||
}
|
||||
|
||||
if ($dsn = $this->getParameter('dsn'))
|
||||
{
|
||||
require_once('creole/Creole.php');
|
||||
$params = Creole::parseDSN($dsn);
|
||||
|
||||
$options = array('phptype', 'hostspec', 'database', 'username', 'password', 'port', 'protocol', 'encoding', 'persistent');
|
||||
foreach ($options as $option)
|
||||
{
|
||||
if (!$this->getParameter($option) && isset($params[$option]))
|
||||
{
|
||||
$this->setParameter($option, $params[$option]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self::$config['propel']['datasources'][$this->getParameter('datasource')] =
|
||||
array(
|
||||
'adapter' => $this->getParameter('phptype'),
|
||||
'connection' =>
|
||||
array(
|
||||
'phptype' => $this->getParameter('phptype'),
|
||||
'hostspec' => $this->getParameter('hostspec'),
|
||||
'database' => $this->getParameter('database'),
|
||||
'username' => $this->getParameter('username'),
|
||||
'password' => $this->getParameter('password'),
|
||||
'port' => $this->getParameter('port'),
|
||||
'encoding' => $this->getParameter('encoding'),
|
||||
'persistent' => $this->getParameter('persistent'),
|
||||
'protocol' => $this->getParameter('protocol'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public static function getConfiguration()
|
||||
{
|
||||
return self::$config;
|
||||
}
|
||||
|
||||
public function setConnectionParameter($key, $value)
|
||||
{
|
||||
if ($key == 'host')
|
||||
{
|
||||
$key = 'hostspec';
|
||||
}
|
||||
|
||||
self::$config['propel']['datasources'][$this->getParameter('datasource')]['connection'][$key] = $value;
|
||||
$this->setParameter($key, $value);
|
||||
}
|
||||
}
|
72
lib/symfony/addon/propel/generator/sfPropelAdminGenerator.class.php
Executable file
72
lib/symfony/addon/propel/generator/sfPropelAdminGenerator.class.php
Executable file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Propel Admin generator.
|
||||
*
|
||||
* This class generates an admin module with propel.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage generator
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPropelAdminGenerator.class.php 3302 2007-01-18 13:42:46Z fabien $
|
||||
*/
|
||||
|
||||
class sfPropelAdminGenerator extends sfPropelCrudGenerator
|
||||
{
|
||||
/**
|
||||
* Initializes the current sfGenerator instance.
|
||||
*
|
||||
* @param sfGeneratorManager A sfGeneratorManager instance
|
||||
*/
|
||||
public function initialize($generatorManager)
|
||||
{
|
||||
parent::initialize($generatorManager);
|
||||
|
||||
$this->setGeneratorClass('sfPropelAdmin');
|
||||
}
|
||||
|
||||
public function getAllColumns()
|
||||
{
|
||||
$phpNames = array();
|
||||
foreach ($this->getTableMap()->getColumns() as $column)
|
||||
{
|
||||
$phpNames[] = new sfAdminColumn($column->getPhpName(), $column);
|
||||
}
|
||||
|
||||
return $phpNames;
|
||||
}
|
||||
|
||||
public function getAdminColumnForField($field, $flag = null)
|
||||
{
|
||||
$phpName = sfInflector::camelize($field);
|
||||
|
||||
return new sfAdminColumn($phpName, $this->getColumnForPhpName($phpName), $flag);
|
||||
}
|
||||
|
||||
// returns a column phpName or null if none was found
|
||||
public function getColumnForPhpName($phpName)
|
||||
{
|
||||
// search the matching column for this column name
|
||||
|
||||
foreach ($this->getTableMap()->getColumns() as $column)
|
||||
{
|
||||
if ($column->getPhpName() == $phpName)
|
||||
{
|
||||
$found = true;
|
||||
|
||||
return $column;
|
||||
}
|
||||
}
|
||||
|
||||
// not a "real" column, so we will simulate one
|
||||
return null;
|
||||
}
|
||||
}
|
144
lib/symfony/addon/propel/generator/sfPropelCrudGenerator.class.php
Executable file
144
lib/symfony/addon/propel/generator/sfPropelCrudGenerator.class.php
Executable file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Propel CRUD generator.
|
||||
*
|
||||
* This class generates a basic CRUD module with propel.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage generator
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPropelCrudGenerator.class.php 3302 2007-01-18 13:42:46Z fabien $
|
||||
*/
|
||||
|
||||
class sfPropelCrudGenerator extends sfAdminGenerator
|
||||
{
|
||||
/**
|
||||
* Initializes the current sfGenerator instance.
|
||||
*
|
||||
* @param sfGeneratorManager A sfGeneratorManager instance
|
||||
*/
|
||||
public function initialize($generatorManager)
|
||||
{
|
||||
parent::initialize($generatorManager);
|
||||
|
||||
$this->setGeneratorClass('sfPropelCrud');
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads primary keys.
|
||||
*
|
||||
* This method is ORM dependant.
|
||||
*
|
||||
* @throws sfException
|
||||
*/
|
||||
protected function loadPrimaryKeys()
|
||||
{
|
||||
foreach ($this->tableMap->getColumns() as $column)
|
||||
{
|
||||
if ($column->isPrimaryKey())
|
||||
{
|
||||
$this->primaryKey[] = $column;
|
||||
}
|
||||
}
|
||||
|
||||
if (!count($this->primaryKey))
|
||||
{
|
||||
throw new sfException(sprintf('Cannot generate a module for a model without a primary key (%s)', $this->className));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads map builder classes.
|
||||
*
|
||||
* This method is ORM dependant.
|
||||
*
|
||||
* @throws sfException
|
||||
*/
|
||||
protected function loadMapBuilderClasses()
|
||||
{
|
||||
// we must load all map builder classes to be able to deal with foreign keys (cf. editSuccess.php template)
|
||||
$classes = sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs());
|
||||
foreach ($classes as $class)
|
||||
{
|
||||
$class_map_builder = basename($class, '.php');
|
||||
$maps[$class_map_builder] = new $class_map_builder();
|
||||
if (!$maps[$class_map_builder]->isBuilt())
|
||||
{
|
||||
$maps[$class_map_builder]->doBuild();
|
||||
}
|
||||
|
||||
if ($this->className == str_replace('MapBuilder', '', $class_map_builder))
|
||||
{
|
||||
$this->map = $maps[$class_map_builder];
|
||||
}
|
||||
}
|
||||
if (!$this->map)
|
||||
{
|
||||
throw new sfException('The model class "'.$this->className.'" does not exist.');
|
||||
}
|
||||
|
||||
$this->tableMap = $this->map->getDatabaseMap()->getTable(constant($this->className.'Peer::TABLE_NAME'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a PHP call to an object helper.
|
||||
*
|
||||
* @param string The helper name
|
||||
* @param string The column name
|
||||
* @param array An array of parameters
|
||||
* @param array An array of local parameters
|
||||
*
|
||||
* @return string PHP code
|
||||
*/
|
||||
function getPHPObjectHelper($helperName, $column, $params, $localParams = array())
|
||||
{
|
||||
$params = $this->getObjectTagParams($params, $localParams);
|
||||
|
||||
return sprintf('object_%s($%s, \'%s\', %s)', $helperName, $this->getSingularName(), $this->getColumnGetter($column, false), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the getter either non-developped: 'getFoo' or developped: '$class->getFoo()'.
|
||||
*
|
||||
* @param string The column name
|
||||
* @param boolean true if you want developped method names, false otherwise
|
||||
* @param string The prefix value
|
||||
*
|
||||
* @return string PHP code
|
||||
*/
|
||||
function getColumnGetter($column, $developed = false, $prefix = '')
|
||||
{
|
||||
$getter = 'get'.$column->getPhpName();
|
||||
if ($developed)
|
||||
{
|
||||
$getter = sprintf('$%s%s->%s()', $prefix, $this->getSingularName(), $getter);
|
||||
}
|
||||
|
||||
return $getter;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the PHP name of the related class name.
|
||||
*
|
||||
* Used for foreign keys only; this method should be removed when we use sfAdminColumn instead.
|
||||
*
|
||||
* @param string The column name
|
||||
*
|
||||
* @return string The PHP name of the related class name
|
||||
*/
|
||||
function getRelatedClassName($column)
|
||||
{
|
||||
$relatedTable = $this->getMap()->getDatabaseMap()->getTable($column->getRelatedTableName());
|
||||
|
||||
return $relatedTable->getPhpName();
|
||||
}
|
||||
}
|
32
lib/symfony/addon/propel/sfPropelAutoload.php
Executable file
32
lib/symfony/addon/propel/sfPropelAutoload.php
Executable file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPropelAutoload.php 2808 2006-11-25 07:22:49Z fabien $
|
||||
*/
|
||||
require_once 'propel/Propel.php';
|
||||
|
||||
if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
|
||||
{
|
||||
// register debug driver
|
||||
require_once 'creole/Creole.php';
|
||||
Creole::registerDriver('*', 'symfony.addon.creole.drivers.sfDebugConnection');
|
||||
|
||||
// register our logger
|
||||
require_once(sfConfig::get('sf_symfony_lib_dir').'/addon/creole/drivers/sfDebugConnection.php');
|
||||
sfDebugConnection::setLogger(sfLogger::getInstance());
|
||||
}
|
||||
|
||||
// propel initialization
|
||||
Propel::setConfiguration(sfPropelDatabase::getConfiguration());
|
||||
Propel::initialize();
|
89
lib/symfony/addon/propel/sfPropelBehavior.class.php
Executable file
89
lib/symfony/addon/propel/sfPropelBehavior.class.php
Executable file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPropelBehavior.class.php 2453 2006-10-20 05:58:48Z fabien $
|
||||
*/
|
||||
class sfPropelBehavior
|
||||
{
|
||||
static protected $behaviors = array();
|
||||
|
||||
static public function registerMethods($name, $callables)
|
||||
{
|
||||
if (!isset(self::$behaviors[$name]))
|
||||
{
|
||||
self::$behaviors[$name] = array('methods' => array(), 'hooks' => array());
|
||||
}
|
||||
foreach ($callables as $callable)
|
||||
{
|
||||
self::$behaviors[$name]['methods'][] = $callable;
|
||||
}
|
||||
}
|
||||
|
||||
static public function registerHooks($name, $hooks)
|
||||
{
|
||||
if (!isset(self::$behaviors[$name]))
|
||||
{
|
||||
self::$behaviors[$name] = array('methods' => array(), 'hooks' => array());
|
||||
}
|
||||
foreach ($hooks as $hook => $callable)
|
||||
{
|
||||
if (!isset(self::$behaviors[$name]['hooks']))
|
||||
{
|
||||
self::$behaviors[$name]['hooks'][$hook] = array();
|
||||
}
|
||||
|
||||
self::$behaviors[$name]['hooks'][$hook][] = $callable;
|
||||
}
|
||||
}
|
||||
|
||||
static public function add($class, $behaviors)
|
||||
{
|
||||
foreach ($behaviors as $name => $parameters)
|
||||
{
|
||||
if (is_int($name))
|
||||
{
|
||||
// no parameters
|
||||
$name = $parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
// register parameters
|
||||
foreach ($parameters as $key => $value)
|
||||
{
|
||||
sfConfig::set('propel_behavior_'.$name.'_'.$class.'_'.$key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset(self::$behaviors[$name]))
|
||||
{
|
||||
throw new sfConfigurationException(sprintf('Propel behavior "%s" is not registered', $name));
|
||||
}
|
||||
|
||||
// register hooks
|
||||
foreach (self::$behaviors[$name]['hooks'] as $hook => $callables)
|
||||
{
|
||||
foreach ($callables as $callable)
|
||||
{
|
||||
sfMixer::register('Base'.$class.$hook, $callable);
|
||||
}
|
||||
}
|
||||
|
||||
// register new methods
|
||||
foreach (self::$behaviors[$name]['methods'] as $callable)
|
||||
{
|
||||
sfMixer::register('Base'.$class, $callable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
385
lib/symfony/addon/propel/sfPropelData.class.php
Executable file
385
lib/symfony/addon/propel/sfPropelData.class.php
Executable file
@ -0,0 +1,385 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class is the Propel implementation of sfData. It interacts with the data source
|
||||
* and loads data.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPropelData.class.php 5339 2007-10-01 07:35:33Z fabien $
|
||||
*/
|
||||
class sfPropelData extends sfData
|
||||
{
|
||||
protected
|
||||
$maps = array(),
|
||||
$deletedClasses = array(),
|
||||
$con = null;
|
||||
|
||||
// symfony load-data (file|dir)
|
||||
/**
|
||||
* Loads data from a file or directory into a Propel data source
|
||||
*
|
||||
* @param mixed A file or directory path
|
||||
* @param string The Propel connection name, default 'propel'
|
||||
*
|
||||
* @throws Exception If the database throws an error, rollback transaction and rethrows exception
|
||||
*/
|
||||
public function loadData($directory_or_file = null, $connectionName = 'propel')
|
||||
{
|
||||
$fixture_files = $this->getFiles($directory_or_file);
|
||||
|
||||
// wrap all database operations in a single transaction
|
||||
$this->con = Propel::getConnection($connectionName);
|
||||
try
|
||||
{
|
||||
$this->con->begin();
|
||||
|
||||
$this->doDeleteCurrentData($fixture_files);
|
||||
|
||||
$this->doLoadData($fixture_files);
|
||||
|
||||
$this->con->commit();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$this->con->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the abstract loadDataFromArray method and loads the data using the generated data model.
|
||||
*
|
||||
* @param array The data to be loaded into the data source
|
||||
*
|
||||
* @throws Exception If data is unnamed.
|
||||
* @throws sfException If an object defined in the model does not exist in the data
|
||||
* @throws sfException If a column that does not exist is referenced
|
||||
*/
|
||||
public function loadDataFromArray($data)
|
||||
{
|
||||
if ($data === null)
|
||||
{
|
||||
// no data
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($data as $class => $datas)
|
||||
{
|
||||
$class = trim($class);
|
||||
|
||||
$peer_class = $class.'Peer';
|
||||
|
||||
// load map class
|
||||
$this->loadMapBuilder($class);
|
||||
|
||||
$tableMap = $this->maps[$class]->getDatabaseMap()->getTable(constant($peer_class.'::TABLE_NAME'));
|
||||
|
||||
$column_names = call_user_func_array(array($peer_class, 'getFieldNames'), array(BasePeer::TYPE_FIELDNAME));
|
||||
|
||||
// iterate through datas for this class
|
||||
// might have been empty just for force a table to be emptied on import
|
||||
if (!is_array($datas))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($datas as $key => $data)
|
||||
{
|
||||
// create a new entry in the database
|
||||
$obj = new $class();
|
||||
|
||||
if (!is_array($data))
|
||||
{
|
||||
throw new Exception(sprintf('You must give a name for each fixture data entry (class %s)'), $class);
|
||||
}
|
||||
|
||||
foreach ($data as $name => $value)
|
||||
{
|
||||
// foreign key?
|
||||
try
|
||||
{
|
||||
$column = $tableMap->getColumn($name);
|
||||
if ($column->isForeignKey() && !is_null($value))
|
||||
{
|
||||
$relatedTable = $this->maps[$class]->getDatabaseMap()->getTable($column->getRelatedTableName());
|
||||
if (!isset($this->object_references[$relatedTable->getPhpName().'_'.$value]))
|
||||
{
|
||||
$error = 'The object "%s" from class "%s" is not defined in your data file.';
|
||||
$error = sprintf($error, $value, $relatedTable->getPhpName());
|
||||
throw new sfException($error);
|
||||
}
|
||||
$value = $this->object_references[$relatedTable->getPhpName().'_'.$value];
|
||||
}
|
||||
}
|
||||
catch (PropelException $e)
|
||||
{
|
||||
}
|
||||
|
||||
$pos = array_search($name, $column_names);
|
||||
$method = 'set'.sfInflector::camelize($name);
|
||||
if ($pos)
|
||||
{
|
||||
$obj->setByPosition($pos, $value);
|
||||
}
|
||||
else if (is_callable(array($obj, $method)))
|
||||
{
|
||||
$obj->$method($value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$error = 'Column "%s" does not exist for class "%s"';
|
||||
$error = sprintf($error, $name, $class);
|
||||
throw new sfException($error);
|
||||
}
|
||||
}
|
||||
$obj->save($this->con);
|
||||
|
||||
// save the id for future reference
|
||||
if (method_exists($obj, 'getPrimaryKey'))
|
||||
{
|
||||
$this->object_references[$class.'_'.$key] = $obj->getPrimaryKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears existing data from the data source by reading the fixture files
|
||||
* and deleting the existing data for only those classes that are mentioned
|
||||
* in the fixtures.
|
||||
*
|
||||
* @param array The list of YAML files.
|
||||
*
|
||||
* @throws sfException If a class mentioned in a fixture can not be found
|
||||
*/
|
||||
protected function doDeleteCurrentData($fixture_files)
|
||||
{
|
||||
// delete all current datas in database
|
||||
if (!$this->deleteCurrentData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rsort($fixture_files);
|
||||
foreach ($fixture_files as $fixture_file)
|
||||
{
|
||||
$data = sfYaml::load($fixture_file);
|
||||
|
||||
if ($data === null)
|
||||
{
|
||||
// no data
|
||||
continue;
|
||||
}
|
||||
|
||||
$classes = array_keys($data);
|
||||
krsort($classes);
|
||||
foreach ($classes as $class)
|
||||
{
|
||||
$class = trim($class);
|
||||
if (in_array($class, $this->deletedClasses))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$peer_class = $class.'Peer';
|
||||
|
||||
if (!$classPath = sfCore::getClassPath($peer_class))
|
||||
{
|
||||
throw new sfException(sprintf('Unable to find path for class "%s".', $peer_class));
|
||||
}
|
||||
|
||||
require_once($classPath);
|
||||
|
||||
call_user_func(array($peer_class, 'doDeleteAll'), $this->con);
|
||||
|
||||
$this->deletedClasses[] = $class;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the mappings for the classes
|
||||
*
|
||||
* @param string The model class name
|
||||
*
|
||||
* @throws sfException If the class cannot be found
|
||||
*/
|
||||
protected function loadMapBuilder($class)
|
||||
{
|
||||
$mapBuilderClass = $class.'MapBuilder';
|
||||
if (!isset($this->maps[$class]))
|
||||
{
|
||||
if (!$classPath = sfCore::getClassPath($mapBuilderClass))
|
||||
{
|
||||
throw new sfException(sprintf('Unable to find path for class "%s".', $mapBuilderClass));
|
||||
}
|
||||
|
||||
require_once($classPath);
|
||||
$this->maps[$class] = new $mapBuilderClass();
|
||||
$this->maps[$class]->doBuild();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps data to fixture from one or more tables.
|
||||
*
|
||||
* @param string directory or file to dump to
|
||||
* @param mixed name or names of tables to dump (or all to dump all tables)
|
||||
* @param string connection name
|
||||
*/
|
||||
public function dumpData($directory_or_file = null, $tables = 'all', $connectionName = 'propel')
|
||||
{
|
||||
$sameFile = true;
|
||||
if (is_dir($directory_or_file))
|
||||
{
|
||||
// multi files
|
||||
$sameFile = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// same file
|
||||
// delete file
|
||||
}
|
||||
|
||||
$this->con = Propel::getConnection($connectionName);
|
||||
|
||||
// get tables
|
||||
if ('all' === $tables || is_null($tables))
|
||||
{
|
||||
// load all map builder classes
|
||||
$files = sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs());
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$mapBuilderClass = basename($file, '.php');
|
||||
$map = new $mapBuilderClass();
|
||||
$map->doBuild();
|
||||
}
|
||||
|
||||
$dbMap = Propel::getDatabaseMap($connectionName);
|
||||
$tables = array();
|
||||
foreach ($dbMap->getTables() as $table)
|
||||
{
|
||||
$tables[] = $table->getPhpName();
|
||||
}
|
||||
}
|
||||
else if (!is_array($tables))
|
||||
{
|
||||
$tables = array($tables);
|
||||
}
|
||||
|
||||
$dumpData = array();
|
||||
|
||||
// load map classes
|
||||
array_walk($tables, array($this, 'loadMapBuilder'));
|
||||
|
||||
$tables = $this->fixOrderingOfForeignKeyData($tables);
|
||||
|
||||
foreach ($tables as $tableName)
|
||||
{
|
||||
$tableMap = $this->maps[$tableName]->getDatabaseMap()->getTable(constant($tableName.'Peer::TABLE_NAME'));
|
||||
|
||||
// get db info
|
||||
$rs = $this->con->executeQuery('SELECT * FROM '.constant($tableName.'Peer::TABLE_NAME'));
|
||||
|
||||
while ($rs->next())
|
||||
{
|
||||
$pk = $tableName;
|
||||
$values = array();
|
||||
foreach ($tableMap->getColumns() as $column)
|
||||
{
|
||||
$col = strtolower($column->getColumnName());
|
||||
if ($column->isPrimaryKey())
|
||||
{
|
||||
$pk .= '_'.$rs->get($col);
|
||||
}
|
||||
else if ($column->isForeignKey())
|
||||
{
|
||||
$relatedTable = $this->maps[$tableName]->getDatabaseMap()->getTable($column->getRelatedTableName());
|
||||
|
||||
$values[$col] = $relatedTable->getPhpName().'_'.$rs->get($col);
|
||||
}
|
||||
else
|
||||
{
|
||||
$values[$col] = $rs->get($col);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($dumpData[$tableName]))
|
||||
{
|
||||
$dumpData[$tableName] = array();
|
||||
}
|
||||
|
||||
$dumpData[$tableName][$pk] = $values;
|
||||
}
|
||||
}
|
||||
|
||||
// save to file(s)
|
||||
if ($sameFile)
|
||||
{
|
||||
file_put_contents($directory_or_file, Spyc::YAMLDump($dumpData));
|
||||
}
|
||||
else
|
||||
{
|
||||
$i = 0;
|
||||
foreach ($tables as $tableName)
|
||||
{
|
||||
if (!isset($dumpData[$tableName]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
file_put_contents(sprintf("%s/%03d-%s.yml", $directory_or_file, ++$i, $tableName), Spyc::YAMLDump(array($tableName => $dumpData[$tableName])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes the ordering of foreign key data, by outputting data a foreign key depends on before the table with the foreign key.
|
||||
*
|
||||
* @param array The array with the class names.
|
||||
*/
|
||||
public function fixOrderingOfForeignKeyData($classes)
|
||||
{
|
||||
// reordering classes to take foreign keys into account
|
||||
for ($i = 0, $count = count($classes); $i < $count; $i++)
|
||||
{
|
||||
$class = $classes[$i];
|
||||
$tableMap = $this->maps[$class]->getDatabaseMap()->getTable(constant($class.'Peer::TABLE_NAME'));
|
||||
foreach ($tableMap->getColumns() as $column)
|
||||
{
|
||||
if ($column->isForeignKey())
|
||||
{
|
||||
$relatedTable = $this->maps[$class]->getDatabaseMap()->getTable($column->getRelatedTableName());
|
||||
$relatedTablePos = array_search($relatedTable->getPhpName(), $classes);
|
||||
|
||||
// check if relatedTable is after the current table
|
||||
if ($relatedTablePos > $i)
|
||||
{
|
||||
// move related table 1 position before current table
|
||||
$classes = array_merge(
|
||||
array_slice($classes, 0, $i),
|
||||
array($classes[$relatedTablePos]),
|
||||
array_slice($classes, $i, $relatedTablePos - $i),
|
||||
array_slice($classes, $relatedTablePos + 1)
|
||||
);
|
||||
|
||||
// we have moved a table, so let's see if we are done
|
||||
return $this->fixOrderingOfForeignKeyData($classes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
}
|
719
lib/symfony/addon/propel/sfPropelDatabaseSchema.class.php
Executable file
719
lib/symfony/addon/propel/sfPropelDatabaseSchema.class.php
Executable file
@ -0,0 +1,719 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @author François Zaninotto <francois.zaninotto@symfony-project.com>
|
||||
* @version SVN: $Id$
|
||||
*/
|
||||
class sfPropelDatabaseSchema
|
||||
{
|
||||
protected $connection_name = '';
|
||||
protected $database = array();
|
||||
|
||||
public function asArray()
|
||||
{
|
||||
return array($this->connection_name => $this->database);
|
||||
}
|
||||
|
||||
public function loadYAML($file)
|
||||
{
|
||||
$schema = sfYaml::load($file);
|
||||
|
||||
if (count($schema) > 1)
|
||||
{
|
||||
throw new sfException('A schema.yml must only contain 1 database entry.');
|
||||
}
|
||||
|
||||
$tmp = array_keys($schema);
|
||||
$this->connection_name = array_shift($tmp);
|
||||
if ($this->connection_name)
|
||||
{
|
||||
$this->database = $schema[$this->connection_name];
|
||||
|
||||
$this->fixYAMLDatabase();
|
||||
$this->fixYAMLI18n();
|
||||
$this->fixYAMLColumns();
|
||||
}
|
||||
}
|
||||
|
||||
public function asXML()
|
||||
{
|
||||
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||
|
||||
$xml .= "<database name=\"$this->connection_name\"".$this->getAttributesFor($this->database).">\n";
|
||||
|
||||
// tables
|
||||
foreach ($this->getChildren($this->database) as $tb_name => $table)
|
||||
{
|
||||
$xml .= "\n <table name=\"$tb_name\"".$this->getAttributesFor($table).">\n";
|
||||
|
||||
// columns
|
||||
foreach ($this->getChildren($table) as $col_name => $column)
|
||||
{
|
||||
$xml .= " <column name=\"$col_name\"".$this->getAttributesForColumn($tb_name, $col_name, $column);
|
||||
}
|
||||
|
||||
// indexes
|
||||
if (isset($table['_indexes']))
|
||||
{
|
||||
foreach ($table['_indexes'] as $index_name => $index)
|
||||
{
|
||||
$xml .= " <index name=\"$index_name\">\n";
|
||||
foreach ($index as $index_column)
|
||||
{
|
||||
$xml .= " <index-column name=\"$index_column\" />\n";
|
||||
}
|
||||
$xml .= " </index>\n";
|
||||
}
|
||||
}
|
||||
|
||||
// uniques
|
||||
if (isset($table['_uniques']))
|
||||
{
|
||||
foreach ($table['_uniques'] as $unique_name => $index)
|
||||
{
|
||||
$xml .= " <unique name=\"$unique_name\">\n";
|
||||
foreach ($index as $unique_column)
|
||||
{
|
||||
$xml .= " <unique-column name=\"$unique_column\" />\n";
|
||||
}
|
||||
$xml .= " </unique>\n";
|
||||
}
|
||||
}
|
||||
|
||||
// foreign-keys
|
||||
if (isset($table['_foreignKeys']))
|
||||
{
|
||||
foreach ($table['_foreignKeys'] as $fkey_name => $fkey)
|
||||
{
|
||||
$xml .= " <foreign-key foreignTable=\"$fkey[foreignTable]\"";
|
||||
|
||||
// foreign key name
|
||||
if (!is_numeric($fkey_name))
|
||||
{
|
||||
$xml .= " name=\"$fkey_name\"";
|
||||
}
|
||||
|
||||
// onDelete
|
||||
if (isset($fkey['onDelete']))
|
||||
{
|
||||
$xml .= " onDelete=\"$fkey[onDelete]\"";
|
||||
}
|
||||
|
||||
// onUpdate
|
||||
if (isset($fkey['onUpdate']))
|
||||
{
|
||||
$xml .= " onUpdate=\"$fkey[onUpdate]\"";
|
||||
}
|
||||
$xml .= ">\n";
|
||||
|
||||
// references
|
||||
if (isset($fkey['references']))
|
||||
{
|
||||
foreach ($fkey['references'] as $reference)
|
||||
{
|
||||
$xml .= " <reference local=\"$reference[local]\" foreign=\"$reference[foreign]\" />\n";
|
||||
}
|
||||
}
|
||||
$xml .= " </foreign-key>\n";
|
||||
}
|
||||
}
|
||||
|
||||
$xml .= " </table>\n";
|
||||
}
|
||||
$xml .= "\n</database>\n";
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
protected function fixYAMLDatabase()
|
||||
{
|
||||
if (!isset($this->database['_attributes']))
|
||||
{
|
||||
$this->database['_attributes'] = array();
|
||||
}
|
||||
|
||||
// conventions for database attributes
|
||||
$this->setIfNotSet($this->database['_attributes'], 'defaultIdMethod', 'native');
|
||||
$this->setIfNotSet($this->database['_attributes'], 'noXsd', true);
|
||||
$this->setIfNotSet($this->database['_attributes'], 'package', 'lib.model');
|
||||
}
|
||||
|
||||
protected function fixYAMLI18n()
|
||||
{
|
||||
foreach ($this->getTables() as $i18n_table => $columns)
|
||||
{
|
||||
$pos = strpos($i18n_table, '_i18n');
|
||||
|
||||
$has_primary_key = false;
|
||||
foreach ($columns as $column => $attributes)
|
||||
{
|
||||
if (is_array($attributes) && array_key_exists('primaryKey', $attributes))
|
||||
{
|
||||
$has_primary_key = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($pos > 0 && $pos == strlen($i18n_table) - 5 && !$has_primary_key)
|
||||
{
|
||||
// i18n table without primary key
|
||||
$main_table = $this->findTable(substr($i18n_table, 0, $pos));
|
||||
|
||||
if ($main_table)
|
||||
{
|
||||
// set i18n attributes for main table
|
||||
$this->setIfNotSet($this->database[$main_table]['_attributes'], 'isI18N', 1);
|
||||
$this->setIfNotSet($this->database[$main_table]['_attributes'], 'i18nTable', $i18n_table);
|
||||
|
||||
// set id and culture columns for i18n table
|
||||
$this->setIfNotSet($this->database[$i18n_table], 'id', array(
|
||||
'type' => 'integer',
|
||||
'required' => true,
|
||||
'primaryKey' => true,
|
||||
'foreignTable' => $main_table,
|
||||
'foreignReference' => 'id',
|
||||
'onDelete' => 'cascade'
|
||||
));
|
||||
$this->setIfNotSet($this->database[$i18n_table], 'culture', array(
|
||||
'isCulture' => true,
|
||||
'type' => 'varchar',
|
||||
'size' => '7',
|
||||
'required' => true,
|
||||
'primaryKey' => true
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new sfException(sprintf('Missing main table for internationalized table "%s".', $i18n_table));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function fixYAMLColumns()
|
||||
{
|
||||
foreach ($this->getTables() as $table => $columns)
|
||||
{
|
||||
$has_primary_key = false;
|
||||
|
||||
foreach ($columns as $column => $attributes)
|
||||
{
|
||||
if ($attributes == null)
|
||||
{
|
||||
// conventions for null attributes
|
||||
if ($column == 'created_at' || $column == 'updated_at')
|
||||
{
|
||||
// timestamp convention
|
||||
$this->database[$table][$column]['type']= 'timestamp';
|
||||
}
|
||||
|
||||
if ($column == 'id')
|
||||
{
|
||||
// primary key convention
|
||||
$this->database[$table]['id'] = array(
|
||||
'type' => 'integer',
|
||||
'required' => true,
|
||||
'primaryKey' => true,
|
||||
'autoincrement' => true
|
||||
);
|
||||
$has_primary_key = true;
|
||||
}
|
||||
|
||||
$pos = strpos($column, '_id');
|
||||
if ($pos > 0 && $pos == strlen($column) - 3)
|
||||
{
|
||||
// foreign key convention
|
||||
$foreign_table = $this->findTable(substr($column, 0, $pos));
|
||||
if ($foreign_table)
|
||||
{
|
||||
$this->database[$table][$column] = array(
|
||||
'type' => 'integer',
|
||||
'foreignTable' => $foreign_table,
|
||||
'foreignReference' => 'id'
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new sfException(sprintf('Unable to resolve foreign table for column "%s"', $column));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_array($attributes))
|
||||
{
|
||||
// compact type given as single attribute
|
||||
$this->database[$table][$column] = $this->getAttributesFromCompactType($attributes);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($attributes['type']))
|
||||
{
|
||||
// compact type given as value of the type attribute
|
||||
$this->database[$table][$column] = array_merge($this->database[$table][$column], $this->getAttributesFromCompactType($attributes['type']));
|
||||
}
|
||||
if (isset($attributes['primaryKey']))
|
||||
{
|
||||
$has_primary_key = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$has_primary_key)
|
||||
{
|
||||
// convention for tables without primary key
|
||||
$this->database[$table]['id'] = array(
|
||||
'type' => 'integer',
|
||||
'required' => true,
|
||||
'primaryKey' => true,
|
||||
'autoincrement' => true
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getAttributesFromCompactType($type)
|
||||
{
|
||||
preg_match('/varchar\(([\d]+)\)/', $type, $matches);
|
||||
if (isset($matches[1]))
|
||||
{
|
||||
return array('type' => 'varchar', 'size' => $matches[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return array('type' => $type);
|
||||
}
|
||||
}
|
||||
|
||||
protected function setIfNotSet(&$entry, $key, $value)
|
||||
{
|
||||
if (!isset($entry[$key]))
|
||||
{
|
||||
$entry[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
protected function findTable($table_name)
|
||||
{
|
||||
// find a table from a phpName or a name
|
||||
$table_match = false;
|
||||
foreach ($this->getTables() as $tb_name => $table)
|
||||
{
|
||||
if ((isset($table['_attributes']['phpName']) && $table['_attributes']['phpName'] == sfInflector::camelize($table_name)) || ($tb_name == $table_name))
|
||||
{
|
||||
$table_match = $tb_name;
|
||||
}
|
||||
}
|
||||
|
||||
return $table_match;
|
||||
}
|
||||
|
||||
protected function getAttributesForColumn($tb_name, $col_name, $column)
|
||||
{
|
||||
$attributes_string = '';
|
||||
if (is_array($column))
|
||||
{
|
||||
foreach ($column as $key => $value)
|
||||
{
|
||||
if (!in_array($key, array('foreignTable', 'foreignReference', 'onDelete', 'onUpdate', 'index', 'unique')))
|
||||
{
|
||||
$attributes_string .= " $key=\"".htmlspecialchars($this->getCorrectValueFor($key, $value))."\"";
|
||||
}
|
||||
}
|
||||
$attributes_string .= " />\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new sfException('Incorrect settings for column '.$col_name);
|
||||
}
|
||||
|
||||
// conventions for foreign key attributes
|
||||
if (is_array($column) && isset($column['foreignTable']))
|
||||
{
|
||||
$attributes_string .= " <foreign-key foreignTable=\"$column[foreignTable]\"";
|
||||
if (isset($column['onDelete']))
|
||||
{
|
||||
$attributes_string .= " onDelete=\"$column[onDelete]\"";
|
||||
}
|
||||
if (isset($column['onUpdate']))
|
||||
{
|
||||
$attributes_string .= " onUpdate=\"$column[onUpdate]\"";
|
||||
}
|
||||
$attributes_string .= ">\n";
|
||||
$attributes_string .= " <reference local=\"$col_name\" foreign=\"$column[foreignReference]\" />\n";
|
||||
$attributes_string .= " </foreign-key>\n";
|
||||
}
|
||||
|
||||
// conventions for index and unique index attributes
|
||||
if (is_array($column) && isset($column['index']))
|
||||
{
|
||||
if ($column['index'] === 'unique')
|
||||
{
|
||||
$attributes_string .= " <unique name=\"${tb_name}_${col_name}_unique\">\n";
|
||||
$attributes_string .= " <unique-column name=\"$col_name\" />\n";
|
||||
$attributes_string .= " </unique>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$attributes_string .= " <index name=\"${tb_name}_${col_name}_index\">\n";
|
||||
$attributes_string .= " <index-column name=\"$col_name\" />\n";
|
||||
$attributes_string .= " </index>\n";
|
||||
}
|
||||
}
|
||||
|
||||
// conventions for sequence name attributes
|
||||
// required for databases using sequences for auto-increment columns (e.g. PostgreSQL or Oracle)
|
||||
if (is_array($column) && isset($column['sequence']))
|
||||
{
|
||||
$attributes_string .= " <id-method-parameter value=\"$column[sequence]\" />\n";
|
||||
}
|
||||
|
||||
return $attributes_string;
|
||||
}
|
||||
|
||||
protected function getAttributesFor($tag)
|
||||
{
|
||||
if (!isset($tag['_attributes']))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
$attributes = $tag['_attributes'];
|
||||
$attributes_string = '';
|
||||
foreach ($attributes as $key => $value)
|
||||
{
|
||||
$attributes_string .= ' '.$key.'="'.htmlspecialchars($this->getCorrectValueFor($key, $value)).'"';
|
||||
}
|
||||
|
||||
return $attributes_string;
|
||||
}
|
||||
|
||||
protected function getCorrectValueFor($key, $value)
|
||||
{
|
||||
$booleans = array('required', 'primaryKey', 'autoincrement', 'autoIncrement', 'noXsd', 'isI18N', 'isCulture');
|
||||
if (in_array($key, $booleans))
|
||||
{
|
||||
return $value == 1 ? 'true' : 'false';
|
||||
}
|
||||
else
|
||||
{
|
||||
return is_null($value) ? 'null' : $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function getTables()
|
||||
{
|
||||
return $this->getChildren($this->database);
|
||||
}
|
||||
|
||||
public function getChildren($hash)
|
||||
{
|
||||
foreach ($hash as $key => $value)
|
||||
{
|
||||
// ignore special children (starting with _)
|
||||
if ($key[0] == '_')
|
||||
{
|
||||
unset($hash[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
public function loadXML($file)
|
||||
{
|
||||
$schema = simplexml_load_file($file);
|
||||
$database = array();
|
||||
|
||||
// database
|
||||
list($database_name, $database_attributes) = $this->getNameAndAttributes($schema->attributes());
|
||||
if ($database_name)
|
||||
{
|
||||
$this->connection_name = $database_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new sfException('The database tag misses a name attribute');
|
||||
}
|
||||
if ($database_attributes)
|
||||
{
|
||||
$database['_attributes'] = $database_attributes;
|
||||
}
|
||||
|
||||
// tables
|
||||
foreach ($schema as $table)
|
||||
{
|
||||
list($table_name, $table_attributes) = $this->getNameAndAttributes($table->attributes());
|
||||
if ($table_name)
|
||||
{
|
||||
$database[$table_name] = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new sfException('A table tag misses the name attribute');
|
||||
}
|
||||
if ($table_attributes)
|
||||
{
|
||||
$database[$table_name]['_attributes'] = $table_attributes;
|
||||
}
|
||||
|
||||
// columns
|
||||
foreach ($table->xpath('column') as $column)
|
||||
{
|
||||
list($column_name, $column_attributes) = $this->getNameAndAttributes($column->attributes());
|
||||
if ($column_name)
|
||||
{
|
||||
$database[$table_name][$column_name] = $column_attributes;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new sfException('A column tag misses the name attribute');
|
||||
}
|
||||
}
|
||||
|
||||
// foreign-keys
|
||||
$database[$table_name]['_foreign_keys'] = array();
|
||||
foreach ($table->xpath('foreign-key') as $foreign_key)
|
||||
{
|
||||
$foreign_key_table = array();
|
||||
|
||||
// foreign key attributes
|
||||
if (isset($foreign_key['foreignTable']))
|
||||
{
|
||||
$foreign_key_table['foreign_table'] = (string) $foreign_key['foreignTable'];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new sfException('A foreign key misses the foreignTable attribute');
|
||||
}
|
||||
if (isset($foreign_key['onDelete']))
|
||||
{
|
||||
$foreign_key_table['on_delete'] = (string) $foreign_key['onDelete'];
|
||||
}
|
||||
if (isset($foreign_key['onUpdate']))
|
||||
{
|
||||
$foreign_key_table['on_update'] = (string) $foreign_key['onUpdate'];
|
||||
}
|
||||
|
||||
// foreign key references
|
||||
$foreign_key_table['references'] = array();
|
||||
foreach ($foreign_key->xpath('reference') as $reference)
|
||||
{
|
||||
$reference_attributes = array();
|
||||
foreach ($reference->attributes() as $reference_attribute_name => $reference_attribute_value)
|
||||
{
|
||||
$reference_attributes[$reference_attribute_name] = strval($reference_attribute_value);
|
||||
}
|
||||
$foreign_key_table['references'][] = $reference_attributes;
|
||||
}
|
||||
|
||||
if (isset($foreign_key['name']))
|
||||
{
|
||||
$database[$table_name]['_foreign_keys'][(string)$foreign_key['name']] = $foreign_key_table;
|
||||
}
|
||||
else
|
||||
{
|
||||
$database[$table_name]['_foreign_keys'][] = $foreign_key_table;
|
||||
}
|
||||
|
||||
}
|
||||
$this->removeEmptyKey($database[$table_name], '_foreign_keys');
|
||||
|
||||
// indexes
|
||||
$database[$table_name]['_indexes'] = array();
|
||||
foreach ($table->xpath('index') as $index)
|
||||
{
|
||||
$index_keys = array();
|
||||
foreach ($index->xpath('index-column') as $index_key)
|
||||
{
|
||||
$index_keys[] = strval($index_key['name']);
|
||||
}
|
||||
$database[$table_name]['_indexes'][strval($index['name'])] = $index_keys;
|
||||
}
|
||||
$this->removeEmptyKey($database[$table_name], '_indexes');
|
||||
|
||||
// unique indexes
|
||||
$database[$table_name]['_uniques'] = array();
|
||||
foreach ($table->xpath('unique') as $index)
|
||||
{
|
||||
$unique_keys = array();
|
||||
foreach ($index->xpath('unique-column') as $unique_key)
|
||||
{
|
||||
$unique_keys[] = strval($unique_key['name']);
|
||||
}
|
||||
$database[$table_name]['_uniques'][strval($index['name'])] = $unique_keys;
|
||||
}
|
||||
$this->removeEmptyKey($database[$table_name], '_uniques');
|
||||
}
|
||||
$this->database = $database;
|
||||
|
||||
$this->fixXML();
|
||||
}
|
||||
|
||||
public function fixXML()
|
||||
{
|
||||
$this->fixXMLForeignKeys();
|
||||
$this->fixXMLIndexes();
|
||||
// $this->fixXMLColumns();
|
||||
}
|
||||
|
||||
protected function fixXMLForeignKeys()
|
||||
{
|
||||
foreach ($this->getTables() as $table => $columns)
|
||||
{
|
||||
if (isset($this->database[$table]['_foreign_keys']))
|
||||
{
|
||||
$foreign_keys = $this->database[$table]['_foreign_keys'];
|
||||
foreach ($foreign_keys as $foreign_key_name => $foreign_key_attributes)
|
||||
{
|
||||
// Only single foreign keys can be simplified
|
||||
if (count($foreign_key_attributes['references']) == 1)
|
||||
{
|
||||
$reference = $foreign_key_attributes['references'][0];
|
||||
|
||||
// set simple foreign key
|
||||
$this->database[$table][$reference['local']]['foreignTable'] = $foreign_key_attributes['foreign_table'];
|
||||
$this->database[$table][$reference['local']]['foreignReference'] = $reference['foreign'];
|
||||
if (isset($foreign_key_attributes['on_delete']))
|
||||
{
|
||||
$this->database[$table][$reference['local']]['onDelete'] = $foreign_key_attributes['on_delete'];
|
||||
}
|
||||
if (isset($foreign_key_attributes['on_update']))
|
||||
{
|
||||
$this->database[$table][$reference['local']]['onUpdate'] = $foreign_key_attributes['on_update'];
|
||||
}
|
||||
|
||||
// remove complex foreign key
|
||||
unset($this->database[$table]['_foreign_keys'][$foreign_key_name]);
|
||||
}
|
||||
|
||||
$this->removeEmptyKey($this->database[$table], '_foreign_keys');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function fixXMLIndexes()
|
||||
{
|
||||
foreach ($this->getTables() as $table => $columns)
|
||||
{
|
||||
if (isset($this->database[$table]['_indexes']))
|
||||
{
|
||||
$indexes = $this->database[$table]['_indexes'];
|
||||
foreach ($indexes as $index => $references)
|
||||
{
|
||||
// Only single indexes can be simplified
|
||||
if (count($references) == 1 && array_key_exists(substr($index, 0, strlen($index) - 6), $columns))
|
||||
{
|
||||
$reference = $references[0];
|
||||
|
||||
// set simple index
|
||||
$this->database[$table][$reference]['index'] = 'true';
|
||||
|
||||
// remove complex index
|
||||
unset($this->database[$table]['_indexes'][$index]);
|
||||
}
|
||||
|
||||
$this->removeEmptyKey($this->database[$table], '_indexes');
|
||||
}
|
||||
}
|
||||
if (isset($this->database[$table]['_uniques']))
|
||||
{
|
||||
$uniques = $this->database[$table]['_uniques'];
|
||||
foreach ($uniques as $index => $references)
|
||||
{
|
||||
// Only single unique indexes can be simplified
|
||||
if (count($references) == 1 && array_key_exists(substr($index, 0, strlen($index) - 7), $columns))
|
||||
{
|
||||
$reference = $references[0];
|
||||
|
||||
// set simple index
|
||||
$this->database[$table][$reference]['index'] = 'unique';
|
||||
|
||||
// remove complex unique index
|
||||
unset($this->database[$table]['_uniques'][$index]);
|
||||
}
|
||||
|
||||
$this->removeEmptyKey($this->database[$table], '_uniques');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function fixXMLColumns()
|
||||
{
|
||||
foreach ($this->getTables() as $table => $columns)
|
||||
{
|
||||
foreach ($columns as $column => $attributes)
|
||||
{
|
||||
if ($column == 'id' && !array_diff($attributes, array('type' => 'integer', 'required' => 'true', 'primaryKey' => 'true', 'autoincrement' => 'true')))
|
||||
{
|
||||
// simplify primary keys
|
||||
$this->database[$table]['id'] = null;
|
||||
}
|
||||
|
||||
if (($column == 'created_at') || ($column == 'updated_at') && !array_diff($attributes, array('type' => 'timestamp')))
|
||||
{
|
||||
// simplify timestamps
|
||||
$this->database[$table][$column] = null;
|
||||
}
|
||||
|
||||
$pos = strpos($column, '_id');
|
||||
$has_fk_name = $pos > 0 && $pos == strlen($column) - 3;
|
||||
$is_foreign_key = isset($attributes['type']) && $attributes['type'] == 'integer' && isset($attributes['foreignReference']) && $attributes['foreignReference'] == 'id';
|
||||
$has_foreign_table = isset($attributes['foreignTable']) && array_key_exists($attributes['foreignTable'], $this->getTables());
|
||||
$has_other_attribute = isset($attributes['onDelete']);
|
||||
if ($has_fk_name && $has_foreign_table && $is_foreign_key && !$has_other_attribute)
|
||||
{
|
||||
// simplify foreign key
|
||||
$this->database[$table][$column] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function asYAML()
|
||||
{
|
||||
return sfYaml::dump(array($this->connection_name => $this->database));
|
||||
}
|
||||
|
||||
protected function getNameAndAttributes($hash, $name_attribute = 'name')
|
||||
{
|
||||
// tag name
|
||||
$name = '';
|
||||
if (isset($hash[$name_attribute]))
|
||||
{
|
||||
$name = strval($hash[$name_attribute]);
|
||||
unset($hash[$name_attribute]);
|
||||
}
|
||||
|
||||
// tag attributes
|
||||
$attributes = array();
|
||||
foreach ($hash as $attribute => $value)
|
||||
{
|
||||
$attributes[$attribute] = strval($value);
|
||||
}
|
||||
|
||||
return array($name, $attributes);
|
||||
}
|
||||
|
||||
protected function removeEmptyKey(&$hash, $key)
|
||||
{
|
||||
if (isset($hash[$key]) && !$hash[$key])
|
||||
{
|
||||
unset($hash[$key]);
|
||||
}
|
||||
}
|
||||
}
|
106
lib/symfony/addon/propel/sfPropelManyToMany.class.php
Executable file
106
lib/symfony/addon/propel/sfPropelManyToMany.class.php
Executable file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage util
|
||||
* @author Nick Lane <nick.lane@internode.on.net>
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPropelManyToMany.class.php 1931 2006-09-02 17:56:18Z fabien $
|
||||
*/
|
||||
class sfPropelManyToMany
|
||||
{
|
||||
public static function getColumn($class, $middleClass)
|
||||
{
|
||||
// find the related class
|
||||
$tableMap = call_user_func(array($middleClass.'Peer', 'getTableMap'));
|
||||
$object_table_name = constant($class.'Peer::TABLE_NAME');
|
||||
foreach ($tableMap->getColumns() as $column)
|
||||
{
|
||||
if ($column->isForeignKey() && $object_table_name == $column->getRelatedTableName())
|
||||
{
|
||||
return $column;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getRelatedColumn($class, $middleClass)
|
||||
{
|
||||
// find the related class
|
||||
$tableMap = call_user_func(array($middleClass.'Peer', 'getTableMap'));
|
||||
$object_table_name = constant($class.'Peer::TABLE_NAME');
|
||||
foreach ($tableMap->getColumns() as $column)
|
||||
{
|
||||
if ($column->isForeignKey() && $object_table_name != $column->getRelatedTableName())
|
||||
{
|
||||
return $column;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getRelatedClass($class, $middleClass)
|
||||
{
|
||||
$column = self::getRelatedColumn($class, $middleClass);
|
||||
|
||||
// we must load all map builder classes
|
||||
$classes = sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs());
|
||||
foreach ($classes as $class)
|
||||
{
|
||||
$class_map_builder = basename($class, '.php');
|
||||
$map = new $class_map_builder();
|
||||
$map->doBuild();
|
||||
}
|
||||
|
||||
$tableMap = call_user_func(array($middleClass.'Peer', 'getTableMap'));
|
||||
|
||||
return $tableMap->getDatabaseMap()->getTable($column->getRelatedTableName())->getPhpName();
|
||||
}
|
||||
|
||||
public static function getAllObjects($object, $middleClass, $criteria = null)
|
||||
{
|
||||
if (null === $criteria)
|
||||
{
|
||||
$criteria = new Criteria();
|
||||
}
|
||||
|
||||
$relatedClass = self::getRelatedClass(get_class($object), $middleClass);
|
||||
|
||||
return call_user_func(array($relatedClass.'Peer', 'doSelect'), $criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets objects related by a many-to-many relationship, with a middle table.
|
||||
*
|
||||
* @param $object The object to get related objects for.
|
||||
* @param $middleClass The middle class used for the many-to-many relationship.
|
||||
* @param $criteria Criteria to apply to the selection.
|
||||
*/
|
||||
public static function getRelatedObjects($object, $middleClass, $criteria = null)
|
||||
{
|
||||
if (null === $criteria)
|
||||
{
|
||||
$criteria = new Criteria();
|
||||
}
|
||||
|
||||
$relatedClass = self::getRelatedClass(get_class($object), $middleClass);
|
||||
|
||||
$relatedObjects = array();
|
||||
$objectMethod = 'get'.$middleClass.'sJoin'.$relatedClass;
|
||||
$relatedMethod = 'get'.$relatedClass;
|
||||
$rels = $object->$objectMethod($criteria);
|
||||
foreach ($rels as $rel)
|
||||
{
|
||||
$relatedObjects[] = $rel->$relatedMethod();
|
||||
}
|
||||
|
||||
return $relatedObjects;
|
||||
}
|
||||
}
|
138
lib/symfony/addon/propel/sfPropelPager.class.php
Executable file
138
lib/symfony/addon/propel/sfPropelPager.class.php
Executable file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPropelPager.class.php 2728 2006-11-17 09:46:01Z chtito $
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* sfPropelPager class.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPropelPager.class.php 2728 2006-11-17 09:46:01Z chtito $
|
||||
*/
|
||||
class sfPropelPager extends sfPager
|
||||
{
|
||||
protected
|
||||
$criteria = null,
|
||||
$peer_method_name = 'doSelect',
|
||||
$peer_count_method_name = 'doCount';
|
||||
|
||||
public function __construct($class, $maxPerPage = 10)
|
||||
{
|
||||
parent::__construct($class, $maxPerPage);
|
||||
|
||||
$this->setCriteria(new Criteria());
|
||||
$this->tableName = constant($class.'Peer::TABLE_NAME');
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$hasMaxRecordLimit = ($this->getMaxRecordLimit() !== false);
|
||||
$maxRecordLimit = $this->getMaxRecordLimit();
|
||||
|
||||
$cForCount = clone $this->getCriteria();
|
||||
$cForCount->setOffset(0);
|
||||
$cForCount->setLimit(0);
|
||||
$cForCount->clearGroupByColumns();
|
||||
|
||||
// require the model class (because autoloading can crash under some conditions)
|
||||
if (!$classPath = sfCore::getClassPath($this->getClassPeer()))
|
||||
{
|
||||
throw new sfException(sprintf('Unable to find path for class "%s".', $this->getClassPeer()));
|
||||
}
|
||||
require_once($classPath);
|
||||
$count = call_user_func(array($this->getClassPeer(), $this->getPeerCountMethod()), $cForCount);
|
||||
|
||||
$this->setNbResults($hasMaxRecordLimit ? min($count, $maxRecordLimit) : $count);
|
||||
|
||||
$c = $this->getCriteria();
|
||||
$c->setOffset(0);
|
||||
$c->setLimit(0);
|
||||
|
||||
if (($this->getPage() == 0 || $this->getMaxPerPage() == 0))
|
||||
{
|
||||
$this->setLastPage(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->setLastPage(ceil($this->getNbResults() / $this->getMaxPerPage()));
|
||||
|
||||
$offset = ($this->getPage() - 1) * $this->getMaxPerPage();
|
||||
$c->setOffset($offset);
|
||||
|
||||
if ($hasMaxRecordLimit)
|
||||
{
|
||||
$maxRecordLimit = $maxRecordLimit - $offset;
|
||||
if ($maxRecordLimit > $this->getMaxPerPage())
|
||||
{
|
||||
$c->setLimit($this->getMaxPerPage());
|
||||
}
|
||||
else
|
||||
{
|
||||
$c->setLimit($maxRecordLimit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$c->setLimit($this->getMaxPerPage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function retrieveObject($offset)
|
||||
{
|
||||
$cForRetrieve = clone $this->getCriteria();
|
||||
$cForRetrieve->setOffset($offset - 1);
|
||||
$cForRetrieve->setLimit(1);
|
||||
|
||||
$results = call_user_func(array($this->getClassPeer(), $this->getPeerMethod()), $cForRetrieve);
|
||||
|
||||
return $results[0];
|
||||
}
|
||||
|
||||
public function getResults()
|
||||
{
|
||||
$c = $this->getCriteria();
|
||||
|
||||
return call_user_func(array($this->getClassPeer(), $this->getPeerMethod()), $c);
|
||||
}
|
||||
|
||||
public function getPeerMethod()
|
||||
{
|
||||
return $this->peer_method_name;
|
||||
}
|
||||
|
||||
public function setPeerMethod($peer_method_name)
|
||||
{
|
||||
$this->peer_method_name = $peer_method_name;
|
||||
}
|
||||
|
||||
public function getPeerCountMethod()
|
||||
{
|
||||
return $this->peer_count_method_name;
|
||||
}
|
||||
|
||||
public function setPeerCountMethod($peer_count_method_name)
|
||||
{
|
||||
$this->peer_count_method_name = $peer_count_method_name;
|
||||
}
|
||||
|
||||
public function getClassPeer()
|
||||
{
|
||||
return $this->class.'Peer';
|
||||
}
|
||||
}
|
98
lib/symfony/addon/propel/validator/sfPropelUniqueValidator.class.php
Executable file
98
lib/symfony/addon/propel/validator/sfPropelUniqueValidator.class.php
Executable file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* sfPropelUniqueValidator validates that the uniqueness of a column.
|
||||
* This validator only works for single column primary key.
|
||||
*
|
||||
* <b>Required parameters:</b>
|
||||
*
|
||||
* # <b>class</b> - [none] - Propel class name.
|
||||
* # <b>column</b> - [none] - Propel column name.
|
||||
*
|
||||
* <b>Optional parameters:</b>
|
||||
*
|
||||
* # <b>unique_error</b> - [Uniqueness error] - An error message to use when
|
||||
* the value for this column already
|
||||
* exists in the database.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage validator
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @author Fédéric Coelho <frederic.coelho@symfony-project.com>
|
||||
* @version SVN: $Id: sfPropelUniqueValidator.class.php 2995 2006-12-09 18:01:32Z fabien $
|
||||
*/
|
||||
class sfPropelUniqueValidator extends sfValidator
|
||||
{
|
||||
public function execute(&$value, &$error)
|
||||
{
|
||||
$className = $this->getParameter('class').'Peer';
|
||||
$columnName = call_user_func(array($className, 'translateFieldName'), $this->getParameter('column'), BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME);
|
||||
|
||||
$c = new Criteria();
|
||||
$c->add($columnName, $value);
|
||||
$object = call_user_func(array($className, 'doSelectOne'), $c);
|
||||
|
||||
if ($object)
|
||||
{
|
||||
$tableMap = call_user_func(array($className, 'getTableMap'));
|
||||
foreach ($tableMap->getColumns() as $column)
|
||||
{
|
||||
if (!$column->isPrimaryKey())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$method = 'get'.$column->getPhpName();
|
||||
$primaryKey = call_user_func(array($className, 'translateFieldName'), $column->getPhpName(), BasePeer::TYPE_PHPNAME, BasePeer::TYPE_FIELDNAME);
|
||||
if ($object->$method() != $this->getContext()->getRequest()->getParameter($primaryKey))
|
||||
{
|
||||
$error = $this->getParameter('unique_error');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this validator.
|
||||
*
|
||||
* @param sfContext The current application context.
|
||||
* @param array An associative array of initialization parameters.
|
||||
*
|
||||
* @return bool true, if initialization completes successfully, otherwise false.
|
||||
*/
|
||||
public function initialize($context, $parameters = null)
|
||||
{
|
||||
// initialize parent
|
||||
parent::initialize($context);
|
||||
|
||||
// set defaults
|
||||
$this->setParameter('unique_error', 'Uniqueness error');
|
||||
|
||||
$this->getParameterHolder()->add($parameters);
|
||||
|
||||
// check parameters
|
||||
if (!$this->getParameter('class'))
|
||||
{
|
||||
throw new sfValidatorException('The "class" parameter is mandatory for the sfPropelUniqueValidator validator.');
|
||||
}
|
||||
|
||||
if (!$this->getParameter('column'))
|
||||
{
|
||||
throw new sfValidatorException('The "column" parameter is mandatory for the sfPropelUniqueValidator validator.');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
120
lib/symfony/addon/sfData.class.php
Executable file
120
lib/symfony/addon/sfData.class.php
Executable file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class defines the interface for interacting with data, as well
|
||||
* as default implementations.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfData.class.php 3382 2007-02-01 07:34:56Z fabien $
|
||||
*/
|
||||
|
||||
abstract class sfData
|
||||
{
|
||||
protected
|
||||
$deleteCurrentData = true,
|
||||
$object_references = array();
|
||||
|
||||
/**
|
||||
* Sets a flag to indicate if the current data in the database
|
||||
* should be deleted before new data is loaded.
|
||||
*
|
||||
* @param boolean The flag value
|
||||
*/
|
||||
public function setDeleteCurrentData($boolean)
|
||||
{
|
||||
$this->deleteCurrentData = $boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value of the flag that indicates whether
|
||||
* current data is to be deleted or not.
|
||||
*
|
||||
* @returns boolean
|
||||
*/
|
||||
public function getDeleteCurrentData()
|
||||
{
|
||||
return $this->deleteCurrentData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads data for the database from a YAML file
|
||||
*
|
||||
* @param string The path to the YAML file.
|
||||
*/
|
||||
protected function doLoadDataFromFile($fixture_file)
|
||||
{
|
||||
// import new datas
|
||||
$data = sfYaml::load($fixture_file);
|
||||
|
||||
$this->loadDataFromArray($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the insertion of data into the data source
|
||||
*
|
||||
* @param array The data to be inserted into the data source
|
||||
*/
|
||||
abstract public function loadDataFromArray($data);
|
||||
|
||||
/**
|
||||
* Manages reading all of the fixture data files and
|
||||
* loading them into the data source
|
||||
*
|
||||
* @param array The path names of the YAML data files
|
||||
*/
|
||||
protected function doLoadData($fixture_files)
|
||||
{
|
||||
$this->object_references = array();
|
||||
$this->maps = array();
|
||||
|
||||
sort($fixture_files);
|
||||
foreach ($fixture_files as $fixture_file)
|
||||
{
|
||||
$this->doLoadDataFromFile($fixture_file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of one or more *.yml files and returns the list in an array
|
||||
*
|
||||
* @param string A directory or file name; if null, then defaults to 'sf_data_dir'/fixtures
|
||||
*
|
||||
* @returns array A list of *.yml files.
|
||||
*
|
||||
* @throws sfInitializationException If the directory or file does not exist.
|
||||
*/
|
||||
protected function getFiles($directory_or_file = null)
|
||||
{
|
||||
// directory or file?
|
||||
$fixture_files = array();
|
||||
if (!$directory_or_file)
|
||||
{
|
||||
$directory_or_file = sfConfig::get('sf_data_dir').'/fixtures';
|
||||
}
|
||||
|
||||
if (is_file($directory_or_file))
|
||||
{
|
||||
$fixture_files[] = $directory_or_file;
|
||||
}
|
||||
else if (is_dir($directory_or_file))
|
||||
{
|
||||
$fixture_files = sfFinder::type('file')->name('*.yml')->in($directory_or_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new sfInitializationException('You must give a directory or a file.');
|
||||
}
|
||||
|
||||
return $fixture_files;
|
||||
}
|
||||
}
|
406
lib/symfony/addon/sfMail.class.php
Executable file
406
lib/symfony/addon/sfMail.class.php
Executable file
@ -0,0 +1,406 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* sfMail class.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfMail.class.php 3172 2007-01-05 16:03:15Z fabien $
|
||||
*/
|
||||
class sfMail
|
||||
{
|
||||
protected $mailer;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
require_once(sfConfig::get('sf_symfony_lib_dir').'/vendor/phpmailer/class.phpmailer.php');
|
||||
require_once(sfConfig::get('sf_symfony_lib_dir').'/vendor/phpmailer/class.smtp.php');
|
||||
|
||||
$this->mailer = new PHPMailer();
|
||||
}
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
}
|
||||
|
||||
public function setCharset($charset)
|
||||
{
|
||||
$this->mailer->CharSet = $charset;
|
||||
}
|
||||
|
||||
public function getCharset()
|
||||
{
|
||||
return $this->mailer->CharSet;
|
||||
}
|
||||
|
||||
public function setContentType($content_type)
|
||||
{
|
||||
$this->mailer->ContentType = $content_type;
|
||||
}
|
||||
|
||||
public function getContentType()
|
||||
{
|
||||
return $this->mailer->ContentType;
|
||||
}
|
||||
|
||||
public function setPriority($priority)
|
||||
{
|
||||
$this->mailer->Priority = $priority;
|
||||
}
|
||||
|
||||
public function getPriority()
|
||||
{
|
||||
return $this->mailer->Priority;
|
||||
}
|
||||
|
||||
public function setEncoding($encoding)
|
||||
{
|
||||
$this->mailer->Encoding = $encoding;
|
||||
}
|
||||
|
||||
public function getEncoding()
|
||||
{
|
||||
return $this->mailer->Encoding;
|
||||
}
|
||||
|
||||
public function setSubject($subject)
|
||||
{
|
||||
$this->mailer->Subject = $subject;
|
||||
}
|
||||
|
||||
public function getSubject()
|
||||
{
|
||||
return $this->mailer->Subject;
|
||||
}
|
||||
|
||||
public function setBody($body)
|
||||
{
|
||||
$this->mailer->Body = $body;
|
||||
}
|
||||
|
||||
public function getBody()
|
||||
{
|
||||
return $this->mailer->Body;
|
||||
}
|
||||
|
||||
public function setMailer($type = 'mail', $options = array())
|
||||
{
|
||||
switch ($type)
|
||||
{
|
||||
case 'smtp':
|
||||
$this->mailer->IsSMTP();
|
||||
if (isset($options['keep_alive'])) $this->mailer->SMTPKeepAlive = true;
|
||||
break;
|
||||
case 'sendmail':
|
||||
$this->mailer->IsSendmail();
|
||||
break;
|
||||
default:
|
||||
$this->mailer->IsMail();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function getMailer()
|
||||
{
|
||||
return $this->mailer->Mailer;
|
||||
}
|
||||
|
||||
public function setSender($address, $name = null)
|
||||
{
|
||||
if (!$address)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ($name == null)
|
||||
{
|
||||
list($address, $name) = $this->splitAddress($address);
|
||||
}
|
||||
$this->mailer->Sender = $address;
|
||||
}
|
||||
|
||||
public function getSender()
|
||||
{
|
||||
return $this->mailer->Sender;
|
||||
}
|
||||
|
||||
public function setFrom($address, $name = null)
|
||||
{
|
||||
if (!$address)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ($name == null)
|
||||
{
|
||||
list($address, $name) = $this->splitAddress($address);
|
||||
}
|
||||
$this->mailer->From = $address;
|
||||
$this->mailer->FromName = $name;
|
||||
}
|
||||
|
||||
public function getFrom()
|
||||
{
|
||||
return $this->mailer->From;
|
||||
}
|
||||
|
||||
/*
|
||||
* $recipents:
|
||||
* test@example.com
|
||||
* Example email <test@example.com>
|
||||
* array('test@example.com', 'test1@example.com')
|
||||
* array('Example email <test@example.com>', 'test1@example.com')
|
||||
*/
|
||||
public function addAddresses($addresses)
|
||||
{
|
||||
if (!$addresses)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_array($addresses))
|
||||
{
|
||||
foreach ($addresses as $address)
|
||||
{
|
||||
list($address, $name) = $this->splitAddress($address);
|
||||
$this->mailer->AddAddress($address, $name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list($address, $name) = $this->splitAddress($addresses);
|
||||
$this->mailer->AddAddress($address, $name);
|
||||
}
|
||||
}
|
||||
|
||||
private function splitAddress($address)
|
||||
{
|
||||
if (preg_match('/^(.+)\s<(.+?)>$/', $address, $matches))
|
||||
{
|
||||
return array($matches[2], $matches[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return array($address, '');
|
||||
}
|
||||
}
|
||||
|
||||
public function addAddress($address, $name = null)
|
||||
{
|
||||
if ($name == null)
|
||||
{
|
||||
list($address, $name) = $this->splitAddress($address);
|
||||
}
|
||||
$this->mailer->AddAddress($address, $name);
|
||||
}
|
||||
|
||||
public function addCc($address, $name = null)
|
||||
{
|
||||
if ($name == null)
|
||||
{
|
||||
list($address, $name) = $this->splitAddress($address);
|
||||
}
|
||||
$this->mailer->AddCc($address, $name);
|
||||
}
|
||||
|
||||
public function addBcc($address, $name = null)
|
||||
{
|
||||
if ($name == null)
|
||||
{
|
||||
list($address, $name) = $this->splitAddress($address);
|
||||
}
|
||||
$this->mailer->AddBcc($address, $name);
|
||||
}
|
||||
|
||||
public function addReplyTo($address, $name = null)
|
||||
{
|
||||
if (!$address)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ($name == null)
|
||||
{
|
||||
list($address, $name) = $this->splitAddress($address);
|
||||
}
|
||||
$this->mailer->AddReplyTo($address, $name);
|
||||
}
|
||||
|
||||
public function clearAddresses()
|
||||
{
|
||||
$this->mailer->ClearAddresses();
|
||||
}
|
||||
|
||||
public function clearCcs()
|
||||
{
|
||||
$this->mailer->ClearCcs();
|
||||
}
|
||||
|
||||
public function clearBccs()
|
||||
{
|
||||
$this->mailer->ClearBccs();
|
||||
}
|
||||
|
||||
public function clearReplyTos()
|
||||
{
|
||||
$this->mailer->ClearReplyTos();
|
||||
}
|
||||
|
||||
public function clearAllRecipients()
|
||||
{
|
||||
$this->mailer->ClearAllRecipients();
|
||||
}
|
||||
|
||||
public function addAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream')
|
||||
{
|
||||
$this->mailer->AddAttachment($path, $name, $encoding, $type);
|
||||
}
|
||||
|
||||
public function addStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream')
|
||||
{
|
||||
$this->mailer->AddStringAttachment($string, $filename, $encoding, $type);
|
||||
}
|
||||
|
||||
public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream')
|
||||
{
|
||||
$this->mailer->AddEmbeddedImage($path, $cid, $name, $encoding, $type);
|
||||
}
|
||||
|
||||
public function setAttachments($attachments)
|
||||
{
|
||||
if ($attachments instanceof sfMailAttachments)
|
||||
{
|
||||
$this->mailer->setAttachments($attachments->getAttachments());
|
||||
}
|
||||
}
|
||||
|
||||
public function clearAttachments()
|
||||
{
|
||||
$this->mailer->ClearAttachments();
|
||||
}
|
||||
|
||||
function addCustomHeader($name, $value)
|
||||
{
|
||||
$this->mailer->AddCustomHeader("$name: $value");
|
||||
}
|
||||
|
||||
function clearCustomHeaders()
|
||||
{
|
||||
$this->mailer->ClearCustomHeaders();
|
||||
}
|
||||
|
||||
public function prepare()
|
||||
{
|
||||
// Set whether the message is multipart/alternative
|
||||
if (!empty($this->mailer->AltBody))
|
||||
{
|
||||
$this->mailer->ContentType = "multipart/alternative";
|
||||
}
|
||||
|
||||
$this->mailer->SetMessageType();
|
||||
}
|
||||
|
||||
public function send()
|
||||
{
|
||||
if (!$this->mailer->Send())
|
||||
{
|
||||
throw new sfException($this->mailer->ErrorInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public function smtpClose()
|
||||
{
|
||||
$this->mailer->SmtpClose();
|
||||
}
|
||||
|
||||
public function getRawHeader()
|
||||
{
|
||||
return $this->mailer->CreateHeader();
|
||||
}
|
||||
|
||||
public function getRawBody()
|
||||
{
|
||||
return $this->mailer->CreateBody();
|
||||
}
|
||||
|
||||
public function setDomain($hostname)
|
||||
{
|
||||
$this->mailer->Hostname = $hostname;
|
||||
}
|
||||
|
||||
public function getDomain()
|
||||
{
|
||||
return $this->mailer->Hostname;
|
||||
}
|
||||
|
||||
public function setHostname($hostname)
|
||||
{
|
||||
$this->mailer->Host = $hostname;
|
||||
}
|
||||
|
||||
public function getHostname()
|
||||
{
|
||||
return $this->mailer->Host;
|
||||
}
|
||||
|
||||
public function setPort($port)
|
||||
{
|
||||
$this->mailer->Port = $port;
|
||||
}
|
||||
|
||||
public function getPort()
|
||||
{
|
||||
return $this->mailer->Port;
|
||||
}
|
||||
|
||||
public function setUsername($username)
|
||||
{
|
||||
$this->mailer->Username = $username;
|
||||
$this->mailer->SMTPAuth = $username ? true : false;
|
||||
}
|
||||
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->mailer->Username;
|
||||
}
|
||||
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->mailer->Password = $password;
|
||||
}
|
||||
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->mailer->Password;
|
||||
}
|
||||
|
||||
public function setWordWrap($wordWrap)
|
||||
{
|
||||
$this->mailer->WordWrap = $wordWrap;
|
||||
}
|
||||
|
||||
public function getWordWrap()
|
||||
{
|
||||
return $this->mailer->WordWrap;
|
||||
}
|
||||
|
||||
public function setAltBody($text)
|
||||
{
|
||||
$this->mailer->AltBody = $text;
|
||||
}
|
||||
|
||||
public function getAltBody()
|
||||
{
|
||||
return $this->mailer->AltBody;
|
||||
}
|
||||
}
|
307
lib/symfony/addon/sfPager.class.php
Executable file
307
lib/symfony/addon/sfPager.class.php
Executable file
@ -0,0 +1,307 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the symfony package.
|
||||
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPager.class.php 3099 2006-12-20 08:16:15Z fabien $
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* sfPager class.
|
||||
*
|
||||
* @package symfony
|
||||
* @subpackage addon
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @version SVN: $Id: sfPager.class.php 3099 2006-12-20 08:16:15Z fabien $
|
||||
*/
|
||||
abstract class sfPager
|
||||
{
|
||||
protected
|
||||
$page = 1,
|
||||
$maxPerPage = 0,
|
||||
$lastPage = 1,
|
||||
$nbResults = 0,
|
||||
$class = '',
|
||||
$tableName = '',
|
||||
$objects = null,
|
||||
$cursor = 1,
|
||||
$parameters = array(),
|
||||
$currentMaxLink = 1,
|
||||
$parameterHolder = null,
|
||||
$maxRecordLimit = false;
|
||||
|
||||
public function __construct($class, $maxPerPage = 10)
|
||||
{
|
||||
$this->setClass($class);
|
||||
$this->setMaxPerPage($maxPerPage);
|
||||
$this->setPage(1);
|
||||
$this->parameterHolder = new sfParameterHolder();
|
||||
}
|
||||
|
||||
// function to be called after parameters have been set
|
||||
abstract public function init();
|
||||
|
||||
// main method: returns an array of result on the given page
|
||||
abstract public function getResults();
|
||||
|
||||
// used internally by getCurrent()
|
||||
abstract protected function retrieveObject($offset);
|
||||
|
||||
public function getCurrentMaxLink()
|
||||
{
|
||||
return $this->currentMaxLink;
|
||||
}
|
||||
|
||||
public function getMaxRecordLimit()
|
||||
{
|
||||
return $this->maxRecordLimit;
|
||||
}
|
||||
|
||||
public function setMaxRecordLimit($limit)
|
||||
{
|
||||
$this->maxRecordLimit = $limit;
|
||||
}
|
||||
|
||||
public function getLinks($nb_links = 5)
|
||||
{
|
||||
$links = array();
|
||||
$tmp = $this->page - floor($nb_links / 2);
|
||||
$check = $this->lastPage - $nb_links + 1;
|
||||
$limit = ($check > 0) ? $check : 1;
|
||||
$begin = ($tmp > 0) ? (($tmp > $limit) ? $limit : $tmp) : 1;
|
||||
|
||||
$i = $begin;
|
||||
while (($i < $begin + $nb_links) && ($i <= $this->lastPage))
|
||||
{
|
||||
$links[] = $i++;
|
||||
}
|
||||
|
||||
$this->currentMaxLink = $links[count($links) - 1];
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
public function haveToPaginate()
|
||||
{
|
||||
return (($this->getPage() != 0) && ($this->getNbResults() > $this->getMaxPerPage()));
|
||||
}
|
||||
|
||||
public function getCursor()
|
||||
{
|
||||
return $this->cursor;
|
||||
}
|
||||
|
||||
public function setCursor($pos)
|
||||
{
|
||||
if ($pos < 1)
|
||||
{
|
||||
$this->cursor = 1;
|
||||
}
|
||||
else if ($pos > $this->nbResults)
|
||||
{
|
||||
$this->cursor = $this->nbResults;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->cursor = $pos;
|
||||
}
|
||||
}
|
||||
|
||||
public function getObjectByCursor($pos)
|
||||
{
|
||||
$this->setCursor($pos);
|
||||
|
||||
return $this->getCurrent();
|
||||
}
|
||||
|
||||
public function getCurrent()
|
||||
{
|
||||
return $this->retrieveObject($this->cursor);
|
||||
}
|
||||
|
||||
public function getNext()
|
||||
{
|
||||
if (($this->cursor + 1) > $this->nbResults)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->retrieveObject($this->cursor + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public function getPrevious()
|
||||
{
|
||||
if (($this->cursor - 1) < 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->retrieveObject($this->cursor - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public function getFirstIndice()
|
||||
{
|
||||
if ($this->page == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ($this->page - 1) * $this->maxPerPage + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public function getLastIndice()
|
||||
{
|
||||
if ($this->page == 0)
|
||||
{
|
||||
return $this->nbResults;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($this->page * $this->maxPerPage) >= $this->nbResults)
|
||||
{
|
||||
return $this->nbResults;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ($this->page * $this->maxPerPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getCriteria()
|
||||
{
|
||||
return $this->criteria;
|
||||
}
|
||||
|
||||
public function setCriteria($c)
|
||||
{
|
||||
$this->criteria = $c;
|
||||
}
|
||||
|
||||
public function getClass()
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
public function setClass($class)
|
||||
{
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
public function getNbResults()
|
||||
{
|
||||
return $this->nbResults;
|
||||
}
|
||||
|
||||
protected function setNbResults($nb)
|
||||
{
|
||||
$this->nbResults = $nb;
|
||||
}
|
||||
|
||||
public function getFirstPage()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getLastPage()
|
||||
{
|
||||
return $this->lastPage;
|
||||
}
|
||||
|
||||
protected function setLastPage($page)
|
||||
{
|
||||
$this->lastPage = $page;
|
||||
if ($this->getPage() > $page)
|
||||
{
|
||||
$this->setPage($page);
|
||||
}
|
||||
}
|
||||
|
||||
public function getPage()
|
||||
{
|
||||
return $this->page;
|
||||
}
|
||||
|
||||
public function getNextPage()
|
||||
{
|
||||
return min($this->getPage() + 1, $this->getLastPage());
|
||||
}
|
||||
|
||||
public function getPreviousPage()
|
||||
{
|
||||
return max($this->getPage() - 1, $this->getFirstPage());
|
||||
}
|
||||
|
||||
public function setPage($page)
|
||||
{
|
||||
$page = intval($page);
|
||||
|
||||
$this->page = ($page <= 0) ? 1 : $page;
|
||||
}
|
||||
|
||||
public function getMaxPerPage()
|
||||
{
|
||||
return $this->maxPerPage;
|
||||
}
|
||||
|
||||
public function setMaxPerPage($max)
|
||||
{
|
||||
if ($max > 0)
|
||||
{
|
||||
$this->maxPerPage = $max;
|
||||
if ($this->page == 0)
|
||||
{
|
||||
$this->page = 1;
|
||||
}
|
||||
}
|
||||
else if ($max == 0)
|
||||
{
|
||||
$this->maxPerPage = 0;
|
||||
$this->page = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->maxPerPage = 1;
|
||||
if ($this->page == 0)
|
||||
{
|
||||
$this->page = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getParameterHolder()
|
||||
{
|
||||
return $this->parameterHolder;
|
||||
}
|
||||
|
||||
public function getParameter($name, $default = null, $ns = null)
|
||||
{
|
||||
return $this->parameterHolder->get($name, $default, $ns);
|
||||
}
|
||||
|
||||
public function hasParameter($name, $ns = null)
|
||||
{
|
||||
return $this->parameterHolder->has($name, $ns);
|
||||
}
|
||||
|
||||
public function setParameter($name, $value, $ns = null)
|
||||
{
|
||||
return $this->parameterHolder->set($name, $value, $ns);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user