124 lines
3.5 KiB
PHP
124 lines
3.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service;
|
|
|
|
use App\BusProNet\Model\XmlExportInfo;
|
|
use App\Model\BpnXmlSyncTarget;
|
|
use League\Flysystem\FilesystemException;
|
|
use League\Flysystem\FilesystemOperator;
|
|
use League\Flysystem\StorageAttributes;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
|
|
|
final class BpnXmlSyncManager
|
|
{
|
|
private const CACHE_TAGS_TO_INVALIDATE = [
|
|
'xml-sync',
|
|
];
|
|
|
|
public function __construct(
|
|
private readonly FilesystemOperator $xmlSource,
|
|
private readonly FilesystemOperator $xmlExport,
|
|
private readonly TagAwareCacheInterface $bpnCache,
|
|
private readonly LoggerInterface $logger,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @return list<BpnXmlSyncTarget>
|
|
*/
|
|
public function getSyncTargets(): array
|
|
{
|
|
return [
|
|
new BpnXmlSyncTarget('travel', $this->xmlSource, $this->xmlExport),
|
|
];
|
|
}
|
|
|
|
public function readRemoteInfo(FilesystemOperator $source, string $datasetName): ?XmlExportInfo
|
|
{
|
|
try {
|
|
$content = $source->read(XmlExportInfo::getFilename());
|
|
|
|
return XmlExportInfo::fromString($content);
|
|
} catch (FilesystemException|\InvalidArgumentException $e) {
|
|
$this->logger->warning('Could not read remote info file, likely being updated', [
|
|
'dataset' => $datasetName,
|
|
'exception' => $e->getMessage(),
|
|
]);
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public function readLocalInfo(FilesystemOperator $destination): ?XmlExportInfo
|
|
{
|
|
try {
|
|
if (false === $destination->fileExists(XmlExportInfo::getFilename())) {
|
|
return null;
|
|
}
|
|
|
|
$content = $destination->read(XmlExportInfo::getFilename());
|
|
|
|
return XmlExportInfo::fromString($content);
|
|
} catch (FilesystemException|\InvalidArgumentException) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return array{updated:int,deleted:int}
|
|
*
|
|
* @throws FilesystemException
|
|
*/
|
|
public function syncFiles(
|
|
FilesystemOperator $source,
|
|
FilesystemOperator $destination,
|
|
?callable $onStart = null,
|
|
?callable $onProgress = null,
|
|
): array {
|
|
$remoteFiles = $source
|
|
->listContents('.')
|
|
->filter(fn (StorageAttributes $attributes) => $attributes->isFile())
|
|
->map(fn (StorageAttributes $attributes) => $attributes->path())
|
|
->toArray();
|
|
|
|
$localFiles = $destination
|
|
->listContents('.')
|
|
->filter(fn (StorageAttributes $attributes) => $attributes->isFile())
|
|
->map(fn (StorageAttributes $attributes) => $attributes->path())
|
|
->toArray();
|
|
|
|
$filesToDelete = array_diff($localFiles, $remoteFiles);
|
|
|
|
if (null !== $onStart) {
|
|
$onStart(count($remoteFiles));
|
|
}
|
|
|
|
foreach ($remoteFiles as $path) {
|
|
$content = $source->read($path);
|
|
$destination->write($path, $content);
|
|
if (null !== $onProgress) {
|
|
$onProgress();
|
|
}
|
|
}
|
|
|
|
foreach ($filesToDelete as $path) {
|
|
$destination->delete($path);
|
|
}
|
|
|
|
return [
|
|
'updated' => count($remoteFiles),
|
|
'deleted' => count($filesToDelete),
|
|
];
|
|
}
|
|
|
|
public function invalidateCaches(): int
|
|
{
|
|
$this->bpnCache->invalidateTags(self::CACHE_TAGS_TO_INVALIDATE);
|
|
|
|
return count(self::CACHE_TAGS_TO_INVALIDATE);
|
|
}
|
|
}
|