Introducing the Propel Bridge
Basic bridge with stable components for Propel.
This commit is contained in:
parent
c18f5a8d94
commit
cdad7ab166
128
src/Symfony/Bridge/Propel/DataCollector/PropelDataCollector.php
Normal file
128
src/Symfony/Bridge/Propel/DataCollector/PropelDataCollector.php
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bridge\Propel\DataCollector;
|
||||||
|
|
||||||
|
use Symfony\Bridge\Propel\Logger\PropelLogger;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PropelDataCollector collector class collects information.
|
||||||
|
*
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
*/
|
||||||
|
class PropelDataCollector extends DataCollector
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Propel logger
|
||||||
|
* @var \Symfony\Bridge\Propel\Logger\PropelLogger
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Propel configuration
|
||||||
|
* @var \PropelConfiguration
|
||||||
|
*/
|
||||||
|
protected $propelConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param \Symfony\Bridge\Propel\Logger\PropelLogger $logger A Propel logger.
|
||||||
|
* @param \PropelConfiguration $propelConfiguration The Propel configuration object.
|
||||||
|
*/
|
||||||
|
public function __construct(PropelLogger $logger, \PropelConfiguration $propelConfiguration)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->propelConfiguration = $propelConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||||
|
{
|
||||||
|
$this->data = array(
|
||||||
|
'queries' => $this->buildQueries(),
|
||||||
|
'querycount' => $this->countQueries(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the collector name.
|
||||||
|
*
|
||||||
|
* @return string The collector name.
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'propel';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns queries.
|
||||||
|
*
|
||||||
|
* @return array Queries
|
||||||
|
*/
|
||||||
|
public function getQueries()
|
||||||
|
{
|
||||||
|
return $this->data['queries'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the query count.
|
||||||
|
*
|
||||||
|
* @return int The query count
|
||||||
|
*/
|
||||||
|
public function getQueryCount()
|
||||||
|
{
|
||||||
|
return $this->data['querycount'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an array of Build objects.
|
||||||
|
*
|
||||||
|
* @return array An array of Build objects
|
||||||
|
*/
|
||||||
|
private function buildQueries()
|
||||||
|
{
|
||||||
|
$queries = array();
|
||||||
|
|
||||||
|
$outerGlue = $this->propelConfiguration->getParameter('debugpdo.logging.outerglue', ' | ');
|
||||||
|
$innerGlue = $this->propelConfiguration->getParameter('debugpdo.logging.innerglue', ': ');
|
||||||
|
|
||||||
|
foreach ($this->logger->getQueries() as $q) {
|
||||||
|
$parts = explode($outerGlue, $q);
|
||||||
|
|
||||||
|
$times = explode($innerGlue, $parts[0]);
|
||||||
|
$memories = explode($innerGlue, $parts[1]);
|
||||||
|
|
||||||
|
$sql = trim($parts[2]);
|
||||||
|
$time = trim($times[1]);
|
||||||
|
$memory = trim($memories[1]);
|
||||||
|
|
||||||
|
$queries[] = array('sql' => $sql, 'time' => $time, 'memory' => $memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $queries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count queries.
|
||||||
|
*
|
||||||
|
* @return int The number of queries.
|
||||||
|
*/
|
||||||
|
private function countQueries()
|
||||||
|
{
|
||||||
|
return count($this->logger->getQueries());
|
||||||
|
}
|
||||||
|
}
|
230
src/Symfony/Bridge/Propel/Form/ChoiceList/ModelChoiceList.php
Normal file
230
src/Symfony/Bridge/Propel/Form/ChoiceList/ModelChoiceList.php
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bridge\Propel\Form\ChoiceList;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\Util\PropertyPath;
|
||||||
|
use Symfony\Component\Form\Exception\FormException;
|
||||||
|
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||||
|
use Symfony\Component\Form\Extension\Core\ChoiceList\ArrayChoiceList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Widely inspirated by the EntityChoiceList (Symfony2).
|
||||||
|
*
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
*/
|
||||||
|
class ModelChoiceList extends ArrayChoiceList
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The models from which the user can choose
|
||||||
|
*
|
||||||
|
* This array is either indexed by ID (if the ID is a single field)
|
||||||
|
* or by key in the choices array (if the ID consists of multiple fields)
|
||||||
|
*
|
||||||
|
* This property is initialized by initializeChoices(). It should only
|
||||||
|
* be accessed through getModel() and getModels().
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $models = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fields of which the identifier of the underlying class consists
|
||||||
|
*
|
||||||
|
* This property should only be accessed through identifier.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $identifier = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TableMap
|
||||||
|
*
|
||||||
|
* @var \TableMap
|
||||||
|
*/
|
||||||
|
private $table = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property path
|
||||||
|
*
|
||||||
|
* @var \Symfony\Component\Form\Util\PropertyPath
|
||||||
|
*/
|
||||||
|
private $propertyPath = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query
|
||||||
|
*/
|
||||||
|
private $query = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $class
|
||||||
|
* @param string $property
|
||||||
|
* @param array $choices
|
||||||
|
* @param \ModelCriteria $queryObject
|
||||||
|
*/
|
||||||
|
public function __construct($class, $property = null, $choices = array(), $queryObject = null)
|
||||||
|
{
|
||||||
|
$this->class = $class;
|
||||||
|
|
||||||
|
$queryClass = $this->class . 'Query';
|
||||||
|
$query = new $queryClass();
|
||||||
|
|
||||||
|
$this->table = $query->getTableMap();
|
||||||
|
$this->identifier = $this->table->getPrimaryKeys();
|
||||||
|
$this->query = $queryObject ?: $query;
|
||||||
|
|
||||||
|
// The property option defines, which property (path) is used for
|
||||||
|
// displaying models as strings
|
||||||
|
if ($property) {
|
||||||
|
$this->propertyPath = new PropertyPath($property);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($choices);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the choices and returns them
|
||||||
|
*
|
||||||
|
* The choices are generated from the models. If the models have a
|
||||||
|
* composite identifier, the choices are indexed using ascending integers.
|
||||||
|
* Otherwise the identifiers are used as indices.
|
||||||
|
*
|
||||||
|
* If the models were passed in the "choices" option, this method
|
||||||
|
* does not have any significant overhead. Otherwise, if a query object
|
||||||
|
* was passed in the "query" option, this query is now used and executed.
|
||||||
|
* In the last case, all models for the underlying class are fetched.
|
||||||
|
*
|
||||||
|
* If the option "property" was passed, the property path in that option
|
||||||
|
* is used as option values. Otherwise this method tries to convert
|
||||||
|
* objects to strings using __toString().
|
||||||
|
*
|
||||||
|
* @return array An array of choices
|
||||||
|
*/
|
||||||
|
protected function load()
|
||||||
|
{
|
||||||
|
parent::load();
|
||||||
|
|
||||||
|
if ($this->choices) {
|
||||||
|
$models = $this->choices;
|
||||||
|
} else {
|
||||||
|
$models = $this->query->find();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->choices = array();
|
||||||
|
$this->models = array();
|
||||||
|
|
||||||
|
foreach ($models as $key => $model) {
|
||||||
|
if ($this->propertyPath) {
|
||||||
|
// If the property option was given, use it
|
||||||
|
$value = $this->propertyPath->getValue($model);
|
||||||
|
} else {
|
||||||
|
// Otherwise expect a __toString() method in the model
|
||||||
|
$value = (string)$model;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->identifier) > 1) {
|
||||||
|
// When the identifier consists of multiple field, use
|
||||||
|
// naturally ordered keys to refer to the choices
|
||||||
|
$this->choices[$key] = $value;
|
||||||
|
$this->models[$key] = $model;
|
||||||
|
} else {
|
||||||
|
// When the identifier is a single field, index choices by
|
||||||
|
// model ID for performance reasons
|
||||||
|
$id = current($this->getIdentifierValues($model));
|
||||||
|
$this->choices[$id] = $value;
|
||||||
|
$this->models[$id] = $model;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return $this->identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the according models for the choices
|
||||||
|
*
|
||||||
|
* If the choices were not initialized, they are initialized now. This
|
||||||
|
* is an expensive operation, except if the models were passed in the
|
||||||
|
* "choices" option.
|
||||||
|
*
|
||||||
|
* @return array An array of models
|
||||||
|
*/
|
||||||
|
public function getModels()
|
||||||
|
{
|
||||||
|
if (!$this->loaded) {
|
||||||
|
$this->load();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->models;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the model for the given key
|
||||||
|
*
|
||||||
|
* If the underlying models have composite identifiers, the choices
|
||||||
|
* are intialized. The key is expected to be the index in the choices
|
||||||
|
* array in this case.
|
||||||
|
*
|
||||||
|
* If they have single identifiers, they are either fetched from the
|
||||||
|
* internal model cache (if filled) or loaded from the database.
|
||||||
|
*
|
||||||
|
* @param string $key The choice key (for models with composite
|
||||||
|
* identifiers) or model ID (for models with single
|
||||||
|
* identifiers)
|
||||||
|
* @return object The matching model
|
||||||
|
*/
|
||||||
|
public function getModel($key)
|
||||||
|
{
|
||||||
|
if (!$this->loaded) {
|
||||||
|
$this->load();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (count($this->identifier) > 1) {
|
||||||
|
// $key is a collection index
|
||||||
|
$models = $this->getModels();
|
||||||
|
|
||||||
|
return isset($models[$key]) ? $models[$key] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->models) {
|
||||||
|
return isset($this->models[$key]) ? $this->models[$key] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$queryClass = $this->class . 'Query';
|
||||||
|
|
||||||
|
return $queryClass::create()->findPk($key);
|
||||||
|
} catch (NoResultException $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the values of the identifier fields of an model
|
||||||
|
*
|
||||||
|
* Propel must know about this model, that is, the model must already
|
||||||
|
* be persisted or added to the idmodel map before. Otherwise an
|
||||||
|
* exception is thrown.
|
||||||
|
*
|
||||||
|
* @param object $model The model for which to get the identifier
|
||||||
|
* @throws FormException If the model does not exist
|
||||||
|
*/
|
||||||
|
public function getIdentifierValues($model)
|
||||||
|
{
|
||||||
|
if ($model instanceof \BaseObject) {
|
||||||
|
return array($model->getPrimaryKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model->getPrimaryKeys();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bridge\Propel\Form\DataTransformer;
|
||||||
|
|
||||||
|
use Symfony\Bridge\Propel\Form\ChoiceList\ModelChoiceList;
|
||||||
|
use Symfony\Component\Form\DataTransformerInterface;
|
||||||
|
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||||
|
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
*/
|
||||||
|
class ModelToIdTransformer implements DataTransformerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Propel\PropelBundle\Form\ChoiceList\ModelChoiceList
|
||||||
|
*/
|
||||||
|
private $choiceList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Propel\PropelBundle\Form\ChoiceList\ModelChoiceList $choiceList
|
||||||
|
*/
|
||||||
|
public function __construct(ModelChoiceList $choiceList)
|
||||||
|
{
|
||||||
|
$this->choiceList = $choiceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function transform($model)
|
||||||
|
{
|
||||||
|
if (null === $model || '' === $model) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_object($model)) {
|
||||||
|
throw new UnexpectedTypeException($model, 'object');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->choiceList->getIdentifier()) > 1) {
|
||||||
|
$availableModels = $this->choiceList->getModels();
|
||||||
|
|
||||||
|
return array_search($model, $availableModels);
|
||||||
|
}
|
||||||
|
|
||||||
|
return current($this->choiceList->getIdentifierValues($model));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reverseTransform($key)
|
||||||
|
{
|
||||||
|
if ('' === $key || null === $key) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->choiceList->getIdentifier()) > 1 && !is_numeric($key)) {
|
||||||
|
throw new UnexpectedTypeException($key, 'numeric');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$model = $this->choiceList->getModel($key)) {
|
||||||
|
throw new TransformationFailedException(sprintf('The model with key "%s" could not be found', $key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bridge\Propel\Form\DataTransformer;
|
||||||
|
|
||||||
|
use Symfony\Bridge\Propel\Form\ChoiceList\ModelChoiceList;
|
||||||
|
use Symfony\Component\Form\DataTransformerInterface;
|
||||||
|
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||||
|
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||||
|
|
||||||
|
use \PropelCollection;
|
||||||
|
use \PropelObjectCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ModelsToArrayTransformer class.
|
||||||
|
*
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
* @author Pierre-Yves Lebecq <py.lebecq@gmail.com>
|
||||||
|
*/
|
||||||
|
class ModelsToArrayTransformer implements DataTransformerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Propel\PropelBundle\Form\ChoiceList\ModelChoiceList
|
||||||
|
*/
|
||||||
|
private $choiceList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Propel\PropelBundle\Form\ChoiceList\ModelChoiceList $choiceList
|
||||||
|
*/
|
||||||
|
public function __construct(ModelChoiceList $choiceList)
|
||||||
|
{
|
||||||
|
$this->choiceList = $choiceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function transform($collection)
|
||||||
|
{
|
||||||
|
if (null === $collection) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$collection instanceof PropelCollection) {
|
||||||
|
throw new UnexpectedTypeException($collection, '\PropelCollection');
|
||||||
|
}
|
||||||
|
|
||||||
|
$array = array();
|
||||||
|
|
||||||
|
if (count($this->choiceList->getIdentifier()) > 1) {
|
||||||
|
$availableModels = $this->choiceList->getModels();
|
||||||
|
|
||||||
|
foreach ($collection as $model) {
|
||||||
|
$key = array_search($model, $availableModels);
|
||||||
|
$array[] = $key;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($collection as $model) {
|
||||||
|
$array[] = current($this->choiceList->getIdentifierValues($model));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reverseTransform($keys)
|
||||||
|
{
|
||||||
|
$collection = new PropelObjectCollection();
|
||||||
|
|
||||||
|
if ('' === $keys || null === $keys) {
|
||||||
|
return $collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($keys)) {
|
||||||
|
throw new UnexpectedTypeException($keys, 'array');
|
||||||
|
}
|
||||||
|
|
||||||
|
$notFound = array();
|
||||||
|
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if ($model = $this->choiceList->getModel($key)) {
|
||||||
|
$collection->append($model);
|
||||||
|
} else {
|
||||||
|
$notFound[] = $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($notFound) > 0) {
|
||||||
|
throw new TransformationFailedException(sprintf('The models with keys "%s" could not be found', implode('", "', $notFound)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $collection;
|
||||||
|
}
|
||||||
|
}
|
147
src/Symfony/Bridge/Propel/Form/PropelTypeGuesser.php
Normal file
147
src/Symfony/Bridge/Propel/Form/PropelTypeGuesser.php
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bridge\Propel\Form;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\FormTypeGuesserInterface;
|
||||||
|
use Symfony\Component\Form\Guess\Guess;
|
||||||
|
use Symfony\Component\Form\Guess\TypeGuess;
|
||||||
|
use Symfony\Component\Form\Guess\ValueGuess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Propel Type guesser.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class PropelTypeGuesser implements FormTypeGuesserInterface
|
||||||
|
{
|
||||||
|
private $cache = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function guessType($class, $property)
|
||||||
|
{
|
||||||
|
if (!$table = $this->getTable($class)) {
|
||||||
|
return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($table->getRelations() as $relation) {
|
||||||
|
if (in_array($relation->getType(), array(\RelationMap::MANY_TO_ONE, \RelationMap::ONE_TO_MANY))) {
|
||||||
|
if ($property == $relation->getForeignTable()->getName()) {
|
||||||
|
return new TypeGuess('model', array(
|
||||||
|
'class' => $relation->getForeignTable()->getClassName(),
|
||||||
|
'multiple' => \RelationMap::MANY_TO_ONE === $relation->getType() ? false : true,
|
||||||
|
), Guess::HIGH_CONFIDENCE);
|
||||||
|
}
|
||||||
|
} elseif ($relation->getType() === \RelationMap::MANY_TO_MANY) {
|
||||||
|
if (strtolower($property) == strtolower($relation->getPluralName())) {
|
||||||
|
return new TypeGuess('model', array(
|
||||||
|
'class' => $relation->getLocalTable()->getClassName(),
|
||||||
|
'multiple' => true,
|
||||||
|
), Guess::HIGH_CONFIDENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$column = $this->getColumn($class, $property)) {
|
||||||
|
return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($column->getType()) {
|
||||||
|
case \PropelColumnTypes::BOOLEAN:
|
||||||
|
case \PropelColumnTypes::BOOLEAN_EMU:
|
||||||
|
return new TypeGuess('checkbox', array(), Guess::HIGH_CONFIDENCE);
|
||||||
|
case \PropelColumnTypes::TIMESTAMP:
|
||||||
|
case \PropelColumnTypes::BU_TIMESTAMP:
|
||||||
|
return new TypeGuess('datetime', array(), Guess::HIGH_CONFIDENCE);
|
||||||
|
case \PropelColumnTypes::DATE:
|
||||||
|
case \PropelColumnTypes::BU_DATE:
|
||||||
|
return new TypeGuess('date', array(), Guess::HIGH_CONFIDENCE);
|
||||||
|
case \PropelColumnTypes::TIME:
|
||||||
|
return new TypeGuess('time', array(), Guess::HIGH_CONFIDENCE);
|
||||||
|
case \PropelColumnTypes::FLOAT:
|
||||||
|
case \PropelColumnTypes::REAL:
|
||||||
|
case \PropelColumnTypes::DOUBLE:
|
||||||
|
case \PropelColumnTypes::DECIMAL:
|
||||||
|
return new TypeGuess('number', array(), Guess::MEDIUM_CONFIDENCE);
|
||||||
|
case \PropelColumnTypes::TINYINT:
|
||||||
|
case \PropelColumnTypes::SMALLINT:
|
||||||
|
case \PropelColumnTypes::INTEGER:
|
||||||
|
case \PropelColumnTypes::BIGINT:
|
||||||
|
case \PropelColumnTypes::NUMERIC:
|
||||||
|
return new TypeGuess('integer', array(), Guess::MEDIUM_CONFIDENCE);
|
||||||
|
case \PropelColumnTypes::CHAR:
|
||||||
|
case \PropelColumnTypes::VARCHAR:
|
||||||
|
return new TypeGuess('text', array(), Guess::MEDIUM_CONFIDENCE);
|
||||||
|
case \PropelColumnTypes::LONGVARCHAR:
|
||||||
|
case \PropelColumnTypes::BLOB:
|
||||||
|
case \PropelColumnTypes::CLOB:
|
||||||
|
case \PropelColumnTypes::CLOB_EMU:
|
||||||
|
return new TypeGuess('textarea', array(), Guess::MEDIUM_CONFIDENCE);
|
||||||
|
default:
|
||||||
|
return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function guessRequired($class, $property)
|
||||||
|
{
|
||||||
|
if ($column = $this->getColumn($class, $property)) {
|
||||||
|
return new ValueGuess($column->isNotNull(), Guess::HIGH_CONFIDENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function guessMaxLength($class, $property)
|
||||||
|
{
|
||||||
|
if (($column = $this->getColumn($class, $property)) && $column->isText()) {
|
||||||
|
return new ValueGuess($column->getSize(), Guess::HIGH_CONFIDENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function guessMinLength($class, $property)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTable($class)
|
||||||
|
{
|
||||||
|
if (isset($this->cache[$class])) {
|
||||||
|
return $this->cache[$class];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (class_exists($queryClass = $class.'Query')) {
|
||||||
|
$query = new $queryClass();
|
||||||
|
|
||||||
|
return $this->cache[$class] = $query->getTableMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getColumn($class, $property)
|
||||||
|
{
|
||||||
|
if (isset($this->cache[$class.'::'.$property])) {
|
||||||
|
return $this->cache[$class.'::'.$property];
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = $this->getTable($class);
|
||||||
|
|
||||||
|
if ($table && $table->hasColumn($property)) {
|
||||||
|
return $this->cache[$class.'::'.$property] = $table->getColumn($property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
73
src/Symfony/Bridge/Propel/Form/Type/ModelType.php
Normal file
73
src/Symfony/Bridge/Propel/Form/Type/ModelType.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bridge\Propel\Form\Type;
|
||||||
|
|
||||||
|
use Symfony\Bridge\Propel\Form\ChoiceList\ModelChoiceList;
|
||||||
|
use Symfony\Bridge\Propel\Form\DataTransformer\ModelToIdTransformer;
|
||||||
|
use Symfony\Bridge\Propel\Form\DataTransformer\ModelsToArrayTransformer;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilder;
|
||||||
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ModelType class.
|
||||||
|
*
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
*/
|
||||||
|
class ModelType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilder $builder, array $options)
|
||||||
|
{
|
||||||
|
if ($options['multiple']) {
|
||||||
|
$builder->prependClientTransformer(new ModelsToArrayTransformer($options['choice_list']));
|
||||||
|
} else {
|
||||||
|
$builder->prependClientTransformer(new ModelToIdTransformer($options['choice_list']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultOptions(array $options)
|
||||||
|
{
|
||||||
|
$defaultOptions = array(
|
||||||
|
'template' => 'choice',
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => false,
|
||||||
|
'class' => null,
|
||||||
|
'property' => null,
|
||||||
|
'query' => null,
|
||||||
|
'choices' => array(),
|
||||||
|
'preferred_choices' => array(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$options = array_replace($defaultOptions, $options);
|
||||||
|
|
||||||
|
if (!isset($options['choice_list'])) {
|
||||||
|
$defaultOptions['choice_list'] = new ModelChoiceList(
|
||||||
|
$options['class'],
|
||||||
|
$options['property'],
|
||||||
|
$options['choices'],
|
||||||
|
$options['query']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $defaultOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent(array $options)
|
||||||
|
{
|
||||||
|
return 'choice';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'propel_model';
|
||||||
|
}
|
||||||
|
}
|
139
src/Symfony/Bridge/Propel/Logger/PropelLogger.php
Normal file
139
src/Symfony/Bridge/Propel/Logger/PropelLogger.php
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bridge\Propel\Logger;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PropelLogger.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
*/
|
||||||
|
class PropelLogger
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $queries;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param LoggerInterface $logger A LoggerInterface instance
|
||||||
|
*/
|
||||||
|
public function __construct(LoggerInterface $logger = null)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->queries = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience function for logging an alert event.
|
||||||
|
*
|
||||||
|
* @param mixed $message the message to log.
|
||||||
|
*/
|
||||||
|
public function alert($message)
|
||||||
|
{
|
||||||
|
if (null !== $this->logger) {
|
||||||
|
$this->logger->alert($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience function for logging a critical event.
|
||||||
|
*
|
||||||
|
* @param mixed $message the message to log.
|
||||||
|
*/
|
||||||
|
public function crit($message)
|
||||||
|
{
|
||||||
|
if (null !== $this->logger) {
|
||||||
|
$this->logger->crit($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience function for logging an error event.
|
||||||
|
*
|
||||||
|
* @param mixed $message the message to log.
|
||||||
|
*/
|
||||||
|
public function err($message)
|
||||||
|
{
|
||||||
|
if (null !== $this->logger) {
|
||||||
|
$this->logger->err($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience function for logging a warning event.
|
||||||
|
*
|
||||||
|
* @param mixed $message the message to log.
|
||||||
|
*/
|
||||||
|
public function warning($message)
|
||||||
|
{
|
||||||
|
if (null !== $this->logger) {
|
||||||
|
$this->logger->warn($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience function for logging an critical event.
|
||||||
|
*
|
||||||
|
* @param mixed $message the message to log.
|
||||||
|
*/
|
||||||
|
public function notice($message)
|
||||||
|
{
|
||||||
|
if (null !== $this->logger) {
|
||||||
|
$this->logger->notice($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience function for logging an critical event.
|
||||||
|
*
|
||||||
|
* @param mixed $message the message to log.
|
||||||
|
*/
|
||||||
|
public function info($message)
|
||||||
|
{
|
||||||
|
if (null !== $this->logger) {
|
||||||
|
$this->logger->info($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience function for logging a debug event.
|
||||||
|
*
|
||||||
|
* @param mixed $message the message to log.
|
||||||
|
*/
|
||||||
|
public function debug($message)
|
||||||
|
{
|
||||||
|
$this->queries[] = $message;
|
||||||
|
if (null !== $this->logger) {
|
||||||
|
$this->logger->debug($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns queries.
|
||||||
|
*
|
||||||
|
* @return array Queries
|
||||||
|
*/
|
||||||
|
public function getQueries()
|
||||||
|
{
|
||||||
|
return $this->queries;
|
||||||
|
}
|
||||||
|
}
|
4
src/Symfony/Bridge/Propel/README.md
Normal file
4
src/Symfony/Bridge/Propel/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Propel Bridge
|
||||||
|
=============
|
||||||
|
|
||||||
|
Provides integration for Propel with various Symfony2 components.
|
Reference in New Issue
Block a user