Skip to content

Commit db0a995

Browse files
committed
Merge PR #47 from Baachi/doctrine
2 parents d930e8d + ed12b9c commit db0a995

File tree

15 files changed

+434
-6
lines changed

15 files changed

+434
-6
lines changed

.travis.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ env:
1010
- SYMFONY_VERSION=2.1.*
1111
- SYMFONY_VERSION=2.2.*
1212
- SYMFONY_VERSION=2.3.*
13+
- SYMFONY_VERSION=2.4.*
1314
- SYMFONY_VERSION=dev-master
1415

1516
matrix:
@@ -18,8 +19,9 @@ matrix:
1819

1920

2021
before_script:
21-
- curl -s http://getcomposer.org/installer | php
22-
- php composer.phar require symfony/framework-bundle:${SYMFONY_VERSION} --no-update
23-
- php composer.phar update
22+
- composer require symfony/framework-bundle:${SYMFONY_VERSION} --no-update
23+
# This command must be run with `--prefer-source`, otherwise the `Doctrine\Tests\OrmTestCase` class
24+
# won't be found.
25+
- composer update --prefer-source
2426

2527
script: phpunit --coverage-text

Doctrine/ORM/GeocoderListener.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
namespace Bazinga\Bundle\GeocoderBundle\Doctrine\ORM;
4+
5+
use Doctrine\Common\EventSubscriber;
6+
use Doctrine\ORM\Events;
7+
use Doctrine\ORM\Event\OnFlushEventArgs;
8+
9+
use Bazinga\Bundle\GeocoderBundle\Mapping\Driver\DriverInterface;
10+
use Geocoder\Geocoder;
11+
12+
/**
13+
* @author Markus Bachmann <[email protected]>
14+
*/
15+
class GeocoderListener implements EventSubscriber
16+
{
17+
private $driver;
18+
19+
private $geocoder;
20+
21+
public function __construct(Geocoder $geocoder, DriverInterface $driver)
22+
{
23+
$this->driver = $driver;
24+
$this->geocoder = $geocoder;
25+
}
26+
27+
/**
28+
* {@inheritDoc}
29+
*/
30+
public function getSubscribedEvents()
31+
{
32+
return array(
33+
Events::onFlush
34+
);
35+
}
36+
37+
public function onFlush(OnFlushEventArgs $args)
38+
{
39+
$em = $args->getEntityManager();
40+
$uow = $em->getUnitOfWork();
41+
42+
foreach ($uow->getScheduledEntityInsertions() as $entity) {
43+
if (!$this->driver->isGeocodeable($entity)) {
44+
continue;
45+
}
46+
47+
$this->geocodeEntity($entity);
48+
49+
$uow->recomputeSingleEntityChangeSet(
50+
$em->getClassMetadata(get_class($entity)),
51+
$entity
52+
);
53+
}
54+
55+
foreach ($uow->getScheduledEntityUpdates() as $entity) {
56+
if (!$this->driver->isGeocodeable($entity)) {
57+
continue;
58+
}
59+
60+
$this->geocodeEntity($entity);
61+
62+
$uow->recomputeSingleEntityChangeSet(
63+
$em->getClassMetadata(get_class($entity)),
64+
$entity
65+
);
66+
}
67+
}
68+
69+
private function geocodeEntity($entity)
70+
{
71+
$metadata = $this->driver->loadMetadataFromObject($entity);
72+
$address = $metadata->addressProperty->getValue($entity);
73+
$result = $this->geocoder->geocode($address);
74+
75+
$metadata->latitudeProperty->setValue($entity, $result['latitude']);
76+
$metadata->longitudeProperty->setValue($entity, $result['longitude']);
77+
}
78+
}

Mapping/Annotations/Address.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Bazinga\Bundle\GeocoderBundle\Mapping\Annotations;
4+
5+
/**
6+
* @author Markus Bachmann <[email protected]>
7+
*
8+
* @Annotation
9+
*/
10+
class Address
11+
{
12+
13+
}

Mapping/Annotations/Geocodeable.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Bazinga\Bundle\GeocoderBundle\Mapping\Annotations;
4+
5+
/**
6+
* @author Markus Bachmann <[email protected]>
7+
*
8+
* @Annotation
9+
*/
10+
class Geocodeable
11+
{
12+
}

