integrate former Symfony Propel1 bridge
This commit is contained in:
parent
bde72e0ee6
commit
38b491aa46
147
DataCollector/PropelDataCollector.php
Normal file
147
DataCollector/PropelDataCollector.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 Propel\PropelBundle\DataCollector;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\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 PropelLogger
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Propel configuration.
|
||||||
|
*
|
||||||
|
* @var \PropelConfiguration
|
||||||
|
*/
|
||||||
|
protected $propelConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param 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
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'propel';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the collected stats for all executed SQL queries.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getQueries()
|
||||||
|
{
|
||||||
|
return $this->data['queries'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the query count.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getQueryCount()
|
||||||
|
{
|
||||||
|
return $this->data['querycount'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the total time spent on running all queries.
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function getTime()
|
||||||
|
{
|
||||||
|
$time = 0;
|
||||||
|
foreach ($this->data['queries'] as $query) {
|
||||||
|
$time += (float) $query['time'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the stats of all executed SQL queries.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
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, 4);
|
||||||
|
|
||||||
|
$times = explode($innerGlue, $parts[0]);
|
||||||
|
$con = explode($innerGlue, $parts[2]);
|
||||||
|
$memories = explode($innerGlue, $parts[1]);
|
||||||
|
|
||||||
|
$sql = trim($parts[3]);
|
||||||
|
$con = trim($con[1]);
|
||||||
|
$time = trim($times[1]);
|
||||||
|
$memory = trim($memories[1]);
|
||||||
|
|
||||||
|
$queries[] = array('connection' => $con, 'sql' => $sql, 'time' => $time, 'memory' => $memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $queries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the total count of SQL queries.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function countQueries()
|
||||||
|
{
|
||||||
|
return count($this->logger->getQueries());
|
||||||
|
}
|
||||||
|
}
|
69
DependencyInjection/Security/UserProvider/PropelFactory.php
Normal file
69
DependencyInjection/Security/UserProvider/PropelFactory.php
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?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 Propel\PropelBundle\DependencyInjection\Security\UserProvider;
|
||||||
|
|
||||||
|
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface;
|
||||||
|
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PropelFactory creates services for Propel user provider.
|
||||||
|
*
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
*/
|
||||||
|
class PropelFactory implements UserProviderFactoryInterface
|
||||||
|
{
|
||||||
|
private $key;
|
||||||
|
private $providerId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param string $providerId
|
||||||
|
*/
|
||||||
|
public function __construct($key, $providerId)
|
||||||
|
{
|
||||||
|
$this->key = $key;
|
||||||
|
$this->providerId = $providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(ContainerBuilder $container, $id, $config)
|
||||||
|
{
|
||||||
|
$container
|
||||||
|
->setDefinition($id, new DefinitionDecorator($this->providerId))
|
||||||
|
->addArgument($config['class'])
|
||||||
|
->addArgument($config['property'])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKey()
|
||||||
|
{
|
||||||
|
return $this->key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addConfiguration(NodeDefinition $node)
|
||||||
|
{
|
||||||
|
$node
|
||||||
|
->children()
|
||||||
|
->scalarNode('class')
|
||||||
|
->isRequired()
|
||||||
|
->cannotBeEmpty()
|
||||||
|
->end()
|
||||||
|
->scalarNode('property')
|
||||||
|
->defaultNull()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
512
Form/ChoiceList/ModelChoiceList.php
Normal file
512
Form/ChoiceList/ModelChoiceList.php
Normal file
|
@ -0,0 +1,512 @@
|
||||||
|
<?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 Propel\PropelBundle\Form\ChoiceList;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\Form\Type\ModelType;
|
||||||
|
use Symfony\Component\Form\Exception\StringCastException;
|
||||||
|
use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList;
|
||||||
|
use Symfony\Component\Form\Extension\Core\DataTransformer\ChoicesToValuesTransformer;
|
||||||
|
use Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer;
|
||||||
|
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
|
||||||
|
use Symfony\Component\OptionsResolver\Exception\MissingOptionsException;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A choice list for object choices based on Propel model.
|
||||||
|
*
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
* @author Toni Uebernickel <tuebernickel@gmail.com>
|
||||||
|
*/
|
||||||
|
class ModelChoiceList extends ObjectChoiceList
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The fields of which the identifier of the underlying class consists.
|
||||||
|
*
|
||||||
|
* This property should only be accessed through identifier.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $identifier = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The query to retrieve the choices of this list.
|
||||||
|
*
|
||||||
|
* @var \ModelCriteria
|
||||||
|
*/
|
||||||
|
protected $query;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The query to retrieve the preferred choices for this list.
|
||||||
|
*
|
||||||
|
* @var \ModelCriteria
|
||||||
|
*/
|
||||||
|
protected $preferredQuery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the model objects have already been loaded.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $loaded = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to use the identifier for index generation.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $identifierAsIndex = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @see ModelType How to use the preferred choices.
|
||||||
|
*
|
||||||
|
* @param string $class The FQCN of the model class to be loaded.
|
||||||
|
* @param string $labelPath A property path pointing to the property used for the choice labels.
|
||||||
|
* @param array $choices An optional array to use, rather than fetching the models.
|
||||||
|
* @param \ModelCriteria $queryObject The query to use retrieving model data from database.
|
||||||
|
* @param string $groupPath A property path pointing to the property used to group the choices.
|
||||||
|
* @param array|\ModelCriteria $preferred The preferred items of this choice.
|
||||||
|
* Either an array if $choices is given,
|
||||||
|
* or a \ModelCriteria to be merged with the $queryObject.
|
||||||
|
* @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths.
|
||||||
|
* @param string $useAsIdentifier a custom unique column (eg slug) to use instead of primary key.
|
||||||
|
*
|
||||||
|
* @throws MissingOptionsException In case the class parameter is empty.
|
||||||
|
* @throws InvalidOptionsException In case the query class is not found.
|
||||||
|
*/
|
||||||
|
public function __construct($class, $labelPath = null, $choices = null, $queryObject = null, $groupPath = null, $preferred = array(), PropertyAccessorInterface $propertyAccessor = null, $useAsIdentifier = null)
|
||||||
|
{
|
||||||
|
$this->class = $class;
|
||||||
|
|
||||||
|
$queryClass = $this->class.'Query';
|
||||||
|
if (!class_exists($queryClass)) {
|
||||||
|
if (empty($this->class)) {
|
||||||
|
throw new MissingOptionsException('The "class" parameter is empty, you should provide the model class');
|
||||||
|
}
|
||||||
|
throw new InvalidOptionsException(sprintf('The query class "%s" is not found, you should provide the FQCN of the model class', $queryClass));
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = new $queryClass();
|
||||||
|
|
||||||
|
$this->query = $queryObject ?: $query;
|
||||||
|
if ($useAsIdentifier) {
|
||||||
|
$this->identifier = array($this->query->getTableMap()->getColumn($useAsIdentifier));
|
||||||
|
} else {
|
||||||
|
$this->identifier = $this->query->getTableMap()->getPrimaryKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->loaded = is_array($choices) || $choices instanceof \Traversable;
|
||||||
|
|
||||||
|
if ($preferred instanceof \ModelCriteria) {
|
||||||
|
$this->preferredQuery = $preferred->mergeWith($this->query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->loaded) {
|
||||||
|
// Make sure the constraints of the parent constructor are
|
||||||
|
// fulfilled
|
||||||
|
$choices = array();
|
||||||
|
$preferred = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1 === count($this->identifier) && $this->isScalar(current($this->identifier))) {
|
||||||
|
$this->identifierAsIndex = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($choices, $labelPath, $preferred, $groupPath, null, $propertyAccessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the class name of the model.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getClass()
|
||||||
|
{
|
||||||
|
return $this->class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getChoices()
|
||||||
|
{
|
||||||
|
$this->load();
|
||||||
|
|
||||||
|
return parent::getChoices();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getValues()
|
||||||
|
{
|
||||||
|
$this->load();
|
||||||
|
|
||||||
|
return parent::getValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getPreferredViews()
|
||||||
|
{
|
||||||
|
$this->load();
|
||||||
|
|
||||||
|
return parent::getPreferredViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getRemainingViews()
|
||||||
|
{
|
||||||
|
$this->load();
|
||||||
|
|
||||||
|
return parent::getRemainingViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getChoicesForValues(array $values)
|
||||||
|
{
|
||||||
|
if (empty($values)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This performance optimization reflects a common scenario:
|
||||||
|
* * A simple select of a model entry.
|
||||||
|
* * The choice option "expanded" is set to false.
|
||||||
|
* * The current request is the submission of the selected value.
|
||||||
|
*
|
||||||
|
* @see ChoicesToValuesTransformer::reverseTransform()
|
||||||
|
* @see ChoiceToValueTransformer::reverseTransform()
|
||||||
|
*/
|
||||||
|
if (!$this->loaded) {
|
||||||
|
if (1 === count($this->identifier)) {
|
||||||
|
$filterBy = 'filterBy'.current($this->identifier)->getPhpName();
|
||||||
|
|
||||||
|
// The initial query is cloned, so all additional filters are applied correctly.
|
||||||
|
$query = clone $this->query;
|
||||||
|
$result = (array) $query
|
||||||
|
->$filterBy($values)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
// Preserve the keys as provided by the values.
|
||||||
|
$models = array();
|
||||||
|
foreach ($values as $index => $value) {
|
||||||
|
foreach ($result as $eachModel) {
|
||||||
|
if ($value === $this->createValue($eachModel)) {
|
||||||
|
// Make sure to convert to the right format
|
||||||
|
$models[$index] = $this->fixChoice($eachModel);
|
||||||
|
|
||||||
|
// If all values have been assigned, skip further loops.
|
||||||
|
unset($values[$index]);
|
||||||
|
if (0 === count($values)) {
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $models;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->load();
|
||||||
|
|
||||||
|
return parent::getChoicesForValues($values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getValuesForChoices(array $models)
|
||||||
|
{
|
||||||
|
if (empty($models)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->loaded) {
|
||||||
|
/*
|
||||||
|
* This performance optimization assumes the validation of the respective values will be done by other means.
|
||||||
|
*
|
||||||
|
* It correlates with the performance optimization in {@link ModelChoiceList::getChoicesForValues()}
|
||||||
|
* as it won't load the actual entries from the database.
|
||||||
|
*
|
||||||
|
* @see ChoicesToValuesTransformer::transform()
|
||||||
|
* @see ChoiceToValueTransformer::transform()
|
||||||
|
*/
|
||||||
|
if (1 === count($this->identifier)) {
|
||||||
|
$values = array();
|
||||||
|
foreach ($models as $index => $model) {
|
||||||
|
if ($model instanceof $this->class) {
|
||||||
|
// Make sure to convert to the right format
|
||||||
|
$values[$index] = $this->fixValue(current($this->getIdentifierValues($model)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->load();
|
||||||
|
|
||||||
|
$values = array();
|
||||||
|
$availableValues = $this->getValues();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Overwriting default implementation.
|
||||||
|
*
|
||||||
|
* The two objects may represent the same entry in the database,
|
||||||
|
* but if they originated from different queries, there are not the same object within the code.
|
||||||
|
*
|
||||||
|
* This happens when using m:n relations with either sides model as data_class of the form.
|
||||||
|
* The choicelist will retrieve the list of available related models with a different query, resulting in different objects.
|
||||||
|
*/
|
||||||
|
$choices = $this->fixChoices($models);
|
||||||
|
foreach ($choices as $i => $givenChoice) {
|
||||||
|
if (null === $givenChoice) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->getChoices() as $j => $choice) {
|
||||||
|
if ($this->isEqual($choice, $givenChoice)) {
|
||||||
|
$values[$i] = $availableValues[$j];
|
||||||
|
|
||||||
|
// If all choices have been assigned, skip further loops.
|
||||||
|
unset($choices[$i]);
|
||||||
|
if (0 === count($choices)) {
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.4, to be removed in 3.0.
|
||||||
|
*/
|
||||||
|
public function getIndicesForChoices(array $models)
|
||||||
|
{
|
||||||
|
trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
if (empty($models)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->load();
|
||||||
|
|
||||||
|
$indices = array();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Overwriting default implementation.
|
||||||
|
*
|
||||||
|
* The two objects may represent the same entry in the database,
|
||||||
|
* but if they originated from different queries, there are not the same object within the code.
|
||||||
|
*
|
||||||
|
* This happens when using m:n relations with either sides model as data_class of the form.
|
||||||
|
* The choice list will retrieve the list of available related models with a different query, resulting in different objects.
|
||||||
|
*/
|
||||||
|
$choices = $this->fixChoices($models);
|
||||||
|
foreach ($choices as $i => $givenChoice) {
|
||||||
|
if (null === $givenChoice) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->getChoices() as $j => $choice) {
|
||||||
|
if ($this->isEqual($choice, $givenChoice)) {
|
||||||
|
$indices[$i] = $j;
|
||||||
|
|
||||||
|
// If all choices have been assigned, skip further loops.
|
||||||
|
unset($choices[$i]);
|
||||||
|
if (0 === count($choices)) {
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @deprecated since version 2.4, to be removed in 3.0.
|
||||||
|
*/
|
||||||
|
public function getIndicesForValues(array $values)
|
||||||
|
{
|
||||||
|
trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
if (empty($values)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->load();
|
||||||
|
|
||||||
|
return parent::getIndicesForValues($values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new unique index for this model.
|
||||||
|
*
|
||||||
|
* If the model has a single-field identifier, this identifier is used.
|
||||||
|
*
|
||||||
|
* Otherwise a new integer is generated.
|
||||||
|
*
|
||||||
|
* @param mixed $model The choice to create an index for
|
||||||
|
*
|
||||||
|
* @return int|string A unique index containing only ASCII letters,
|
||||||
|
* digits and underscores.
|
||||||
|
*/
|
||||||
|
protected function createIndex($model)
|
||||||
|
{
|
||||||
|
if ($this->identifierAsIndex) {
|
||||||
|
return current($this->getIdentifierValues($model));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::createIndex($model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new unique value for this model.
|
||||||
|
*
|
||||||
|
* If the model has a single-field identifier, this identifier is used.
|
||||||
|
*
|
||||||
|
* Otherwise a new integer is generated.
|
||||||
|
*
|
||||||
|
* @param mixed $model The choice to create a value for
|
||||||
|
*
|
||||||
|
* @return int|string A unique value without character limitations.
|
||||||
|
*/
|
||||||
|
protected function createValue($model)
|
||||||
|
{
|
||||||
|
if ($this->identifierAsIndex) {
|
||||||
|
return (string) current($this->getIdentifierValues($model));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::createValue($model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the complete choice list entries, once.
|
||||||
|
*
|
||||||
|
* If data has been loaded the choice list is initialized with the retrieved data.
|
||||||
|
*/
|
||||||
|
private function load()
|
||||||
|
{
|
||||||
|
if ($this->loaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$models = (array) $this->query->find();
|
||||||
|
|
||||||
|
$preferred = array();
|
||||||
|
if ($this->preferredQuery instanceof \ModelCriteria) {
|
||||||
|
$preferred = (array) $this->preferredQuery->find();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// The second parameter $labels is ignored by ObjectChoiceList
|
||||||
|
parent::initialize($models, array(), $preferred);
|
||||||
|
|
||||||
|
$this->loaded = true;
|
||||||
|
} catch (StringCastException $e) {
|
||||||
|
throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the values of the identifier fields of a 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
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getIdentifierValues($model)
|
||||||
|
{
|
||||||
|
if (!$model instanceof $this->class) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1 === count($this->identifier) && current($this->identifier) instanceof \ColumnMap) {
|
||||||
|
$phpName = current($this->identifier)->getPhpName();
|
||||||
|
|
||||||
|
if (method_exists($model, 'get'.$phpName)) {
|
||||||
|
return array($model->{'get'.$phpName}());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($model instanceof \Persistent) {
|
||||||
|
return array($model->getPrimaryKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
// readonly="true" models do not implement \Persistent.
|
||||||
|
if ($model instanceof \BaseObject && method_exists($model, 'getPrimaryKey')) {
|
||||||
|
return array($model->getPrimaryKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!method_exists($model, 'getPrimaryKeys')) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model->getPrimaryKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this column contains scalar values (to be used as indices).
|
||||||
|
*
|
||||||
|
* @param \ColumnMap $column
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isScalar(\ColumnMap $column)
|
||||||
|
{
|
||||||
|
return in_array($column->getPdoType(), array(
|
||||||
|
\PDO::PARAM_BOOL,
|
||||||
|
\PDO::PARAM_INT,
|
||||||
|
\PDO::PARAM_STR,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the given choices for equality.
|
||||||
|
*
|
||||||
|
* @param mixed $choice
|
||||||
|
* @param mixed $givenChoice
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isEqual($choice, $givenChoice)
|
||||||
|
{
|
||||||
|
if ($choice === $givenChoice) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getIdentifierValues($choice) === $this->getIdentifierValues($givenChoice)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
55
Form/DataTransformer/CollectionToArrayTransformer.php
Normal file
55
Form/DataTransformer/CollectionToArrayTransformer.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?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 Propel\PropelBundle\Form\DataTransformer;
|
||||||
|
|
||||||
|
use PropelObjectCollection;
|
||||||
|
use Symfony\Component\Form\DataTransformerInterface;
|
||||||
|
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CollectionToArrayTransformer class.
|
||||||
|
*
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
* @author Pierre-Yves Lebecq <py.lebecq@gmail.com>
|
||||||
|
*/
|
||||||
|
class CollectionToArrayTransformer implements DataTransformerInterface
|
||||||
|
{
|
||||||
|
public function transform($collection)
|
||||||
|
{
|
||||||
|
if (null === $collection) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$collection instanceof PropelObjectCollection) {
|
||||||
|
throw new TransformationFailedException('Expected a \PropelObjectCollection.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $collection->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reverseTransform($array)
|
||||||
|
{
|
||||||
|
$collection = new PropelObjectCollection();
|
||||||
|
|
||||||
|
if ('' === $array || null === $array) {
|
||||||
|
return $collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($array)) {
|
||||||
|
throw new TransformationFailedException('Expected an array.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$collection->setData($array);
|
||||||
|
|
||||||
|
return $collection;
|
||||||
|
}
|
||||||
|
}
|
102
Form/EventListener/TranslationCollectionFormListener.php
Normal file
102
Form/EventListener/TranslationCollectionFormListener.php
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
<?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 Propel\PropelBundle\Form\EventListener;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||||
|
use Symfony\Component\Form\FormEvent;
|
||||||
|
use Symfony\Component\Form\FormEvents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* listener class for propel1_translatable_collection.
|
||||||
|
*
|
||||||
|
* @author Patrick Kaufmann
|
||||||
|
*/
|
||||||
|
class TranslationCollectionFormListener implements EventSubscriberInterface
|
||||||
|
{
|
||||||
|
private $i18nClass;
|
||||||
|
private $languages;
|
||||||
|
|
||||||
|
public function __construct($languages, $i18nClass)
|
||||||
|
{
|
||||||
|
$this->i18nClass = $i18nClass;
|
||||||
|
$this->languages = $languages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getSubscribedEvents()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
FormEvents::PRE_SET_DATA => array('preSetData', 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function preSetData(FormEvent $event)
|
||||||
|
{
|
||||||
|
$form = $event->getForm();
|
||||||
|
$data = $event->getData();
|
||||||
|
|
||||||
|
if (null === $data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($data) && !($data instanceof \Traversable && $data instanceof \ArrayAccess)) {
|
||||||
|
throw new UnexpectedTypeException($data, 'array or (\Traversable and \ArrayAccess)');
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the class name of the i18nClass
|
||||||
|
$temp = explode('\\', $this->i18nClass);
|
||||||
|
$dataClass = end($temp);
|
||||||
|
|
||||||
|
$rootData = $form->getRoot()->getData();
|
||||||
|
$foundData = false;
|
||||||
|
|
||||||
|
$addFunction = 'add'.$dataClass;
|
||||||
|
|
||||||
|
//add a database row for every needed language
|
||||||
|
foreach ($this->languages as $lang) {
|
||||||
|
$found = false;
|
||||||
|
|
||||||
|
foreach ($data as $i18n) {
|
||||||
|
if (!method_exists($i18n, 'getLocale')) {
|
||||||
|
throw new UnexpectedTypeException($i18n, 'Propel i18n object');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($i18n->getLocale() == $lang) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$found) {
|
||||||
|
$currentForm = $form;
|
||||||
|
while (!$foundData) {
|
||||||
|
if (method_exists($rootData, $addFunction)) {
|
||||||
|
$foundData = true;
|
||||||
|
break;
|
||||||
|
} elseif ($currentForm->hasParent()) {
|
||||||
|
$currentForm = $currentForm->getParent();
|
||||||
|
$rootData = $currentForm->getData();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$foundData) {
|
||||||
|
throw new UnexpectedTypeException($rootData, 'Propel i18n object');
|
||||||
|
}
|
||||||
|
|
||||||
|
$newTranslation = new $this->i18nClass();
|
||||||
|
$newTranslation->setLocale($lang);
|
||||||
|
|
||||||
|
$rootData->$addFunction($newTranslation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
81
Form/EventListener/TranslationFormListener.php
Normal file
81
Form/EventListener/TranslationFormListener.php
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<?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 Propel\PropelBundle\Form\EventListener;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Form\FormEvent;
|
||||||
|
use Symfony\Component\Form\FormEvents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event Listener class for propel1_translation.
|
||||||
|
*
|
||||||
|
* @author Patrick Kaufmann
|
||||||
|
*/
|
||||||
|
class TranslationFormListener implements EventSubscriberInterface
|
||||||
|
{
|
||||||
|
private $columns;
|
||||||
|
private $dataClass;
|
||||||
|
|
||||||
|
public function __construct($columns, $dataClass)
|
||||||
|
{
|
||||||
|
$this->columns = $columns;
|
||||||
|
$this->dataClass = $dataClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getSubscribedEvents()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
FormEvents::PRE_SET_DATA => array('preSetData', 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function preSetData(FormEvent $event)
|
||||||
|
{
|
||||||
|
$form = $event->getForm();
|
||||||
|
$data = $event->getData();
|
||||||
|
|
||||||
|
if (!$data instanceof $this->dataClass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//loop over all columns and add the input
|
||||||
|
foreach ($this->columns as $column => $options) {
|
||||||
|
if (is_string($options)) {
|
||||||
|
$column = $options;
|
||||||
|
$options = array();
|
||||||
|
}
|
||||||
|
if (null === $options) {
|
||||||
|
$options = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = 'text';
|
||||||
|
if (array_key_exists('type', $options)) {
|
||||||
|
$type = $options['type'];
|
||||||
|
}
|
||||||
|
$label = $column;
|
||||||
|
if (array_key_exists('label', $options)) {
|
||||||
|
$label = $options['label'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$customOptions = array();
|
||||||
|
if (array_key_exists('options', $options)) {
|
||||||
|
$customOptions = $options['options'];
|
||||||
|
}
|
||||||
|
$options = array(
|
||||||
|
'label' => $label.' '.strtoupper($data->getLocale()),
|
||||||
|
);
|
||||||
|
|
||||||
|
$options = array_merge($options, $customOptions);
|
||||||
|
|
||||||
|
$form->add($column, $type, $options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
Form/PropelExtension.php
Normal file
37
Form/PropelExtension.php
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?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 Propel\PropelBundle\Form;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractExtension;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the Propel form extension, which loads the Propel functionality.
|
||||||
|
*
|
||||||
|
* @author Joseph Rouff <rouffj@gmail.com>
|
||||||
|
*/
|
||||||
|
class PropelExtension extends AbstractExtension
|
||||||
|
{
|
||||||
|
protected function loadTypes()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
new Type\ModelType(PropertyAccess::createPropertyAccessor()),
|
||||||
|
new Type\TranslationCollectionType(),
|
||||||
|
new Type\TranslationType(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadTypeGuesser()
|
||||||
|
{
|
||||||
|
return new PropelTypeGuesser();
|
||||||
|
}
|
||||||
|
}
|
184
Form/PropelTypeGuesser.php
Normal file
184
Form/PropelTypeGuesser.php
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
<?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 Propel\PropelBundle\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 ($relation->getType() === \RelationMap::MANY_TO_ONE) {
|
||||||
|
if (strtolower($property) === strtolower($relation->getName())) {
|
||||||
|
return new TypeGuess('model', array(
|
||||||
|
'class' => $relation->getForeignTable()->getClassName(),
|
||||||
|
'multiple' => false,
|
||||||
|
), Guess::HIGH_CONFIDENCE);
|
||||||
|
}
|
||||||
|
} elseif ($relation->getType() === \RelationMap::ONE_TO_MANY) {
|
||||||
|
if (strtolower($property) === strtolower($relation->getPluralName())) {
|
||||||
|
return new TypeGuess('model', array(
|
||||||
|
'class' => $relation->getForeignTable()->getClassName(),
|
||||||
|
'multiple' => 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::ENUM:
|
||||||
|
case \PropelColumnTypes::CHAR:
|
||||||
|
if ($column->getValueSet()) {
|
||||||
|
//check if this is mysql enum
|
||||||
|
$choices = $column->getValueSet();
|
||||||
|
$labels = array_map('ucfirst', $choices);
|
||||||
|
|
||||||
|
return new TypeGuess('choice', array('choices' => array_combine($choices, $labels)), Guess::MEDIUM_CONFIDENCE);
|
||||||
|
}
|
||||||
|
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)) {
|
||||||
|
if ($column->isText()) {
|
||||||
|
return new ValueGuess($column->getSize(), Guess::HIGH_CONFIDENCE);
|
||||||
|
}
|
||||||
|
switch ($column->getType()) {
|
||||||
|
case \PropelColumnTypes::FLOAT:
|
||||||
|
case \PropelColumnTypes::REAL:
|
||||||
|
case \PropelColumnTypes::DOUBLE:
|
||||||
|
case \PropelColumnTypes::DECIMAL:
|
||||||
|
return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function guessPattern($class, $property)
|
||||||
|
{
|
||||||
|
if ($column = $this->getColumn($class, $property)) {
|
||||||
|
switch ($column->getType()) {
|
||||||
|
case \PropelColumnTypes::FLOAT:
|
||||||
|
case \PropelColumnTypes::REAL:
|
||||||
|
case \PropelColumnTypes::DOUBLE:
|
||||||
|
case \PropelColumnTypes::DECIMAL:
|
||||||
|
return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($table && $table->hasColumnByInsensitiveCase($property)) {
|
||||||
|
return $this->cache[$class.'::'.$property] = $table->getColumnByInsensitiveCase($property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
128
Form/Type/ModelType.php
Normal file
128
Form/Type/ModelType.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 Propel\PropelBundle\Form\Type;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\Form\ChoiceList\ModelChoiceList;
|
||||||
|
use Propel\PropelBundle\Form\DataTransformer\CollectionToArrayTransformer;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccess;
|
||||||
|
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ModelType class.
|
||||||
|
*
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
* @author Toni Uebernickel <tuebernickel@gmail.com>
|
||||||
|
*
|
||||||
|
* Example using the preferred_choices option.
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
* {
|
||||||
|
* $builder
|
||||||
|
* ->add('product', 'model', array(
|
||||||
|
* 'class' => 'Model\Product',
|
||||||
|
* 'query' => ProductQuery::create()
|
||||||
|
* ->filterIsActive(true)
|
||||||
|
* ->useI18nQuery($options['locale'])
|
||||||
|
* ->orderByName()
|
||||||
|
* ->endUse()
|
||||||
|
* ,
|
||||||
|
* 'preferred_choices' => ProductQuery::create()
|
||||||
|
* ->filterByIsTopProduct(true)
|
||||||
|
* ,
|
||||||
|
* ))
|
||||||
|
* ;
|
||||||
|
* }
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
class ModelType extends AbstractType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PropertyAccessorInterface
|
||||||
|
*/
|
||||||
|
private $propertyAccessor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param PropertyAccessorInterface|null $propertyAccessor
|
||||||
|
*/
|
||||||
|
public function __construct(PropertyAccessorInterface $propertyAccessor = null)
|
||||||
|
{
|
||||||
|
$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
if ($options['multiple']) {
|
||||||
|
$builder->addViewTransformer(new CollectionToArrayTransformer(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$propertyAccessor = $this->propertyAccessor;
|
||||||
|
|
||||||
|
$choiceList = function (Options $options) use ($propertyAccessor) {
|
||||||
|
return new ModelChoiceList(
|
||||||
|
$options['class'],
|
||||||
|
$options['property'],
|
||||||
|
$options['choices'],
|
||||||
|
$options['query'],
|
||||||
|
$options['group_by'],
|
||||||
|
$options['preferred_choices'],
|
||||||
|
$propertyAccessor,
|
||||||
|
$options['index_property']
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$resolver->setDefaults(array(
|
||||||
|
'template' => 'choice',
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => false,
|
||||||
|
'class' => null,
|
||||||
|
'property' => null,
|
||||||
|
'query' => null,
|
||||||
|
'choices' => null,
|
||||||
|
'choice_list' => $choiceList,
|
||||||
|
'group_by' => null,
|
||||||
|
'by_reference' => false,
|
||||||
|
'index_property' => null,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return 'choice';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'model';
|
||||||
|
}
|
||||||
|
}
|
78
Form/Type/TranslationCollectionType.php
Normal file
78
Form/Type/TranslationCollectionType.php
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<?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 Propel\PropelBundle\Form\Type;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\Form\EventListener\TranslationCollectionFormListener;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\Exception\MissingOptionsException;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* form type for i18n-columns in propel.
|
||||||
|
*
|
||||||
|
* @author Patrick Kaufmann
|
||||||
|
*/
|
||||||
|
class TranslationCollectionType extends AbstractType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
if (!isset($options['options']['data_class']) || null === $options['options']['data_class']) {
|
||||||
|
throw new MissingOptionsException('data_class must be set');
|
||||||
|
}
|
||||||
|
if (!isset($options['options']['columns']) || null === $options['options']['columns']) {
|
||||||
|
throw new MissingOptionsException('columns must be set');
|
||||||
|
}
|
||||||
|
|
||||||
|
$listener = new TranslationCollectionFormListener($options['languages'], $options['options']['data_class']);
|
||||||
|
$builder->addEventSubscriber($listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return 'collection';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'propel1_translation_collection';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setRequired(array(
|
||||||
|
'languages',
|
||||||
|
));
|
||||||
|
|
||||||
|
$resolver->setDefaults(array(
|
||||||
|
'type' => 'propel1_translation',
|
||||||
|
'allow_add' => false,
|
||||||
|
'allow_delete' => false,
|
||||||
|
'options' => array(
|
||||||
|
'data_class' => null,
|
||||||
|
'columns' => null,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
54
Form/Type/TranslationType.php
Normal file
54
Form/Type/TranslationType.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?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 Propel\PropelBundle\Form\Type;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\Form\EventListener\TranslationFormListener;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translation type class.
|
||||||
|
*
|
||||||
|
* @author Patrick Kaufmann
|
||||||
|
*/
|
||||||
|
class TranslationType extends AbstractType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->addEventSubscriber(
|
||||||
|
new TranslationFormListener($options['columns'], $options['data_class'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'propel1_translation';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setRequired(array(
|
||||||
|
'data_class',
|
||||||
|
'columns',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
177
Logger/PropelLogger.php
Normal file
177
Logger/PropelLogger.php
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
<?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 Propel\PropelBundle\Logger;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\Stopwatch\Stopwatch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PropelLogger.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||||
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
*/
|
||||||
|
class PropelLogger implements \BasicLogger
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $queries = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Stopwatch
|
||||||
|
*/
|
||||||
|
protected $stopwatch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $isPrepared = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param LoggerInterface $logger A LoggerInterface instance
|
||||||
|
* @param Stopwatch $stopwatch A Stopwatch instance
|
||||||
|
*/
|
||||||
|
public function __construct(LoggerInterface $logger = null, Stopwatch $stopwatch = null)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->stopwatch = $stopwatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function alert($message)
|
||||||
|
{
|
||||||
|
$this->log($message, 'alert');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function crit($message)
|
||||||
|
{
|
||||||
|
$this->log($message, 'crit');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function err($message)
|
||||||
|
{
|
||||||
|
$this->log($message, 'err');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function warning($message)
|
||||||
|
{
|
||||||
|
$this->log($message, 'warning');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function notice($message)
|
||||||
|
{
|
||||||
|
$this->log($message, 'notice');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function info($message)
|
||||||
|
{
|
||||||
|
$this->log($message, 'info');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function debug($message)
|
||||||
|
{
|
||||||
|
$add = true;
|
||||||
|
|
||||||
|
if (null !== $this->stopwatch) {
|
||||||
|
$trace = debug_backtrace();
|
||||||
|
$method = $trace[2]['args'][2];
|
||||||
|
|
||||||
|
$watch = 'Propel Query '.(count($this->queries) + 1);
|
||||||
|
if ('PropelPDO::prepare' === $method) {
|
||||||
|
$this->isPrepared = true;
|
||||||
|
$this->stopwatch->start($watch, 'propel');
|
||||||
|
|
||||||
|
$add = false;
|
||||||
|
} elseif ($this->isPrepared) {
|
||||||
|
$this->isPrepared = false;
|
||||||
|
$this->stopwatch->stop($watch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($add) {
|
||||||
|
$this->queries[] = $message;
|
||||||
|
$this->log($message, 'debug');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function log($message, $severity = null)
|
||||||
|
{
|
||||||
|
if (null !== $this->logger) {
|
||||||
|
$message = is_string($message) ? $message : var_export($message, true);
|
||||||
|
|
||||||
|
switch ($severity) {
|
||||||
|
case 'alert':
|
||||||
|
$this->logger->alert($message);
|
||||||
|
break;
|
||||||
|
case 'crit':
|
||||||
|
$this->logger->critical($message);
|
||||||
|
break;
|
||||||
|
case 'err':
|
||||||
|
$this->logger->error($message);
|
||||||
|
break;
|
||||||
|
case 'warning':
|
||||||
|
$this->logger->warning($message);
|
||||||
|
break;
|
||||||
|
case 'notice':
|
||||||
|
$this->logger->notice($message);
|
||||||
|
break;
|
||||||
|
case 'info':
|
||||||
|
$this->logger->info($message);
|
||||||
|
break;
|
||||||
|
case 'debug':
|
||||||
|
default:
|
||||||
|
$this->logger->debug($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns queries.
|
||||||
|
*
|
||||||
|
* @return array Queries
|
||||||
|
*/
|
||||||
|
public function getQueries()
|
||||||
|
{
|
||||||
|
return $this->queries;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,15 +7,14 @@
|
||||||
*
|
*
|
||||||
* @license MIT License
|
* @license MIT License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Propel\PropelBundle;
|
namespace Propel\PropelBundle;
|
||||||
|
|
||||||
use Symfony\Bridge\Propel1\DependencyInjection\Security\UserProvider\PropelFactory;
|
use Propel\PropelBundle\DependencyInjection\Security\UserProvider\PropelFactory;
|
||||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PropelBundle
|
* PropelBundle.
|
||||||
*
|
*
|
||||||
* @author William DURAND <william.durand1@gmail.com>
|
* @author William DURAND <william.durand1@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -51,7 +50,7 @@ class PropelBundle extends Bundle
|
||||||
), false);
|
), false);
|
||||||
$config->setParameter('debugpdo.logging.details', array(
|
$config->setParameter('debugpdo.logging.details', array(
|
||||||
'time' => array('enabled' => true),
|
'time' => array('enabled' => true),
|
||||||
'mem' => array('enabled' => true),
|
'mem' => array('enabled' => true),
|
||||||
'connection' => array('enabled' => true),
|
'connection' => array('enabled' => true),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
<parameters>
|
<parameters>
|
||||||
<parameter key="propel.dbal.default_connection">default</parameter>
|
<parameter key="propel.dbal.default_connection">default</parameter>
|
||||||
<parameter key="propel.configuration.class">PropelConfiguration</parameter>
|
<parameter key="propel.configuration.class">PropelConfiguration</parameter>
|
||||||
<parameter key="propel.logger.class">Symfony\Bridge\Propel1\Logger\PropelLogger</parameter>
|
<parameter key="propel.logger.class">Propel\PropelBundle\Logger\PropelLogger</parameter>
|
||||||
<parameter key="propel.data_collector.class">Symfony\Bridge\Propel1\DataCollector\PropelDataCollector</parameter>
|
<parameter key="propel.data_collector.class">Propel\PropelBundle\DataCollector\PropelDataCollector</parameter>
|
||||||
<parameter key="propel.build_properties.class">Propel\PropelBundle\DependencyInjection\Properties</parameter>
|
<parameter key="propel.build_properties.class">Propel\PropelBundle\DependencyInjection\Properties</parameter>
|
||||||
<parameter key="propel.form.type.model.class">Symfony\Bridge\Propel1\Form\Type\ModelType</parameter>
|
<parameter key="propel.form.type.model.class">Propel\PropelBundle\Form\Type\ModelType</parameter>
|
||||||
<parameter key="propel.twig.extension.syntax.class">Propel\PropelBundle\Twig\Extension\SyntaxExtension</parameter>
|
<parameter key="propel.twig.extension.syntax.class">Propel\PropelBundle\Twig\Extension\SyntaxExtension</parameter>
|
||||||
<parameter key="form.type_guesser.propel.class">Symfony\Bridge\Propel1\Form\PropelTypeGuesser</parameter>
|
<parameter key="form.type_guesser.propel.class">Propel\PropelBundle\Form\PropelTypeGuesser</parameter>
|
||||||
<parameter key="propel.security.acl.provider.model.class">Propel\PropelBundle\Security\Acl\AuditableAclProvider</parameter>
|
<parameter key="propel.security.acl.provider.model.class">Propel\PropelBundle\Security\Acl\AuditableAclProvider</parameter>
|
||||||
<parameter key="propel.security.user.provider.class">Symfony\Bridge\Propel1\Security\User\PropelUserProvider</parameter>
|
<parameter key="propel.security.user.provider.class">Propel\PropelBundle\Security\User\PropelUserProvider</parameter>
|
||||||
</parameters>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<services>
|
||||||
|
|
103
Security/User/PropelUserProvider.php
Normal file
103
Security/User/PropelUserProvider.php
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
<?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 Propel\PropelBundle\Security\User;
|
||||||
|
|
||||||
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||||
|
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
|
||||||
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides easy to use provisioning for Propel model users.
|
||||||
|
*
|
||||||
|
* @author William DURAND <william.durand1@gmail.com>
|
||||||
|
*/
|
||||||
|
class PropelUserProvider implements UserProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A Model class name.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Query class name.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $queryClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A property to use to retrieve the user.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*
|
||||||
|
* @param string $class The User model class.
|
||||||
|
* @param string|null $property The property to use to retrieve a user.
|
||||||
|
*/
|
||||||
|
public function __construct($class, $property = null)
|
||||||
|
{
|
||||||
|
$this->class = $class;
|
||||||
|
$this->queryClass = $class.'Query';
|
||||||
|
$this->property = $property;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function loadUserByUsername($username)
|
||||||
|
{
|
||||||
|
$queryClass = $this->queryClass;
|
||||||
|
$query = $queryClass::create();
|
||||||
|
|
||||||
|
if (null !== $this->property) {
|
||||||
|
$filter = 'filterBy'.ucfirst($this->property);
|
||||||
|
$query->$filter($username);
|
||||||
|
} else {
|
||||||
|
$query->filterByUsername($username);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $user = $query->findOne()) {
|
||||||
|
throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function refreshUser(UserInterface $user)
|
||||||
|
{
|
||||||
|
if (!$user instanceof $this->class) {
|
||||||
|
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$queryClass = $this->queryClass;
|
||||||
|
|
||||||
|
return $queryClass::create()->findPk($user->getPrimaryKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function supportsClass($class)
|
||||||
|
{
|
||||||
|
return $class === $this->class;
|
||||||
|
}
|
||||||
|
}
|
104
Tests/DataCollector/PropelDataCollectorTest.php
Normal file
104
Tests/DataCollector/PropelDataCollectorTest.php
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\DataCollector;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\DataCollector\PropelDataCollector;
|
||||||
|
use Propel\PropelBundle\Tests\TestCase;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class PropelDataCollectorTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testCollectWithoutData()
|
||||||
|
{
|
||||||
|
$c = $this->createCollector(array());
|
||||||
|
$c->collect(new Request(), new Response());
|
||||||
|
|
||||||
|
$this->assertEquals(array(), $c->getQueries());
|
||||||
|
$this->assertEquals(0, $c->getQueryCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCollectWithData()
|
||||||
|
{
|
||||||
|
$queries = array(
|
||||||
|
"time: 0.000 sec | mem: 1.4 MB | connection: default | SET NAMES 'utf8'",
|
||||||
|
);
|
||||||
|
|
||||||
|
$c = $this->createCollector($queries);
|
||||||
|
$c->collect(new Request(), new Response());
|
||||||
|
|
||||||
|
$this->assertEquals(array(
|
||||||
|
array(
|
||||||
|
'sql' => "SET NAMES 'utf8'",
|
||||||
|
'time' => '0.000 sec',
|
||||||
|
'connection' => 'default',
|
||||||
|
'memory' => '1.4 MB',
|
||||||
|
),
|
||||||
|
), $c->getQueries());
|
||||||
|
$this->assertEquals(1, $c->getQueryCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCollectWithMultipleData()
|
||||||
|
{
|
||||||
|
$queries = array(
|
||||||
|
"time: 0.000 sec | mem: 1.4 MB | connection: default | SET NAMES 'utf8'",
|
||||||
|
'time: 0.012 sec | mem: 2.4 MB | connection: default | SELECT tags.NAME, image.FILENAME FROM tags LEFT JOIN image ON tags.IMAGEID = image.ID WHERE image.ID = 12',
|
||||||
|
"time: 0.012 sec | mem: 2.4 MB | connection: default | INSERT INTO `table` (`some_array`) VALUES ('| 1 | 2 | 3 |')",
|
||||||
|
);
|
||||||
|
|
||||||
|
$c = $this->createCollector($queries);
|
||||||
|
$c->collect(new Request(), new Response());
|
||||||
|
|
||||||
|
$this->assertEquals(array(
|
||||||
|
array(
|
||||||
|
'sql' => "SET NAMES 'utf8'",
|
||||||
|
'time' => '0.000 sec',
|
||||||
|
'connection' => 'default',
|
||||||
|
'memory' => '1.4 MB',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'sql' => 'SELECT tags.NAME, image.FILENAME FROM tags LEFT JOIN image ON tags.IMAGEID = image.ID WHERE image.ID = 12',
|
||||||
|
'time' => '0.012 sec',
|
||||||
|
'connection' => 'default',
|
||||||
|
'memory' => '2.4 MB',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'sql' => "INSERT INTO `table` (`some_array`) VALUES ('| 1 | 2 | 3 |')",
|
||||||
|
'time' => '0.012 sec',
|
||||||
|
'connection' => 'default',
|
||||||
|
'memory' => '2.4 MB',
|
||||||
|
),
|
||||||
|
), $c->getQueries());
|
||||||
|
$this->assertEquals(3, $c->getQueryCount());
|
||||||
|
$this->assertEquals(0.024, $c->getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createCollector($queries)
|
||||||
|
{
|
||||||
|
$config = $this->getMock('\PropelConfiguration');
|
||||||
|
|
||||||
|
$config
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getParameter')
|
||||||
|
->will($this->returnArgument(1))
|
||||||
|
;
|
||||||
|
|
||||||
|
$logger = $this->getMock('\Propel\PropelBundle\Logger\PropelLogger');
|
||||||
|
$logger
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getQueries')
|
||||||
|
->will($this->returnValue($queries))
|
||||||
|
;
|
||||||
|
|
||||||
|
return new PropelDataCollector($logger, $config);
|
||||||
|
}
|
||||||
|
}
|
54
Tests/Fixtures/Column.php
Normal file
54
Tests/Fixtures/Column.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\Fixtures;
|
||||||
|
|
||||||
|
class Column extends \ColumnMap
|
||||||
|
{
|
||||||
|
private $name;
|
||||||
|
protected $type;
|
||||||
|
|
||||||
|
public function __construct($name, $type)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
$this->type = $type;
|
||||||
|
$this->phpName = ucfirst($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isText()
|
||||||
|
{
|
||||||
|
if (!$this->type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($this->type) {
|
||||||
|
case \PropelColumnTypes::CHAR:
|
||||||
|
case \PropelColumnTypes::VARCHAR:
|
||||||
|
case \PropelColumnTypes::LONGVARCHAR:
|
||||||
|
case \PropelColumnTypes::BLOB:
|
||||||
|
case \PropelColumnTypes::CLOB:
|
||||||
|
case \PropelColumnTypes::CLOB_EMU:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSize()
|
||||||
|
{
|
||||||
|
return $this->isText() ? 255 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isNotNull()
|
||||||
|
{
|
||||||
|
return 'id' === $this->name;
|
||||||
|
}
|
||||||
|
}
|
111
Tests/Fixtures/Item.php
Normal file
111
Tests/Fixtures/Item.php
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\Fixtures;
|
||||||
|
|
||||||
|
class Item implements \Persistent
|
||||||
|
{
|
||||||
|
private $id;
|
||||||
|
private $value;
|
||||||
|
private $groupName;
|
||||||
|
private $price;
|
||||||
|
|
||||||
|
private $slug;
|
||||||
|
|
||||||
|
public function __construct($id = null, $value = null, $groupName = null, $price = null, $slug = null)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
$this->value = $value;
|
||||||
|
$this->groupName = $groupName;
|
||||||
|
$this->price = $price;
|
||||||
|
$this->slug = $slug;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setId($id)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue()
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGroupName()
|
||||||
|
{
|
||||||
|
return $this->groupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrice()
|
||||||
|
{
|
||||||
|
return $this->price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSlug()
|
||||||
|
{
|
||||||
|
return $this->slug;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrimaryKey()
|
||||||
|
{
|
||||||
|
return $this->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPrimaryKey($primaryKey)
|
||||||
|
{
|
||||||
|
$this->setId($primaryKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isModified()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isColumnModified($col)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isNew()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setNew($b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resetModified()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isDeleted()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDeleted($b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(\PropelPDO $con = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(\PropelPDO $con = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
130
Tests/Fixtures/ItemQuery.php
Normal file
130
Tests/Fixtures/ItemQuery.php
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\Fixtures;
|
||||||
|
|
||||||
|
class ItemQuery
|
||||||
|
{
|
||||||
|
private $map = array(
|
||||||
|
'id' => \PropelColumnTypes::INTEGER,
|
||||||
|
'value' => \PropelColumnTypes::VARCHAR,
|
||||||
|
'price' => \PropelColumnTypes::FLOAT,
|
||||||
|
'is_active' => \PropelColumnTypes::BOOLEAN,
|
||||||
|
'slug' => \PropelColumnTypes::VARCHAR,
|
||||||
|
'enabled' => \PropelColumnTypes::BOOLEAN_EMU,
|
||||||
|
'updated_at' => \PropelColumnTypes::TIMESTAMP,
|
||||||
|
);
|
||||||
|
|
||||||
|
private $caseInsensitiveMap = array(
|
||||||
|
'isactive' => 'is_active',
|
||||||
|
'updatedat' => 'updated_at',
|
||||||
|
);
|
||||||
|
|
||||||
|
public static $result = array();
|
||||||
|
|
||||||
|
public function find()
|
||||||
|
{
|
||||||
|
return self::$result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterById($id)
|
||||||
|
{
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTableMap()
|
||||||
|
{
|
||||||
|
// Allows to define methods in this class
|
||||||
|
// to avoid a lot of mock classes
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrimaryKeys()
|
||||||
|
{
|
||||||
|
$cm = new \ColumnMap('id', new \TableMap());
|
||||||
|
$cm->setType('INTEGER');
|
||||||
|
$cm->setPhpName('Id');
|
||||||
|
|
||||||
|
return array('id' => $cm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method from the TableMap API.
|
||||||
|
*/
|
||||||
|
public function hasColumn($column)
|
||||||
|
{
|
||||||
|
return in_array($column, array_keys($this->map));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method from the TableMap API.
|
||||||
|
*/
|
||||||
|
public function getColumn($column)
|
||||||
|
{
|
||||||
|
if ($this->hasColumn($column)) {
|
||||||
|
return new Column($column, $this->map[$column]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method from the TableMap API.
|
||||||
|
*/
|
||||||
|
public function hasColumnByInsensitiveCase($column)
|
||||||
|
{
|
||||||
|
$column = strtolower($column);
|
||||||
|
|
||||||
|
return in_array($column, array_keys($this->caseInsensitiveMap));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method from the TableMap API.
|
||||||
|
*/
|
||||||
|
public function getColumnByInsensitiveCase($column)
|
||||||
|
{
|
||||||
|
$column = strtolower($column);
|
||||||
|
|
||||||
|
if (isset($this->caseInsensitiveMap[$column])) {
|
||||||
|
return $this->getColumn($this->caseInsensitiveMap[$column]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method from the TableMap API.
|
||||||
|
*/
|
||||||
|
public function getRelations()
|
||||||
|
{
|
||||||
|
// table maps
|
||||||
|
$authorTable = new \TableMap();
|
||||||
|
$authorTable->setClassName('\Foo\Author');
|
||||||
|
|
||||||
|
$resellerTable = new \TableMap();
|
||||||
|
$resellerTable->setClassName('\Foo\Reseller');
|
||||||
|
|
||||||
|
// relations
|
||||||
|
$mainAuthorRelation = new \RelationMap('MainAuthor');
|
||||||
|
$mainAuthorRelation->setType(\RelationMap::MANY_TO_ONE);
|
||||||
|
$mainAuthorRelation->setForeignTable($authorTable);
|
||||||
|
|
||||||
|
$authorRelation = new \RelationMap('Author');
|
||||||
|
$authorRelation->setType(\RelationMap::ONE_TO_MANY);
|
||||||
|
$authorRelation->setForeignTable($authorTable);
|
||||||
|
|
||||||
|
$resellerRelation = new \RelationMap('Reseller');
|
||||||
|
$resellerRelation->setType(\RelationMap::MANY_TO_MANY);
|
||||||
|
$resellerRelation->setLocalTable($resellerTable);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
$mainAuthorRelation,
|
||||||
|
$authorRelation,
|
||||||
|
$resellerRelation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
25
Tests/Fixtures/ReadOnlyItem.php
Normal file
25
Tests/Fixtures/ReadOnlyItem.php
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\Fixtures;
|
||||||
|
|
||||||
|
class ReadOnlyItem extends \BaseObject
|
||||||
|
{
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'Marvin';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrimaryKey()
|
||||||
|
{
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}
|
30
Tests/Fixtures/ReadOnlyItemQuery.php
Normal file
30
Tests/Fixtures/ReadOnlyItemQuery.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\Fixtures;
|
||||||
|
|
||||||
|
class ReadOnlyItemQuery
|
||||||
|
{
|
||||||
|
public function getTableMap()
|
||||||
|
{
|
||||||
|
// Allows to define methods in this class
|
||||||
|
// to avoid a lot of mock classes
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrimaryKeys()
|
||||||
|
{
|
||||||
|
$cm = new \ColumnMap('id', new \TableMap());
|
||||||
|
$cm->setType('INTEGER');
|
||||||
|
|
||||||
|
return array('id' => $cm);
|
||||||
|
}
|
||||||
|
}
|
125
Tests/Fixtures/TranslatableItem.php
Normal file
125
Tests/Fixtures/TranslatableItem.php
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\Fixtures;
|
||||||
|
|
||||||
|
class TranslatableItem implements \Persistent
|
||||||
|
{
|
||||||
|
private $id;
|
||||||
|
private $currentTranslations;
|
||||||
|
private $groupName;
|
||||||
|
private $price;
|
||||||
|
|
||||||
|
public function __construct($id = null, $translations = array())
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
$this->currentTranslations = $translations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setId($id)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGroupName()
|
||||||
|
{
|
||||||
|
return $this->groupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrice()
|
||||||
|
{
|
||||||
|
return $this->price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrimaryKey()
|
||||||
|
{
|
||||||
|
return $this->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPrimaryKey($primaryKey)
|
||||||
|
{
|
||||||
|
$this->setId($primaryKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isModified()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isColumnModified($col)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isNew()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setNew($b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resetModified()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isDeleted()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDeleted($b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(\PropelPDO $con = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(\PropelPDO $con = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTranslation($locale = 'de', \PropelPDO $con = null)
|
||||||
|
{
|
||||||
|
if (!isset($this->currentTranslations[$locale])) {
|
||||||
|
$translation = new TranslatableItemI18n();
|
||||||
|
$translation->setLocale($locale);
|
||||||
|
$this->currentTranslations[$locale] = $translation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->currentTranslations[$locale];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addTranslatableItemI18n(TranslatableItemI18n $i)
|
||||||
|
{
|
||||||
|
if (!in_array($i, $this->currentTranslations)) {
|
||||||
|
$this->currentTranslations[$i->getLocale()] = $i;
|
||||||
|
$i->setItem($this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeTranslatableItemI18n(TranslatableItemI18n $i)
|
||||||
|
{
|
||||||
|
unset($this->currentTranslations[$i->getLocale()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTranslatableItemI18ns()
|
||||||
|
{
|
||||||
|
return $this->currentTranslations;
|
||||||
|
}
|
||||||
|
}
|
128
Tests/Fixtures/TranslatableItemI18n.php
Normal file
128
Tests/Fixtures/TranslatableItemI18n.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 Propel\PropelBundle\Tests\Fixtures;
|
||||||
|
|
||||||
|
class TranslatableItemI18n implements \Persistent
|
||||||
|
{
|
||||||
|
private $id;
|
||||||
|
private $locale;
|
||||||
|
private $value;
|
||||||
|
private $value2;
|
||||||
|
private $item;
|
||||||
|
|
||||||
|
public function __construct($id = null, $locale = null, $value = null)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
$this->locale = $locale;
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setId($id)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrimaryKey()
|
||||||
|
{
|
||||||
|
return $this->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPrimaryKey($primaryKey)
|
||||||
|
{
|
||||||
|
$this->setId($primaryKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isModified()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isColumnModified($col)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isNew()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setNew($b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resetModified()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isDeleted()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDeleted($b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(\PropelPDO $con = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(\PropelPDO $con = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLocale($locale)
|
||||||
|
{
|
||||||
|
$this->locale = $locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLocale()
|
||||||
|
{
|
||||||
|
return $this->locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItem()
|
||||||
|
{
|
||||||
|
return $this->item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setItem($item)
|
||||||
|
{
|
||||||
|
$this->item = $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValue($value)
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue()
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValue2($value2)
|
||||||
|
{
|
||||||
|
$this->value2 = $value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue2()
|
||||||
|
{
|
||||||
|
return $this->value2;
|
||||||
|
}
|
||||||
|
}
|
118
Tests/Form/ChoiceList/CompatModelChoiceListTest.php
Normal file
118
Tests/Form/ChoiceList/CompatModelChoiceListTest.php
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Propel\PropelBundle\Tests\Form\ChoiceList;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\Form\ChoiceList\ModelChoiceList;
|
||||||
|
use Propel\PropelBundle\Tests\Fixtures\Item;
|
||||||
|
use Propel\PropelBundle\Tests\Fixtures\ItemQuery;
|
||||||
|
use Symfony\Component\Form\Tests\Extension\Core\ChoiceList\AbstractChoiceListTest;
|
||||||
|
|
||||||
|
class CompatModelChoiceListTest extends AbstractChoiceListTest
|
||||||
|
{
|
||||||
|
const ITEM_CLASS = '\Propel\PropelBundle\Tests\Fixtures\Item';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \PHPUnit_Framework_MockObject_MockObject|\Propel\PropelBundle\Tests\Fixtures\ItemQuery
|
||||||
|
*/
|
||||||
|
protected $query;
|
||||||
|
|
||||||
|
protected $item1;
|
||||||
|
protected $item2;
|
||||||
|
protected $item3;
|
||||||
|
protected $item4;
|
||||||
|
|
||||||
|
public function testGetChoicesForValues()
|
||||||
|
{
|
||||||
|
$this->query
|
||||||
|
->expects($this->once())
|
||||||
|
->method('filterById')
|
||||||
|
->with(array(1, 2))
|
||||||
|
->will($this->returnSelf())
|
||||||
|
;
|
||||||
|
|
||||||
|
ItemQuery::$result = array(
|
||||||
|
$this->item2,
|
||||||
|
$this->item1,
|
||||||
|
);
|
||||||
|
|
||||||
|
parent::testGetChoicesForValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
$this->query = $this->getMock('Propel\PropelBundle\Tests\Fixtures\ItemQuery', array(
|
||||||
|
'filterById',
|
||||||
|
), array(), '', true, true, true, false, true);
|
||||||
|
|
||||||
|
$this->query
|
||||||
|
->expects($this->any())
|
||||||
|
->method('filterById')
|
||||||
|
->with($this->anything())
|
||||||
|
->will($this->returnSelf())
|
||||||
|
;
|
||||||
|
|
||||||
|
$this->createItems();
|
||||||
|
|
||||||
|
ItemQuery::$result = array(
|
||||||
|
$this->item1,
|
||||||
|
$this->item2,
|
||||||
|
$this->item3,
|
||||||
|
$this->item4,
|
||||||
|
);
|
||||||
|
|
||||||
|
parent::setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createItems()
|
||||||
|
{
|
||||||
|
$this->item1 = new Item(1, 'Foo');
|
||||||
|
$this->item2 = new Item(2, 'Bar');
|
||||||
|
$this->item3 = new Item(3, 'Baz');
|
||||||
|
$this->item4 = new Item(4, 'Cuz');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createChoiceList()
|
||||||
|
{
|
||||||
|
return new ModelChoiceList(self::ITEM_CLASS, 'value', null, $this->query);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getChoices()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
1 => $this->item1,
|
||||||
|
2 => $this->item2,
|
||||||
|
3 => $this->item3,
|
||||||
|
4 => $this->item4,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getLabels()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
1 => 'Foo',
|
||||||
|
2 => 'Bar',
|
||||||
|
3 => 'Baz',
|
||||||
|
4 => 'Cuz',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getValues()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
1 => '1',
|
||||||
|
2 => '2',
|
||||||
|
3 => '3',
|
||||||
|
4 => '4',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getIndices()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
316
Tests/Form/ChoiceList/ModelChoiceListTest.php
Normal file
316
Tests/Form/ChoiceList/ModelChoiceListTest.php
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\Form\ChoiceList;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\Form\ChoiceList\ModelChoiceList;
|
||||||
|
use Propel\PropelBundle\Tests\Fixtures\Item;
|
||||||
|
use Propel\PropelBundle\Tests\Fixtures\ItemQuery;
|
||||||
|
use Propel\PropelBundle\Tests\Fixtures\ReadOnlyItem;
|
||||||
|
use Propel\PropelBundle\Tests\TestCase;
|
||||||
|
use Symfony\Component\Form\Extension\Core\View\ChoiceView;
|
||||||
|
|
||||||
|
class ModelChoiceListTest extends TestCase
|
||||||
|
{
|
||||||
|
const ITEM_CLASS = '\Propel\PropelBundle\Tests\Fixtures\Item';
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
ItemQuery::$result = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEmptyChoicesReturnsEmpty()
|
||||||
|
{
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSame(array(), $choiceList->getChoices());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadOnlyIsValidChoice()
|
||||||
|
{
|
||||||
|
$item = new ReadOnlyItem();
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
'\Propel\PropelBundle\Tests\Fixtures\ReadOnlyItem',
|
||||||
|
'name',
|
||||||
|
array(
|
||||||
|
$item,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSame(array(42 => $item), $choiceList->getChoices());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFlattenedChoices()
|
||||||
|
{
|
||||||
|
$item1 = new Item(1, 'Foo');
|
||||||
|
$item2 = new Item(2, 'Bar');
|
||||||
|
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array(
|
||||||
|
$item1,
|
||||||
|
$item2,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFlattenedPreferredChoices()
|
||||||
|
{
|
||||||
|
$item1 = new Item(1, 'Foo');
|
||||||
|
$item2 = new Item(2, 'Bar');
|
||||||
|
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array(
|
||||||
|
$item1,
|
||||||
|
$item2,
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
array(
|
||||||
|
$item1,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices());
|
||||||
|
$this->assertEquals(array(1 => new ChoiceView($item1, '1', 'Foo')), $choiceList->getPreferredViews());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNestedChoices()
|
||||||
|
{
|
||||||
|
$item1 = new Item(1, 'Foo');
|
||||||
|
$item2 = new Item(2, 'Bar');
|
||||||
|
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array(
|
||||||
|
'group1' => array($item1),
|
||||||
|
'group2' => array($item2),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices());
|
||||||
|
$this->assertEquals(array(
|
||||||
|
'group1' => array(1 => new ChoiceView($item1, '1', 'Foo')),
|
||||||
|
'group2' => array(2 => new ChoiceView($item2, '2', 'Bar')),
|
||||||
|
), $choiceList->getRemainingViews());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGroupBySupportsString()
|
||||||
|
{
|
||||||
|
$item1 = new Item(1, 'Foo', 'Group1');
|
||||||
|
$item2 = new Item(2, 'Bar', 'Group1');
|
||||||
|
$item3 = new Item(3, 'Baz', 'Group2');
|
||||||
|
$item4 = new Item(4, 'Boo!', null);
|
||||||
|
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array(
|
||||||
|
$item1,
|
||||||
|
$item2,
|
||||||
|
$item3,
|
||||||
|
$item4,
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
'groupName'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(array(1 => $item1, 2 => $item2, 3 => $item3, 4 => $item4), $choiceList->getChoices());
|
||||||
|
$this->assertEquals(array(
|
||||||
|
'Group1' => array(1 => new ChoiceView($item1, '1', 'Foo'), 2 => new ChoiceView($item2, '2', 'Bar')),
|
||||||
|
'Group2' => array(3 => new ChoiceView($item3, '3', 'Baz')),
|
||||||
|
4 => new ChoiceView($item4, '4', 'Boo!'),
|
||||||
|
), $choiceList->getRemainingViews());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGroupByInvalidPropertyPathReturnsFlatChoices()
|
||||||
|
{
|
||||||
|
$item1 = new Item(1, 'Foo', 'Group1');
|
||||||
|
$item2 = new Item(2, 'Bar', 'Group1');
|
||||||
|
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array(
|
||||||
|
$item1,
|
||||||
|
$item2,
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
'child.that.does.not.exist'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(array(
|
||||||
|
1 => $item1,
|
||||||
|
2 => $item2,
|
||||||
|
), $choiceList->getChoices());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetValuesForChoices()
|
||||||
|
{
|
||||||
|
$item1 = new Item(1, 'Foo');
|
||||||
|
$item2 = new Item(2, 'Bar');
|
||||||
|
|
||||||
|
ItemQuery::$result = array(
|
||||||
|
$item1,
|
||||||
|
$item2,
|
||||||
|
);
|
||||||
|
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(array(1, 2), $choiceList->getValuesForChoices(array($item1, $item2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDifferentEqualObjectsAreChoosen()
|
||||||
|
{
|
||||||
|
$item = new Item(1, 'Foo');
|
||||||
|
|
||||||
|
ItemQuery::$result = array(
|
||||||
|
$item,
|
||||||
|
);
|
||||||
|
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array($item)
|
||||||
|
);
|
||||||
|
|
||||||
|
$choosenItem = new Item(1, 'Foo');
|
||||||
|
|
||||||
|
$this->assertEquals(array('1'), $choiceList->getValuesForChoices(array($choosenItem)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLegacygetIndicesForChoices()
|
||||||
|
{
|
||||||
|
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
$item1 = new Item(1, 'Foo');
|
||||||
|
$item2 = new Item(2, 'Bar');
|
||||||
|
|
||||||
|
ItemQuery::$result = array(
|
||||||
|
$item1,
|
||||||
|
$item2,
|
||||||
|
);
|
||||||
|
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(array(1, 2), $choiceList->getIndicesForChoices(array($item1, $item2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLegacyDifferentEqualObjectsAreChoosen()
|
||||||
|
{
|
||||||
|
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
$item = new Item(1, 'Foo');
|
||||||
|
|
||||||
|
ItemQuery::$result = array(
|
||||||
|
$item,
|
||||||
|
);
|
||||||
|
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array($item)
|
||||||
|
);
|
||||||
|
|
||||||
|
$choosenItem = new Item(1, 'Foo');
|
||||||
|
|
||||||
|
$this->assertEquals(array(1), $choiceList->getIndicesForChoices(array($choosenItem)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLegacyGetIndicesForNullChoices()
|
||||||
|
{
|
||||||
|
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
$item = new Item(1, 'Foo');
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array($item)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(array(), $choiceList->getIndicesForChoices(array(null)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDontAllowInvalidChoiceValues()
|
||||||
|
{
|
||||||
|
$item = new Item(1, 'Foo');
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array($item)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(array(), $choiceList->getValuesForChoices(array(new Item(2, 'Bar'))));
|
||||||
|
$this->assertEquals(array(), $choiceList->getChoicesForValues(array(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\OptionsResolver\Exception\MissingOptionsException
|
||||||
|
*/
|
||||||
|
public function testEmptyClass()
|
||||||
|
{
|
||||||
|
new ModelChoiceList('');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
|
||||||
|
*/
|
||||||
|
public function testInvalidClass()
|
||||||
|
{
|
||||||
|
new ModelChoiceList('Foo\Bar\DoesNotExistClass');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCustomIdentifier()
|
||||||
|
{
|
||||||
|
$item1 = new Item(1, 'Foo', null, null, 'slug');
|
||||||
|
$item2 = new Item(2, 'Bar', null, null, 'slug2');
|
||||||
|
|
||||||
|
$choiceList = new ModelChoiceList(
|
||||||
|
self::ITEM_CLASS,
|
||||||
|
'value',
|
||||||
|
array(
|
||||||
|
$item1,
|
||||||
|
$item2,
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
array(),
|
||||||
|
null,
|
||||||
|
'slug'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertSame(array('slug' => $item1, 'slug2' => $item2), $choiceList->getChoices());
|
||||||
|
}
|
||||||
|
}
|
106
Tests/Form/DataTransformer/CollectionToArrayTransformerTest.php
Normal file
106
Tests/Form/DataTransformer/CollectionToArrayTransformerTest.php
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\Form\DataTransformer;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\Form\DataTransformer\CollectionToArrayTransformer;
|
||||||
|
use Propel\PropelBundle\Tests\TestCase;
|
||||||
|
|
||||||
|
class CollectionToArrayTransformerTest extends TestCase
|
||||||
|
{
|
||||||
|
private $transformer;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
$this->transformer = new CollectionToArrayTransformer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTransform()
|
||||||
|
{
|
||||||
|
$result = $this->transformer->transform(new \PropelObjectCollection());
|
||||||
|
|
||||||
|
$this->assertTrue(is_array($result));
|
||||||
|
$this->assertCount(0, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTransformWithNull()
|
||||||
|
{
|
||||||
|
$result = $this->transformer->transform(null);
|
||||||
|
|
||||||
|
$this->assertTrue(is_array($result));
|
||||||
|
$this->assertCount(0, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||||
|
*/
|
||||||
|
public function testTransformThrowsExceptionIfNotPropelObjectCollection()
|
||||||
|
{
|
||||||
|
$this->transformer->transform(new DummyObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTransformWithData()
|
||||||
|
{
|
||||||
|
$coll = new \PropelObjectCollection();
|
||||||
|
$coll->setData(array('foo', 'bar'));
|
||||||
|
|
||||||
|
$result = $this->transformer->transform($coll);
|
||||||
|
|
||||||
|
$this->assertTrue(is_array($result));
|
||||||
|
$this->assertCount(2, $result);
|
||||||
|
$this->assertEquals('foo', $result[0]);
|
||||||
|
$this->assertEquals('bar', $result[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReverseTransformWithNull()
|
||||||
|
{
|
||||||
|
$result = $this->transformer->reverseTransform(null);
|
||||||
|
|
||||||
|
$this->assertInstanceOf('\PropelObjectCollection', $result);
|
||||||
|
$this->assertCount(0, $result->getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReverseTransformWithEmptyString()
|
||||||
|
{
|
||||||
|
$result = $this->transformer->reverseTransform('');
|
||||||
|
|
||||||
|
$this->assertInstanceOf('\PropelObjectCollection', $result);
|
||||||
|
$this->assertCount(0, $result->getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||||
|
*/
|
||||||
|
public function testReverseTransformThrowsExceptionIfNotArray()
|
||||||
|
{
|
||||||
|
$this->transformer->reverseTransform(new DummyObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReverseTransformWithData()
|
||||||
|
{
|
||||||
|
$inputData = array('foo', 'bar');
|
||||||
|
|
||||||
|
$result = $this->transformer->reverseTransform($inputData);
|
||||||
|
$data = $result->getData();
|
||||||
|
|
||||||
|
$this->assertInstanceOf('\PropelObjectCollection', $result);
|
||||||
|
|
||||||
|
$this->assertTrue(is_array($data));
|
||||||
|
$this->assertCount(2, $data);
|
||||||
|
$this->assertEquals('foo', $data[0]);
|
||||||
|
$this->assertEquals('bar', $data[1]);
|
||||||
|
$this->assertsame($inputData, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DummyObject
|
||||||
|
{
|
||||||
|
}
|
136
Tests/Form/PropelTypeGuesserTest.php
Normal file
136
Tests/Form/PropelTypeGuesserTest.php
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\Form;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\Form\PropelTypeGuesser;
|
||||||
|
use Propel\PropelBundle\Tests\TestCase;
|
||||||
|
use Symfony\Component\Form\Guess\Guess;
|
||||||
|
|
||||||
|
class PropelTypeGuesserTest extends TestCase
|
||||||
|
{
|
||||||
|
const CLASS_NAME = 'Propel\PropelBundle\Tests\Fixtures\Item';
|
||||||
|
const UNKNOWN_CLASS_NAME = 'Propel\PropelBundle\Tests\Fixtures\UnknownItem';
|
||||||
|
|
||||||
|
private $guesser;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
$this->guesser = new PropelTypeGuesser();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
$this->guesser = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessMaxLengthWithText()
|
||||||
|
{
|
||||||
|
$value = $this->guesser->guessMaxLength(self::CLASS_NAME, 'value');
|
||||||
|
|
||||||
|
$this->assertNotNull($value);
|
||||||
|
$this->assertEquals(255, $value->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessMaxLengthWithFloat()
|
||||||
|
{
|
||||||
|
$value = $this->guesser->guessMaxLength(self::CLASS_NAME, 'price');
|
||||||
|
|
||||||
|
$this->assertNotNull($value);
|
||||||
|
$this->assertNull($value->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessMinLengthWithText()
|
||||||
|
{
|
||||||
|
$value = $this->guesser->guessPattern(self::CLASS_NAME, 'value');
|
||||||
|
|
||||||
|
$this->assertNull($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessMinLengthWithFloat()
|
||||||
|
{
|
||||||
|
$value = $this->guesser->guessPattern(self::CLASS_NAME, 'price');
|
||||||
|
|
||||||
|
$this->assertNotNull($value);
|
||||||
|
$this->assertNull($value->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessRequired()
|
||||||
|
{
|
||||||
|
$value = $this->guesser->guessRequired(self::CLASS_NAME, 'id');
|
||||||
|
|
||||||
|
$this->assertNotNull($value);
|
||||||
|
$this->assertTrue($value->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessRequiredWithNullableColumn()
|
||||||
|
{
|
||||||
|
$value = $this->guesser->guessRequired(self::CLASS_NAME, 'value');
|
||||||
|
|
||||||
|
$this->assertNotNull($value);
|
||||||
|
$this->assertFalse($value->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessTypeWithoutTable()
|
||||||
|
{
|
||||||
|
$value = $this->guesser->guessType(self::UNKNOWN_CLASS_NAME, 'property');
|
||||||
|
|
||||||
|
$this->assertNotNull($value);
|
||||||
|
$this->assertEquals('text', $value->getType());
|
||||||
|
$this->assertEquals(Guess::LOW_CONFIDENCE, $value->getConfidence());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGuessTypeWithoutColumn()
|
||||||
|
{
|
||||||
|
$value = $this->guesser->guessType(self::CLASS_NAME, 'property');
|
||||||
|
|
||||||
|
$this->assertNotNull($value);
|
||||||
|
$this->assertEquals('text', $value->getType());
|
||||||
|
$this->assertEquals(Guess::LOW_CONFIDENCE, $value->getConfidence());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataProviderForGuessType
|
||||||
|
*/
|
||||||
|
public function testGuessType($property, $type, $confidence, $multiple = null)
|
||||||
|
{
|
||||||
|
$value = $this->guesser->guessType(self::CLASS_NAME, $property);
|
||||||
|
|
||||||
|
$this->assertNotNull($value);
|
||||||
|
$this->assertEquals($type, $value->getType());
|
||||||
|
$this->assertEquals($confidence, $value->getConfidence());
|
||||||
|
|
||||||
|
if ($type === 'model') {
|
||||||
|
$options = $value->getOptions();
|
||||||
|
|
||||||
|
$this->assertSame($multiple, $options['multiple']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function dataProviderForGuessType()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('is_active', 'checkbox', Guess::HIGH_CONFIDENCE),
|
||||||
|
array('enabled', 'checkbox', Guess::HIGH_CONFIDENCE),
|
||||||
|
array('id', 'integer', Guess::MEDIUM_CONFIDENCE),
|
||||||
|
array('value', 'text', Guess::MEDIUM_CONFIDENCE),
|
||||||
|
array('price', 'number', Guess::MEDIUM_CONFIDENCE),
|
||||||
|
array('updated_at', 'datetime', Guess::HIGH_CONFIDENCE),
|
||||||
|
|
||||||
|
array('isActive', 'checkbox', Guess::HIGH_CONFIDENCE),
|
||||||
|
array('updatedAt', 'datetime', Guess::HIGH_CONFIDENCE),
|
||||||
|
|
||||||
|
array('Authors', 'model', Guess::HIGH_CONFIDENCE, true),
|
||||||
|
array('Resellers', 'model', Guess::HIGH_CONFIDENCE, true),
|
||||||
|
array('MainAuthor', 'model', Guess::HIGH_CONFIDENCE, false),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
151
Tests/Form/Type/TranslationCollectionTypeTest.php
Normal file
151
Tests/Form/Type/TranslationCollectionTypeTest.php
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
<?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 Propel\PropelBundle\Tests\Form\Type;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\Form\PropelExtension;
|
||||||
|
use Propel\PropelBundle\Tests\Fixtures\Item;
|
||||||
|
use Propel\PropelBundle\Tests\Fixtures\TranslatableItem;
|
||||||
|
use Propel\PropelBundle\Tests\Fixtures\TranslatableItemI18n;
|
||||||
|
use Symfony\Component\Form\Test\TypeTestCase;
|
||||||
|
|
||||||
|
class TranslationCollectionTypeTest extends TypeTestCase
|
||||||
|
{
|
||||||
|
const TRANSLATION_CLASS = 'Propel\PropelBundle\Tests\Fixtures\TranslatableItem';
|
||||||
|
const TRANSLATABLE_I18N_CLASS = 'Propel\PropelBundle\Tests\Fixtures\TranslatableItemI18n';
|
||||||
|
const NON_TRANSLATION_CLASS = 'Propel\PropelBundle\Tests\Fixtures\Item';
|
||||||
|
|
||||||
|
protected function getExtensions()
|
||||||
|
{
|
||||||
|
return array(new PropelExtension());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTranslationsAdded()
|
||||||
|
{
|
||||||
|
$item = new TranslatableItem();
|
||||||
|
$item->addTranslatableItemI18n(new TranslatableItemI18n(1, 'fr', 'val1'));
|
||||||
|
$item->addTranslatableItemI18n(new TranslatableItemI18n(2, 'en', 'val2'));
|
||||||
|
|
||||||
|
$builder = $this->factory->createBuilder('form', null, array(
|
||||||
|
'data_class' => self::TRANSLATION_CLASS,
|
||||||
|
));
|
||||||
|
|
||||||
|
$builder->add('translatableItemI18ns', 'propel1_translation_collection', array(
|
||||||
|
'languages' => array('en', 'fr'),
|
||||||
|
'options' => array(
|
||||||
|
'data_class' => self::TRANSLATABLE_I18N_CLASS,
|
||||||
|
'columns' => array('value', 'value2' => array('label' => 'Label', 'type' => 'textarea')),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
$form = $builder->getForm();
|
||||||
|
$form->setData($item);
|
||||||
|
$translations = $form->get('translatableItemI18ns');
|
||||||
|
|
||||||
|
$this->assertCount(2, $translations);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\Form', $translations['en']);
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\Form', $translations['fr']);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(self::TRANSLATABLE_I18N_CLASS, $translations['en']->getData());
|
||||||
|
$this->assertInstanceOf(self::TRANSLATABLE_I18N_CLASS, $translations['fr']->getData());
|
||||||
|
|
||||||
|
$this->assertEquals($item->getTranslation('en'), $translations['en']->getData());
|
||||||
|
$this->assertEquals($item->getTranslation('fr'), $translations['fr']->getData());
|
||||||
|
|
||||||
|
$columnOptions = $translations['fr']->getConfig()->getOption('columns');
|
||||||
|
$this->assertEquals('value', $columnOptions[0]);
|
||||||
|
$this->assertEquals('textarea', $columnOptions['value2']['type']);
|
||||||
|
$this->assertEquals('Label', $columnOptions['value2']['label']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNotPresentTranslationsAdded()
|
||||||
|
{
|
||||||
|
$item = new TranslatableItem();
|
||||||
|
|
||||||
|
$this->assertCount(0, $item->getTranslatableItemI18ns());
|
||||||
|
|
||||||
|
$builder = $this->factory->createBuilder('form', null, array(
|
||||||
|
'data_class' => self::TRANSLATION_CLASS,
|
||||||
|
));
|
||||||
|
$builder->add('translatableItemI18ns', 'propel1_translation_collection', array(
|
||||||
|
'languages' => array('en', 'fr'),
|
||||||
|
'options' => array(
|
||||||
|
'data_class' => self::TRANSLATABLE_I18N_CLASS,
|
||||||
|
'columns' => array('value', 'value2' => array('label' => 'Label', 'type' => 'textarea')),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$form = $builder->getForm();
|
||||||
|
$form->setData($item);
|
||||||
|
|
||||||
|
$this->assertCount(2, $item->getTranslatableItemI18ns());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
|
||||||
|
*/
|
||||||
|
public function testNoArrayGiven()
|
||||||
|
{
|
||||||
|
$item = new Item(null, 'val');
|
||||||
|
|
||||||
|
$builder = $this->factory->createBuilder('form', null, array(
|
||||||
|
'data_class' => self::NON_TRANSLATION_CLASS,
|
||||||
|
));
|
||||||
|
$builder->add('value', 'propel1_translation_collection', array(
|
||||||
|
'languages' => array('en', 'fr'),
|
||||||
|
'options' => array(
|
||||||
|
'data_class' => self::TRANSLATABLE_I18N_CLASS,
|
||||||
|
'columns' => array('value', 'value2' => array('label' => 'Label', 'type' => 'textarea')),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$form = $builder->getForm();
|
||||||
|
$form->setData($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\OptionsResolver\Exception\MissingOptionsException
|
||||||
|
*/
|
||||||
|
public function testNoDataClassAdded()
|
||||||
|
{
|
||||||
|
$this->factory->createNamed('itemI18ns', 'propel1_translation_collection', null, array(
|
||||||
|
'languages' => array('en', 'fr'),
|
||||||
|
'options' => array(
|
||||||
|
'columns' => array('value', 'value2'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\OptionsResolver\Exception\MissingOptionsException
|
||||||
|
*/
|
||||||
|
public function testNoLanguagesAdded()
|
||||||
|
{
|
||||||
|
$this->factory->createNamed('itemI18ns', 'propel1_translation_collection', null, array(
|
||||||
|
'options' => array(
|
||||||
|
'data_class' => self::TRANSLATABLE_I18N_CLASS,
|
||||||
|
'columns' => array('value', 'value2'),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\OptionsResolver\Exception\MissingOptionsException
|
||||||
|
*/
|
||||||
|
public function testNoColumnsAdded()
|
||||||
|
{
|
||||||
|
$this->factory->createNamed('itemI18ns', 'propel1_translation_collection', null, array(
|
||||||
|
'languages' => array('en', 'fr'),
|
||||||
|
'options' => array(
|
||||||
|
'data_class' => self::TRANSLATABLE_I18N_CLASS,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,12 +7,11 @@
|
||||||
*
|
*
|
||||||
* @license MIT License
|
* @license MIT License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Propel\PropelBundle\Tests\Security\User;
|
namespace Propel\PropelBundle\Tests\Security\User;
|
||||||
|
|
||||||
|
use Propel\PropelBundle\Security\User\PropelUserProvider;
|
||||||
use Propel\PropelBundle\Tests\Fixtures\Model\User;
|
use Propel\PropelBundle\Tests\Fixtures\Model\User;
|
||||||
use Propel\PropelBundle\Tests\TestCase;
|
use Propel\PropelBundle\Tests\TestCase;
|
||||||
use Symfony\Bridge\Propel1\Security\User\PropelUserProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author William Durand <william.durand1@gmail.com>
|
* @author William Durand <william.durand1@gmail.com>
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once __DIR__ . '/../vendor/autoload.php';
|
|
||||||
|
|
||||||
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/../vendor/phing/phing/classes');
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
if (file_exists($file = __DIR__.'/autoload.php')) {
|
|
||||||
require_once $file;
|
|
||||||
} elseif (file_exists($file = __DIR__.'/autoload.php.dist')) {
|
|
||||||
require_once $file;
|
|
||||||
}
|
|
|
@ -15,9 +15,8 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"require": {
|
"require": {
|
||||||
"symfony/framework-bundle": "^2.8.2",
|
"propel/propel1": "^1.6.8",
|
||||||
"symfony/propel1-bridge": "2.7.x-dev",
|
"symfony/framework-bundle": "^2.8.2"
|
||||||
"propel/propel1": "^1.6.8"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^4.8.21|^5.0.10",
|
"phpunit/phpunit": "^4.8.21|^5.0.10",
|
||||||
|
@ -26,6 +25,14 @@
|
||||||
"fzaninotto/faker": "^1.5"
|
"fzaninotto/faker": "^1.5"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"conflict": {
|
||||||
|
"symfony/propel1-bridge": ">=2.8.0"
|
||||||
|
},
|
||||||
|
|
||||||
|
"replace": {
|
||||||
|
"symfony/propel1-bridge": "<=2.8.0"
|
||||||
|
},
|
||||||
|
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/security-acl": "For using the Propel ACL implementation"
|
"symfony/security-acl": "For using the Propel ACL implementation"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,34 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<phpunit backupGlobals="false"
|
<phpunit backupGlobals="false"
|
||||||
backupStaticAttributes="false"
|
backupStaticAttributes="false"
|
||||||
colors="true"
|
colors="true"
|
||||||
convertErrorsToExceptions="true"
|
convertErrorsToExceptions="true"
|
||||||
convertNoticesToExceptions="true"
|
convertNoticesToExceptions="true"
|
||||||
convertWarningsToExceptions="true"
|
convertWarningsToExceptions="true"
|
||||||
processIsolation="false"
|
processIsolation="false"
|
||||||
stopOnFailure="false"
|
stopOnFailure="false"
|
||||||
syntaxCheck="false"
|
syntaxCheck="false"
|
||||||
bootstrap="./Tests/bootstrap.php">
|
bootstrap="vendor/autoload.php">
|
||||||
<php>
|
|
||||||
<!-- <server name="SYMFONY" value="/path/to/symfony" /> -->
|
<php>
|
||||||
</php>
|
<ini name="error_reporting" value="E_ALL ^ E_DEPRECATED"/>
|
||||||
<testsuites>
|
<includePath>vendor/phing/phing/classes</includePath>
|
||||||
<testsuite name="PropelBundle Test Suite">
|
</php>
|
||||||
<directory suffix="Test.php">./Tests</directory>
|
|
||||||
</testsuite>
|
<testsuites>
|
||||||
</testsuites>
|
<testsuite name="PropelBundle Test Suite">
|
||||||
<filter>
|
<directory suffix="Test.php">./Tests</directory>
|
||||||
<whitelist>
|
</testsuite>
|
||||||
<directory>./</directory>
|
</testsuites>
|
||||||
<exclude>
|
|
||||||
<directory>./Tests</directory>
|
<filter>
|
||||||
<directory>./vendor</directory>
|
<whitelist>
|
||||||
<directory>./Resources</directory>
|
<directory>./</directory>
|
||||||
</exclude>
|
<exclude>
|
||||||
</whitelist>
|
<directory>./Tests</directory>
|
||||||
</filter>
|
<directory>./vendor</directory>
|
||||||
|
<directory>./Resources</directory>
|
||||||
|
</exclude>
|
||||||
|
</whitelist>
|
||||||
|
</filter>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
Loading…
Reference in a new issue