Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update sdk requirement #13

Merged
merged 4 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ jobs:
php_extensions: ctype curl dom hash iconv intl gd json mbstring openssl session simplexml xml zip zlib pdo_mysql exif
args: --no-plugins
- name: Php cs fixer
run: php ./vendor/bin/php-cs-fixer fix --dry-run src
run: php ./vendor/bin/php-cs-fixer fix --diff --dry-run src
- name: Phpstan
run: php ./vendor/bin/phpstan --memory-limit=1G analyse
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
- Open Sylius Admin, head to Configuration > Gally and configure the Gally endpoint (URL, credentials)
- Run this commands from your Sylius instance. This commands must be runned only once to synchronize the structure.
```shell
bin/console gally:structure-sync # Sync catalog et source field data with gally
bin/console gally:structure:sync # Sync catalog et source field data with gally
```
- Run a full index from Sylius to Gally. This command can be run only once. Afterwards, the modified products are automatically synchronized.
```shell
Expand All @@ -66,6 +66,10 @@
- At this step, you should be able to see your product and source field in the Gally backend.
- They should also appear in your Sylius frontend when searching or browsing categories.
- And you're done !
- You can also run the command to clean data that are not present in sylius anymore:
```shell
bin/console gally:structure:clean
```

## noUiSlider

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"require": {
"php": "^8.0",
"sylius/sylius": "^1.12",
"gally/gally-php-rest-sdk": "dev-perf-sourceField-api"
"gally/gally-php-rest-sdk": "1.3.0-alpha1"
},
"require-dev": {
"behat/behat": "^3.6.1",
Expand Down
65 changes: 65 additions & 0 deletions src/Command/StructureClean.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Gally to newer versions in the future.
*
* @package Gally
* @author Stephan Hochdörfer <[email protected]>, Gally Team <[email protected]>
* @copyright 2022-present Smile
* @license Open Software License v. 3.0 (OSL-3.0)
*/

declare(strict_types=1);

namespace Gally\SyliusPlugin\Command;

use Gally\SyliusPlugin\Synchronizer\AbstractSynchronizer;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class StructureClean extends Command
{
protected static $defaultName = 'gally:structure:clean';

/**
* @param AbstractSynchronizer[] $synchronizers
*/
public function __construct(
private iterable $synchronizers
) {
parent::__construct();
}

protected function configure(): void
{
$this->setDescription('Remove all entity from gally that not exist anymore on sylius side.')
->addOption('force', 'f', InputOption::VALUE_NONE, 'Really remove the listed entity from the gally.')
->addOption('quiet', 'q', InputOption::VALUE_NONE, 'Don\'t list deleted entities.');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('');
$isDryRun = !$input->getOption('force');
$isQuiet = $input->getOption('quiet');

if ($isDryRun) {
$output->writeln('<error>Running in dry run mode, add -f to really delete entities from Gally.</error>');
$output->writeln('');
}

foreach ($this->synchronizers as $synchronizer) {
$time = microtime(true);
$message = "<comment>Clean {$synchronizer->getEntityClass()}</comment>";
$output->writeln("$message ...");
$synchronizer->cleanAll($isDryRun, $isQuiet);
$time = number_format(microtime(true) - $time, 2);
$output->writeln(" Cleaned ($time)s\n");
}

return 0;
}
}
2 changes: 1 addition & 1 deletion src/Command/StructureSync.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

class StructureSync extends Command
{
protected static $defaultName = 'gally:structure-sync';
protected static $defaultName = 'gally:structure:sync';

/**
* @param AbstractSynchronizer[] $synchronizers
Expand Down
2 changes: 1 addition & 1 deletion src/Entity/GallyConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function getId(): ?int
return $this->id;
}

public function setId(int $id = null): void
public function setId(?int $id = null): void
{
$this->id = $id;
}
Expand Down
5 changes: 5 additions & 0 deletions src/Resources/config/services/commands.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,10 @@
<argument type="tagged_iterator" tag="gally.entity.indexer"/>
<tag name="console.command"/>
</service>

<service id="Gally\SyliusPlugin\Command\StructureClean">
<argument type="tagged_iterator" tag="gally.entity.synchronizer"/>
<tag name="console.command"/>
</service>
</services>
</container>
7 changes: 7 additions & 0 deletions src/Synchronizer/AbstractSynchronizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ public function fetchEntity(ModelInterface $entity): ?ModelInterface

abstract protected function getIdentity(ModelInterface $entity): string;

/**
* Remove all entity from gally that not exist anymore on sylius side.
*/
public function cleanAll(bool $dryRun = true, bool $quiet = false): void
{
}

protected function buildFetchAllParams(int $page): array
{
return [
Expand Down
60 changes: 42 additions & 18 deletions src/Synchronizer/CatalogSynchronizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ public function getIdentity(ModelInterface $entity): string
public function synchronizeAll(): void
{
$this->fetchEntities();

$this->catalogCodes = array_flip($this->getAllEntityCodes());
$this->localizedCatalogSynchronizer->fetchEntities();
$this->localizedCatalogCodes = array_flip($this->localizedCatalogSynchronizer->getAllEntityCodes());

// synchronize all channels where the Gally integration is active
$channels = $this->channelRepository->findBy(['gallyActive' => 1]);
Expand All @@ -75,18 +72,6 @@ public function synchronizeAll(): void
foreach ($channels as $channel) {
$this->synchronizeItem(['channel' => $channel]);
}

foreach (array_flip($this->localizedCatalogCodes) as $localizedCatalogCode) {
/** @var LocalizedCatalogCatalogRead $localizedCatalog */
$localizedCatalog = $this->localizedCatalogSynchronizer->getEntityFromApi($localizedCatalogCode);
$this->localizedCatalogSynchronizer->deleteEntity($localizedCatalog->getId());
}

foreach (array_flip($this->catalogCodes) as $catalogCode) {
/** @var CatalogCatalogRead $catalog */
$catalog = $this->getEntityFromApi($catalogCode);
$this->deleteEntity($catalog->getId());
}
}

public function synchronizeItem(array $params): ?ModelInterface
Expand All @@ -108,12 +93,51 @@ public function synchronizeItem(array $params): ?ModelInterface
'locale' => $locale,
'catalog' => $catalog,
]);
}

unset($this->localizedCatalogCodes[$this->localizedCatalogSynchronizer->getIdentity($localizedCatalog)]);
return $catalog;
}

public function cleanAll(bool $dryRun = true, bool $quiet = false): void
{
$this->fetchEntities();

$this->catalogCodes = array_flip($this->getAllEntityCodes());
$this->localizedCatalogSynchronizer->fetchEntities();
$this->localizedCatalogCodes = array_flip($this->localizedCatalogSynchronizer->getAllEntityCodes());

// Synchronize all channels where the Gally integration is active
$channels = $this->channelRepository->findBy(['gallyActive' => 1]);

/** @var Channel[] $channels */
foreach ($channels as $channel) {
/** @var LocaleInterface $locale */
foreach ($channel->getLocales() as $locale) {
unset($this->localizedCatalogCodes[$channel->getCode() . '_' . $locale->getCode()]);
}
unset($this->catalogCodes[$channel->getCode()]);
}

unset($this->catalogCodes[$this->getIdentity($catalog)]);
foreach (array_flip($this->localizedCatalogCodes) as $localizedCatalogCode) {
/** @var LocalizedCatalogCatalogRead $localizedCatalog */
$localizedCatalog = $this->localizedCatalogSynchronizer->getEntityFromApi($localizedCatalogCode);
if (!$quiet) {
echo " Delete localized catalog {$localizedCatalog->getId()}\n";
}
if (!$dryRun) {
$this->localizedCatalogSynchronizer->deleteEntity($localizedCatalog->getId());
}
}

return $catalog;
foreach (array_flip($this->catalogCodes) as $catalogCode) {
/** @var CatalogCatalogRead $catalog */
$catalog = $this->getEntityFromApi($catalogCode);
if (!$quiet) {
echo " Delete catalog {$catalog->getId()}\n";
}
if (!$dryRun) {
$this->deleteEntity($catalog->getId());
}
}
}
}
55 changes: 45 additions & 10 deletions src/Synchronizer/SourceFieldOptionSynchronizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ public function getIdentity(ModelInterface $entity): string

public function synchronizeAll(): void
{
$this->sourceFieldOptionCodes = array_flip($this->getAllEntityCodes());
$this->sourceFieldSynchronizer->fetchEntities();

$metadataName = strtolower((new \ReflectionClass(Product::class))->getShortName());
Expand All @@ -82,7 +81,6 @@ public function synchronizeAll(): void
/** @var ProductAttribute[] $attributes */
$attributes = $this->productAttributeRepository->findAll();
foreach ($attributes as $attribute) {
$options = [];
if ('select' === $attribute->getType()) {
$position = 0;
$configuration = $attribute->getConfiguration();
Expand Down Expand Up @@ -135,12 +133,6 @@ public function synchronizeAll(): void
}

$this->runBulk();

foreach (array_flip($this->sourceFieldOptionCodes) as $sourceFieldOptionCode) {
/** @var SourceFieldOptionSourceFieldOptionRead $sourceFieldOption */
$sourceFieldOption = $this->getEntityFromApi($sourceFieldOptionCode);
$this->deleteEntity($sourceFieldOption->getId());
}
}

public function synchronizeItem(array $params): ?ModelInterface
Expand Down Expand Up @@ -173,11 +165,54 @@ public function synchronizeItem(array $params): ?ModelInterface
$sourceFieldOption = new SourceFieldOptionSourceFieldOptionWrite($data);
$this->addEntityToBulk($sourceFieldOption);

unset($this->sourceFieldOptionCodes[$this->getIdentity($sourceFieldOption)]);

return $sourceFieldOption;
}

public function cleanAll(bool $dryRun = true, bool $quiet = false): void
{
$this->sourceFieldOptionCodes = array_flip($this->getAllEntityCodes());
$this->sourceFieldSynchronizer->fetchEntities();

$metadataName = strtolower((new \ReflectionClass(Product::class))->getShortName());
/** @var MetadataMetadataRead $metadata */
$metadata = $this->metadataSynchronizer->synchronizeItem(['entity' => $metadataName]);

/** @var ProductAttribute[] $attributes */
$attributes = $this->productAttributeRepository->findAll();
foreach ($attributes as $attribute) {
if ('select' === $attribute->getType()) {
/** @var SourceFieldSourceFieldRead $sourceField */
$sourceField = $this->sourceFieldSynchronizer->getEntityByCode($metadata, $attribute->getCode());
$configuration = $attribute->getConfiguration();
foreach ($configuration['choices'] ?? [] as $code => $choice) {
unset($this->sourceFieldOptionCodes['/source_fields/' . $sourceField->getId() . $code]);
}
}
}

/** @var ProductOption[] $options */
$options = $this->productOptionRepository->findAll();
foreach ($options as $option) {
/** @var SourceFieldSourceFieldRead $sourceField */
$sourceField = $this->sourceFieldSynchronizer->getEntityByCode($metadata, $option->getCode());
/** @var ProductOptionValueInterface $value */
foreach ($option->getValues() as $value) {
unset($this->sourceFieldOptionCodes['/source_fields/' . $sourceField->getId() . $value->getCode()]);
}
}

foreach (array_flip($this->sourceFieldOptionCodes) as $sourceFieldOptionCode) {
/** @var SourceFieldOptionSourceFieldOptionRead $sourceFieldOption */
$sourceFieldOption = $this->getEntityFromApi($sourceFieldOptionCode);
if (!$quiet) {
echo " Delete sourceFieldOption {$sourceFieldOption->getSourceField()} {$sourceFieldOption->getCode()}\n";
}
if (!$dryRun) {
$this->deleteEntity($sourceFieldOption->getId());
}
}
}

public function fetchEntity(ModelInterface $entity): ?ModelInterface
{
/** @var SourceFieldOptionSourceFieldOptionWrite $entity */
Expand Down
Loading
Loading