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:
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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user