Skip to content

Commit aee3948

Browse files
authored
Merge pull request #281 from norkunas/skip-geocoding
Skip geocoding if address has not changed
2 parents cddf5a9 + 5c3de90 commit aee3948

File tree

2 files changed

+82
-6
lines changed

2 files changed

+82
-6
lines changed

Doctrine/ORM/GeocoderListener.php

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Doctrine\Common\EventSubscriber;
1818
use Doctrine\ORM\Event\OnFlushEventArgs;
1919
use Doctrine\ORM\Events;
20+
use Doctrine\ORM\UnitOfWork;
2021
use Geocoder\Provider\Provider;
2122
use Geocoder\Query\GeocodeQuery;
2223

@@ -61,7 +62,10 @@ public function onFlush(OnFlushEventArgs $args)
6162
continue;
6263
}
6364

64-
$this->geocodeEntity($entity);
65+
/** @var ClassMetadata $metadata */
66+
$metadata = $this->driver->loadMetadataFromObject($entity);
67+
68+
$this->geocodeEntity($metadata, $entity);
6569

6670
$uow->recomputeSingleEntityChangeSet(
6771
$em->getClassMetadata(get_class($entity)),
@@ -74,7 +78,14 @@ public function onFlush(OnFlushEventArgs $args)
7478
continue;
7579
}
7680

77-
$this->geocodeEntity($entity);
81+
/** @var ClassMetadata $metadata */
82+
$metadata = $this->driver->loadMetadataFromObject($entity);
83+
84+
if (!$this->shouldGeocode($metadata, $uow, $entity)) {
85+
continue;
86+
}
87+
88+
$this->geocodeEntity($metadata, $entity);
7889

7990
$uow->recomputeSingleEntityChangeSet(
8091
$em->getClassMetadata(get_class($entity)),
@@ -83,11 +94,11 @@ public function onFlush(OnFlushEventArgs $args)
8394
}
8495
}
8596

86-
private function geocodeEntity($entity)
97+
/**
98+
* @param object $entity
99+
*/
100+
private function geocodeEntity(ClassMetadata $metadata, $entity)
87101
{
88-
/** @var ClassMetadata $metadata */
89-
$metadata = $this->driver->loadMetadataFromObject($entity);
90-
91102
if (null !== $metadata->addressGetter) {
92103
$address = $metadata->addressGetter->invoke($entity);
93104
} else {
@@ -106,4 +117,18 @@ private function geocodeEntity($entity)
106117
$metadata->longitudeProperty->setValue($entity, $result->getCoordinates()->getLongitude());
107118
}
108119
}
120+
121+
/**
122+
* @param object $entity
123+
*/
124+
private function shouldGeocode(ClassMetadata $metadata, UnitOfWork $unitOfWork, $entity): bool
125+
{
126+
if (null !== $metadata->addressGetter) {
127+
return true;
128+
}
129+
130+
$changeSet = $unitOfWork->getEntityChangeSet($entity);
131+
132+
return isset($changeSet[$metadata->addressProperty->getName()]);
133+
}
109134
}

Tests/Doctrine/ORM/GeocoderListenerTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
use Doctrine\Common\Annotations\SimpleAnnotationReader;
1919
use Doctrine\DBAL\DriverManager;
2020
use Doctrine\ORM\EntityManager;
21+
use Doctrine\ORM\Events;
2122
use Doctrine\ORM\Tools\SchemaTool;
2223
use Doctrine\Tests\DoctrineTestCase;
2324
use Doctrine\Tests\OrmTestCase;
2425
use Geocoder\Provider\Nominatim\Nominatim;
2526
use Http\Client\Curl\Client;
27+
use Psr\Http\Message\RequestInterface;
28+
use Psr\Http\Message\ResponseInterface;
2629
use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
2730

2831
/**
@@ -148,6 +151,39 @@ public function testPersistForEmptyProperty()
148151
$this->assertNull($dummy->latitude);
149152
$this->assertNull($dummy->longitude);
150153
}
154+
155+
public function testDoesNotGeocodeIfAddressNotChanged()
156+
{
157+
$this->em->getEventManager()->removeEventListener(Events::onFlush, $this->listener);
158+
159+
$reader = new SimpleAnnotationReader();
160+
$reader->addNamespace('Bazinga\GeocoderBundle\Mapping\Annotations');
161+
$reader->addNamespace('Doctrine\ORM\Mapping');
162+
163+
$driver = new AnnotationDriver($reader);
164+
165+
$client = new TrackedCurlClient();
166+
$geocoder = Nominatim::withOpenStreetMapServer($client, 'BazingaGeocoderBundle/Test');
167+
$listener = new GeocoderListener($geocoder, $driver);
168+
169+
$this->em->getEventManager()->addEventSubscriber($listener);
170+
171+
$dummy = new DummyWithProperty();
172+
$dummy->address = 'Frankfurt, Germany';
173+
174+
$this->em->persist($dummy);
175+
$this->em->flush();
176+
177+
$dummy->latitude = 0;
178+
$dummy->longitude = 0;
179+
180+
$this->em->flush();
181+
182+
$this->assertSame('Frankfurt, Germany', $dummy->address);
183+
$this->assertSame(0, $dummy->latitude);
184+
$this->assertSame(0, $dummy->longitude);
185+
$this->assertCount(1, $client->getResponses());
186+
}
151187
}
152188

153189
/**
@@ -337,3 +373,18 @@ class DummyWithEmptyProperty
337373
*/
338374
public $address;
339375
}
376+
377+
class TrackedCurlClient extends Client
378+
{
379+
private $responses = [];
380+
381+
public function sendRequest(RequestInterface $request): ResponseInterface
382+
{
383+
return $this->responses[] = parent::sendRequest($request);
384+
}
385+
386+
public function getResponses(): array
387+
{
388+
return $this->responses;
389+
}
390+
}

0 commit comments

Comments
 (0)