8000 [PropertyInfo] Import the component · symfony/symfony@f1eb185 · GitHub
[go: up one dir, main page]

Skip to content

Commit f1eb185

Browse files
dunglasfabpot
authored andcommitted
[PropertyInfo] Import the component
1 parent d1ae400 commit f1eb185

29 files changed

+2306
-1
lines changed

composer.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"symfony/options-resolver": "self.version",
4949
"symfony/process": "self.version",
5050
"symfony/property-access": "self.version",
51+
"symfony/property-info": "self.version",
5152
"symfony/proxy-manager-bridge": "self.version",
5253
"symfony/routing": "self.version",
5354
"symfony/security": "self.version",
@@ -76,7 +77,11 @@
7677
"monolog/monolog": "~1.11",
7778
"ircmaxell/password-compat": "~1.0",
7879
"ocramius/proxy-manager": "~0.4|~1.0",
79-
"egulias/email-validator": "~1.2"
80+
"egulias/email-validator": "~1.2",
81+
"phpdocumentor/reflection": "^1.0.7"
82+
},
83+
"conflict": {
84+
"phpdocumentor/reflection": "<1.0.7"
8085
},
8186
"autoload": {
8287
"psr-4": {
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\PropertyInfo;
13+
14+
use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory;
15+
use Doctrine\Common\Persistence\Mapping\MappingException;
16+
use Doctrine\ORM\Mapping\ClassMetadataInfo;
17+
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
18+
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
19+
use Symfony\Component\PropertyInfo\Type;
20+
21+
/**
22+
* Extracts data using Doctrine ORM and ODM metadata.
23+
*
24+
* @author Kévin Dunglas <dunglas@gmail.com>
25+
*/
26+
class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface
27+
{
28+
/**
29+
* @var ClassMetadataFactory
30+
*/
31+
private $classMetadataFactory;
32+
33+
public function __construct(ClassMetadataFactory $classMetadataFactory)
34+
{
35+
$this->classMetadataFactory = $classMetadataFactory;
36+
}
37+
38+
/**
39+
* {@inheritdoc}
40+
*/
41+
public function getProperties($class, array $context = array())
42+
{
43+
try {
44+
$metadata = $this->classMetadataFactory->getMetadataFor($class);
45+
} catch (MappingException $exception) {
46+
return;
47+
}
48+
49+
return array_merge($metadata->getFieldNames(), $metadata->getAssociationNames());
50+
}
51+
52+
/**
53+
* {@inheritdoc}
54+
*/
55+
public function getTypes($class, $property, array $context = array())
56+
{
57+
try {
58+
$metadata = $this->classMetadataFactory->getMetadataFor($class);
59+
} catch (MappingException $exception) {
60+
return;
61+
}
62+
63+
if ($metadata->hasAssociation($property)) {
64+
$class = $metadata->getAssociationTargetClass($property);
65+
66+
if ($metadata->isSingleValuedAssociation($property)) {
67+
if ($metadata instanceof ClassMetadataInfo) {
68+
$nullable = isset($metadata->discriminatorColumn['nullable']) ? $metadata->discriminatorColumn['nullable'] : false;
69+
} else {
70+
$nullable = false;
71+
}
72+
73+
return array(new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $class));
74+
}
75+
76+
return array(new Type(
77+
Type::BUILTIN_TYPE_OBJECT,
78+
false,
79+
'Doctrine\Common\Collections\Collection',
80+
true,
81+
new Type(Type::BUILTIN_TYPE_INT),
82+
new Type(Type::BUILTIN_TYPE_OBJECT, false, $class)
83+
));
84+
}
85+
86+
if ($metadata->hasField($property)) {
87+
$typeOfField = $metadata->getTypeOfField($property);
88+
$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);
89+
90+
switch ($typeOfField) {
91+
case 'date':
92+
case 'datetime':
93+
case 'datetimetz':
94+
case 'time':
95+
return array(new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTime'));
96+
97+
case 'array':
98+
return array(new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true));
99+
100+
case 'simple_array':
101+
return array(new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING)));
102+
103+
case 'json_array':
104+
return array(new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true));
105+
106+
default:
107+
return array(new Type($this->getPhpType($typeOfField), $nullable));
108+
}
109+
}
110+
}
111+
112+
/**
113+
* Gets the corresponding built-in PHP type.
114+
*
115+
* @param string $doctrineType
116+
*
117+
* @return string
118+
*/
119+
private function getPhpType($doctrineType)
120+
{
121+
switch ($doctrineType) {
122+
case 'smallint':
123+
// No break
124+
case 'bigint':
125+
// No break
126+
case 'integer':
127+
return Type::BUILTIN_TYPE_INT;
128+
129+
case 'decimal':
130+
return Type::BUILTIN_TYPE_FLOAT;
131+
132+
case 'text':
133+
// No break
134+
case 'guid':
135+
return Type::BUILTIN_TYPE_STRING;
136+
137+
case 'boolean':
138+
return Type::BUILTIN_TYPE_BOOL;
139+
140+
case 'blob':
141+
// No break
142+
case 'binary':
143+
return Type::BUILTIN_TYPE_RESOURCE;
144+
145+
default:
146+
return $doctrineType;
147+
}
148+
}
149+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\PropertyInfo\Tests;
13+
14+
use Doctrine\ORM\EntityManager;
15+
use Doctrine\ORM\Tools\Setup;
16+
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
17+
use Symfony\Component\PropertyInfo\Type;
18+
19+
/**
20+
* @author Kévin Dunglas <dunglas@gmail.com>
21+
*/
22+
class DoctrineExtractorTest extends \PHPUnit_Framework_TestCase
23+
{
24+
/**
25+
* @var DoctrineExtractor
26+
*/
27+
private $extractor;
28+
29+
public function setUp()
30+
{
31+
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'), true);
32+
$entityManager = EntityManager::create(array('driver' => 'pdo_sqlite'), $config);
33+
34+
$this->extractor = new DoctrineExtractor($entityManager->getMetadataFactory());
35+
}
36+
37+
public function testGetProperties()
38+
{
39+
$this->assertEquals(
40+
array(
41+
'id',
42+
'guid',
43+
'time',
44+
'json',
45+
'simpleArray',
46+
'bool',
47+
'binary',
48+
'foo',
49+
'bar',
50+
),
51+
$this->extractor->getProperties('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy')
52+
);
53+
}
54+
55+
/**
56+
* @dataProvider typesProvider
57+
*/
58+
public function testExtract($property, array $type = null)
59+
{
60+
$this->assertEquals($type, $this->extractor->getTypes('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy', $property, array()));
61+
}
62+
63+
public function typesProvider()
64+
{
65+
return array(
66+
array('id', array(new Type(Type::BUILTIN_TYPE_INT))),
67+
array('guid', array(new Type(Type::BUILTIN_TYPE_STRING))),
68+
array('bool', array(new Type(Type::BUILTIN_TYPE_BOOL))),
69+
array('binary', array(new Type(Type::BUILTIN_TYPE_RESOURCE))),
70+
array('json', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true))),
71+
array('foo', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation'))),
72+
array('bar', array(new Type(
73+
Type::BUILTIN_TYPE_OBJECT,
74+
false,
75+
'Doctrine\Common\Collections\Collection',
76+
true,
77+
new Type(Type::BUILTIN_TYPE_INT),
78+
new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation')
79+
))),
80+
array('simpleArray', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING)))),
81+
array('notMapped', null),
82+
);
83+
}
84+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
13+
14+
use Doctrine\ORM\Mapping\Column;
15+
use Doctrine\ORM\Mapping\Entity;
16+
use Doctrine\ORM\Mapping\Id;
17+
use Doctrine\ORM\Mapping\ManyToMany;
18+
use Doctrine\ORM\Mapping\ManyToOne;
19+
20+
/**
21+
* @Entity
22+
*
23+
* @author Kévin Dunglas <dunglas@gmail.com>
24+
*/
25+
class DoctrineDummy
26+
{
27+
/**
28+
* @Id
29+
* @Column(type="smallint")
30+
*/
31+
public $id;
32+
33+
/**
34+
* @ManyToOne(targetEntity="DoctrineRelation")
35+
*/
36+
public $foo;
37+
38+
/**
39+
* @ManyToMany(targetEntity="DoctrineRelation")
40+
*/
41+
public $bar;
42+
43+
/**
44+
* @Column(type="guid")
45+
*/
46+
protected $guid;
47+
48+
/**
49+
* @Column(type="time")
50+
*/
51+
private $time;
52+
53+
/**
54+
* @Column(type="json_array")
55+
*/
56+
private $json;
57+
58+
/**
59+
* @Column(type="simple_array")
60+
*/
61+
private $simpleArray;
62+
63+
/**
64+
* @Column(type="boolean")
65+
*/
66+
private $bool;
67+
68+
/**
69+
* @Column(type="binary")
70+
*/
71+
private $binary;
72+
73+
public $notMapped;
74+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
13+
14+
use Doctrine\ORM\Mapping\Column;
15+
use Doctrine\ORM\Mapping\Id;
16+
17+
/**
18+
* @Entity
19+
*
20+
* @author Kévin Dunglas <dunglas@gmail.com>
21+
*/
22+
class DoctrineRelation
23+
{
24+
/**
25+
* @Id
26+
* @Column(type="smallint")
27+
*/
28+
public $id;
29+
}

src/Symfony/Bridge/Doctrine/composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"symfony/form": "~2.8|~3.0.0",
2727
"symfony/http-kernel": "~2.2|~3.0.0",
2828
"symfony/property-access": "~2.3|~3.0.0",
29+
"symfony/property-info": "~2.8|3.0",
2930
"symfony/security": "~2.2|~3.0.0",
3031
"symfony/expression-language": "~2.2|~3.0.0",
3132
"symfony/validator": "~2.5,>=2.5.5|~3.0.0",
@@ -37,6 +38,7 @@
3738
"suggest": {
3839
"symfony/form": "",
3940
"symfony/validator": "",
41+
"symfony/property-info": "",
4042
"doctrine/data-fixtures": "",
4143
"doctrine/dbal": "",
4244
"doctrine/orm": ""

0 commit comments

Comments
 (0)
0