Mapping/Annotations/Latitude.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Bazinga\Bundle\GeocoderBundle\Mapping\Annotations;
4+
5+
/**
6+
* @author Markus Bachmann <[email protected]>
7+
*
8+
* @Annotation
9+
*/
10+
class Latitude
11+
{
12+
}

Mapping/Annotations/Longitude.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Bazinga\Bundle\GeocoderBundle\Mapping\Annotations;
4+
5+
/**
6+
* @author Markus Bachmann <[email protected]>
7+
*
8+
* @Annotation
9+
*/
10+
class Longitude
11+
{
12+
}

Mapping/ClassMetadata.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Bazinga\Bundle\GeocoderBundle\Mapping;
4+
5+
/**
6+
* @author Markus Bachmann <[email protected]>
7+
*/
8+
class ClassMetadata
9+
{
10+
/**
11+
* @var \ReflectionProperty
12+
*/
13+
public $addressProperty;
14+
15+
/**
16+
* @var \ReflectionProperty
17+
*/
18+
public $latitudeProperty;
19+
20+
/**
21+
* @var \ReflectionProperty
22+
*/
23+
public $longitudeProperty;
24+
}

Mapping/Driver/AnnotationDriver.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace Bazinga\Bundle\GeocoderBundle\Mapping\Driver;
4+
5+
use Doctrine\Common\Annotations\Reader;
6+
use Bazinga\Bundle\GeocoderBundle\Mapping\Exception;
7+
use Bazinga\Bundle\GeocoderBundle\Mapping\Annotations;
8+
use Bazinga\Bundle\GeocoderBundle\Mapping\ClassMetadata;
9+
10+
/**
11+
* @author Markus Bachmann <[email protected]>
12+
*/
13+
class AnnotationDriver implements DriverInterface
14+
{
15+
private $reader;
16+
17+
public function __construct(Reader $reader)
18+
{
19+
$this->reader = $reader;
20+
}
21+
22+
public function isGeocodeable($object)
23+
{
24+
$reflection = new \ReflectionObject($object);
25+
26+
return !!$this->reader->getClassAnnotation($reflection, 'Bazinga\\Bundle\\GeocoderBundle\\Mapping\\Annotations\\Geocodeable');
27+
}
28+
29+
public function loadMetadataFromObject($object)
30+
{
31+
$reflection = new \ReflectionObject($object);
32+
if (!$annotation = $this->reader->getClassAnnotation($reflection, 'Bazinga\\Bundle\\GeocoderBundle\\Mapping\\Annotations\\Geocodeable')) {
33+
throw new Exception\MappingException(sprintf(
34+
'The class %s is not geocodeable', get_class($object)
35+
));
36+
}
37+
38+
$metadata = new ClassMetadata();
39+
40+
foreach ($reflection->getProperties() as $property) {
41+
foreach ($this->reader->getPropertyAnnotations($property) as $annotation) {
42+
if ($annotation instanceof Annotations\Latitude) {
43+
$property->setAccessible(true);
44+
$metadata->latitudeProperty = $property;
45+
} elseif ($annotation instanceof Annotations\Longitude) {
46+
$property->setAccessible(true);
47+
$metadata->longitudeProperty = $property;
48+
} elseif ($annotation instanceof Annotations\Address) {
49+
$property->setAccessible(true);
50+
$metadata->addressProperty = $property;
51+
}
52+
}
53+
}
54+
55+
return $metadata;
56+
}
57+
}

Mapping/Driver/DriverInterface.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
/**
3+
* @author Markus Bachmann <[email protected]>
4+
*/
5+
6+
namespace Bazinga\Bundle\GeocoderBundle\Mapping\Driver;
7+
8+
interface DriverInterface
9+
{
10+
public function isGeocodeable($object);
11+
12+
public function loadMetadataFromObject($object);
13+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Bazinga\Bundle\GeocoderBundle\Mapping\Exception;
4+
5+
/**
6+
* @author Markus Bachmann <[email protected]>
7+
*/
8+
class MappingException extends \Exception
9+
{
10+
}

0 commit comments

Comments
 (0)