Skip to content

Commit

Permalink
dispatch events on import success / failure
Browse files Browse the repository at this point in the history
  • Loading branch information
dhirtzbruch committed Nov 20, 2023
1 parent f73b2a1 commit 9cb7949
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 6 deletions.
43 changes: 37 additions & 6 deletions src/EntityImporterManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@

namespace Fastbolt\EntityImporter;

use DateTime;
use Exception;
use Fastbolt\EntityImporter\Events\ImportFailureEvent;
use Fastbolt\EntityImporter\Events\ImportSuccessEvent;
use Fastbolt\EntityImporter\Exceptions\ImporterDefinitionNotFoundException;
use Fastbolt\EntityImporter\Exceptions\InvalidInputFormatException;
use Fastbolt\EntityImporter\Exceptions\SourceUnavailableException;
use Fastbolt\EntityImporter\Types\ImportResult;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Throwable;

class EntityImporterManager
Expand All @@ -24,13 +31,23 @@ class EntityImporterManager
*/
private EntityImporter $importer;

/**
* @var EventDispatcherInterface
*/
private EventDispatcherInterface $eventDispatcher;

/**
* @param EntityImporter $importer
* @param EventDispatcherInterface $eventDispatcher
* @param iterable<EntityImporterDefinition> $importerDefinitions
*/
public function __construct(EntityImporter $importer, iterable $importerDefinitions)
{
$this->importer = $importer;
public function __construct(
EntityImporter $importer,
EventDispatcherInterface $eventDispatcher,
iterable $importerDefinitions
) {
$this->importer = $importer;
$this->eventDispatcher = $eventDispatcher;

foreach ($importerDefinitions as $importerDefinition) {
$this->definitions[$importerDefinition->getName()] = $importerDefinition;
Expand All @@ -52,13 +69,27 @@ public function getImporterDefinitions(): array
* @param int|null $limit
*
* @return ImportResult
*
* @throws InvalidInputFormatException
* @throws SourceUnavailableException
*/
public function import(string $name, callable $statusCallback, callable $errorCallback, ?int $limit): ImportResult
{
if (!$name || null === ($definition = $this->definitions[$name] ?? null)) {
throw new ImporterDefinitionNotFoundException($name);
$start = new DateTime();
try {
if (!$name || null === ($definition = $this->definitions[$name] ?? null)) {
throw new ImporterDefinitionNotFoundException($name);
}

$return = $this->importer->import($definition, $statusCallback, $errorCallback, $limit);
} catch (Exception $exception) {
$this->eventDispatcher->dispatch(new ImportFailureEvent($definition, $start, $exception));

Check failure on line 86 in src/EntityImporterManager.php

View workflow job for this annotation

GitHub Actions / Psalm

PossiblyUndefinedVariable

src/EntityImporterManager.php:86:69: PossiblyUndefinedVariable: Possibly undefined variable $definition defined in try block (see https://psalm.dev/018)

Check failure on line 86 in src/EntityImporterManager.php

View workflow job for this annotation

GitHub Actions / Psalm

PossiblyUndefinedVariable

src/EntityImporterManager.php:86:69: PossiblyUndefinedVariable: Possibly undefined variable $definition defined in try block (see https://psalm.dev/018)

throw $exception;
}

return $this->importer->import($definition, $statusCallback, $errorCallback, $limit);
$this->eventDispatcher->dispatch(new ImportSuccessEvent($definition, $start, $return));

return $return;
}
}
70 changes: 70 additions & 0 deletions src/Events/ImportFailureEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

/**
* Copyright © Fastbolt Schraubengroßhandels GmbH.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Fastbolt\EntityImporter\Events;

use DateTimeInterface;
use Exception;
use Fastbolt\EntityImporter\EntityImporterDefinition;

class ImportFailureEvent
{
/**
* @var Exception
*/
private Exception $exception;

/**
* @var EntityImporterDefinition|null
*/
private ?EntityImporterDefinition $definition;

/**
* @var DateTimeInterface
*/
private DateTimeInterface $importStart;

/**
* @param EntityImporterDefinition|null $definition
* @param DateTimeInterface $importStart
* @param Exception $exception
*/
public function __construct(

Check warning on line 37 in src/Events/ImportFailureEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportFailureEvent.php#L37

Added line #L37 was not covered by tests
?EntityImporterDefinition $definition,
DateTimeInterface $importStart,
Exception $exception
) {
$this->definition = $definition;
$this->importStart = $importStart;
$this->exception = $exception;
}

Check warning on line 45 in src/Events/ImportFailureEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportFailureEvent.php#L42-L45

Added lines #L42 - L45 were not covered by tests

/**
* @return Exception
*/
public function getException(): Exception

Check warning on line 50 in src/Events/ImportFailureEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportFailureEvent.php#L50

Added line #L50 was not covered by tests
{
return $this->exception;

Check warning on line 52 in src/Events/ImportFailureEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportFailureEvent.php#L52

Added line #L52 was not covered by tests
}

/**
* @return EntityImporterDefinition|null
*/
public function getDefinition(): ?EntityImporterDefinition

Check warning on line 58 in src/Events/ImportFailureEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportFailureEvent.php#L58

Added line #L58 was not covered by tests
{
return $this->definition;

Check warning on line 60 in src/Events/ImportFailureEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportFailureEvent.php#L60

Added line #L60 was not covered by tests
}

/**
* @return DateTimeInterface
*/
public function getImportStart(): DateTimeInterface

Check warning on line 66 in src/Events/ImportFailureEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportFailureEvent.php#L66

Added line #L66 was not covered by tests
{
return $this->importStart;

Check warning on line 68 in src/Events/ImportFailureEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportFailureEvent.php#L68

Added line #L68 was not covered by tests
}
}
70 changes: 70 additions & 0 deletions src/Events/ImportSuccessEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

/**
* Copyright © Fastbolt Schraubengroßhandels GmbH.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Fastbolt\EntityImporter\Events;

use DateTimeInterface;
use Fastbolt\EntityImporter\EntityImporterDefinition;
use Fastbolt\EntityImporter\Types\ImportResult;

class ImportSuccessEvent
{
/**
* @var ImportResult
*/
private ImportResult $importResult;

/**
* @var EntityImporterDefinition
*/
private EntityImporterDefinition $definition;

/**
* @var DateTimeInterface
*/
private DateTimeInterface $importStart;

/**
* @param EntityImporterDefinition $definition
* @param DateTimeInterface $importStart
* @param ImportResult $importResult
*/
public function __construct(

Check warning on line 37 in src/Events/ImportSuccessEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportSuccessEvent.php#L37

Added line #L37 was not covered by tests
EntityImporterDefinition $definition,
DateTimeInterface $importStart,
ImportResult $importResult
) {
$this->definition = $definition;
$this->importStart = $importStart;
$this->importResult = $importResult;
}

Check warning on line 45 in src/Events/ImportSuccessEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportSuccessEvent.php#L42-L45

Added lines #L42 - L45 were not covered by tests

/**
* @return ImportResult
*/
public function getImportResult(): ImportResult

Check warning on line 50 in src/Events/ImportSuccessEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportSuccessEvent.php#L50

Added line #L50 was not covered by tests
{
return $this->importResult;

Check warning on line 52 in src/Events/ImportSuccessEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportSuccessEvent.php#L52

Added line #L52 was not covered by tests
}

/**
* @return EntityImporterDefinition
*/
public function getDefinition(): EntityImporterDefinition

Check warning on line 58 in src/Events/ImportSuccessEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportSuccessEvent.php#L58

Added line #L58 was not covered by tests
{
return $this->definition;

Check warning on line 60 in src/Events/ImportSuccessEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportSuccessEvent.php#L60

Added line #L60 was not covered by tests
}

/**
* @return DateTimeInterface
*/
public function getImportStart(): DateTimeInterface

Check warning on line 66 in src/Events/ImportSuccessEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportSuccessEvent.php#L66

Added line #L66 was not covered by tests
{
return $this->importStart;

Check warning on line 68 in src/Events/ImportSuccessEvent.php

View check run for this annotation

Codecov / codecov/patch

src/Events/ImportSuccessEvent.php#L68

Added line #L68 was not covered by tests
}
}
1 change: 1 addition & 0 deletions src/Reader/Factory/CsvReaderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class CsvReaderFactory implements ReaderFactoryInterface
* @param array<string,mixed> $options
*
* @return CsvReader
* @throws SourceUnavailableException
*/
public function getReader(EntityImporterDefinition $importerDefinition, array $options): CsvReader
{
Expand Down
3 changes: 3 additions & 0 deletions src/Reader/Factory/ReaderFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace Fastbolt\EntityImporter\Reader\Factory;

use Fastbolt\EntityImporter\EntityImporterDefinition;
use Fastbolt\EntityImporter\Exceptions\SourceUnavailableException;
use Fastbolt\EntityImporter\Reader\ReaderInterface;

interface ReaderFactoryInterface
Expand All @@ -18,6 +19,8 @@ interface ReaderFactoryInterface
* @param array<string,mixed> $options Array containing implementation-specific options
*
* @return ReaderInterface
*
* @throws SourceUnavailableException
*/
public function getReader(EntityImporterDefinition $importerDefinition, array $options): ReaderInterface;

Expand Down
2 changes: 2 additions & 0 deletions src/Reader/Factory/XlsxReaderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class XlsxReaderFactory implements ReaderFactoryInterface
* @param array<string,mixed> $options Array containing implementation-specific options
*
* @return XlsxReader
*
* @throws SourceUnavailableException
*/
public function getReader(EntityImporterDefinition $importerDefinition, array $options): XlsxReader
{
Expand Down
1 change: 1 addition & 0 deletions src/Resources/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ services:
Fastbolt\EntityImporter\EntityImporterManager:
$importer: '@Fastbolt\EntityImporter\EntityImporter'
$importerDefinitions: !tagged fastbolt.entity_importer.definition
$eventDispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'

Fastbolt\EntityImporter\Reader\Factory\ReaderFactoryManager:
$factories: !tagged fastbolt.entity_importer.reader_factory
Expand Down
17 changes: 17 additions & 0 deletions tests/unit/EntityImporterManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
use Fastbolt\EntityImporter\EntityImporter;
use Fastbolt\EntityImporter\EntityImporterDefinition;
use Fastbolt\EntityImporter\EntityImporterManager;
use Fastbolt\EntityImporter\Events\ImportFailureEvent;
use Fastbolt\EntityImporter\Events\ImportSuccessEvent;
use Fastbolt\EntityImporter\Exceptions\ImporterDefinitionNotFoundException;
use Fastbolt\TestHelpers\BaseTestCase;
use PHPUnit\Framework\MockObject\MockObject;
use stdClass;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

/**
* @covers \Fastbolt\EntityImporter\EntityImporterManager
Expand Down Expand Up @@ -46,10 +49,16 @@ class EntityImporterManagerTest extends BaseTestCase
*/
private $errorCallback;

/**
* @var EventDispatcherInterface|MockObject
*/
private $dispatcher;

public function testImport(): void
{
$manager = new EntityImporterManager(
$this->importer,
$this->dispatcher,
[
$this->definition1,
$this->definition2,
Expand All @@ -65,6 +74,9 @@ public function testImport(): void
$this->importer->expects(self::once())
->method('import')
->with($this->definition2, $this->statusCallback, $this->errorCallback);
$this->dispatcher->expects(self::once())
->method('dispatch')
->with(self::isInstanceOf(ImportSuccessEvent::class));

$result = $manager->import('importer:def2:name', $this->statusCallback, $this->errorCallback, null);
}
Expand All @@ -75,8 +87,12 @@ public function testImportInvalidType(): void
$this->expectExceptionMessage('Importer importer:def2:name not found.');
$manager = new EntityImporterManager(
$this->importer,
$this->dispatcher,
[]
);
$this->dispatcher->expects(self::once())
->method('dispatch')
->with(self::isInstanceOf(ImportFailureEvent::class));
self::assertSame([], $manager->getImporterDefinitions());
$manager->import('importer:def2:name', $this->statusCallback, $this->errorCallback, null);
}
Expand All @@ -86,6 +102,7 @@ protected function setUp(): void
parent::setUp();

$this->importer = $this->getMock(EntityImporter::class, ['import']);
$this->dispatcher = $this->getMock(EventDispatcherInterface::class);
$this->definition1 = $this->getMock(EntityImporterDefinition::class);
$this->definition2 = $this->getMock(EntityImporterDefinition::class);
$this->statusCallback = $this->getCallable();
Expand Down
10 changes: 10 additions & 0 deletions tests/unit/Events/ImportSuccessEventTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Fastbolt\EntityImporter\Tests\Unit\Events;

use Fastbolt\EntityImporter\Events\ImportSuccessEvent;
use Fastbolt\TestHelpers\BaseTestCase;

class ImportSuccessEventTest extends BaseTestCase {

}

0 comments on commit 9cb7949

Please sign in to comment.