Skip to content

Commit

Permalink
Feature/import export product in csv (FriendsOfSylius#196)
Browse files Browse the repository at this point in the history
* add import/export of products

* use context in behat

* fix returns type

* enable products import/export behat tests

use (new) comma separator

add cli behat tests

update README.md

fix return type and typo

fix exportKeysAvailable

clean not need store data

importer add transformer

improve product import/export

update for new controller style

allow to remove product attribute value

update for sylius 1.4

* add images channels locals

add images channels locals

* upgrade feature for tests imports

fix phpstan version

* set length to product datas

* add variant price

* upgrade to clean code

* update channel price

* fix export images

* fix export images

* fix export images

* fix export price

* use ImportResultLoggerInterface

* fix ImporterResultInterface
  • Loading branch information
oallain authored and stefandoorn committed Jul 26, 2019
1 parent 75e7ad3 commit 0557db8
Show file tree
Hide file tree
Showing 51 changed files with 1,684 additions and 19 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,14 @@ fos_sylius_import_export:
* payment_method (csv, excel, json)
* tax_category (csv, excel, json)
* customer (json)
* product (csv)

### Available exporter types

* country (csv, excel, json)
* order (csv, excel, json)
* customer (csv, excel, json)
* product (csv)

## Example import files

Expand Down
13 changes: 13 additions & 0 deletions features/export/cli/exporting_products_to_csv_via_cli.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@managing_products
Feature: exporting products to csv-file
In order to have my products exported to an external target
As a developer
I want to be able to export product data to csv file from the commandline

Background:
Given I have a working command-line interface

@cli_importer_exporter
Scenario: Exporting products to csv-file
When I export "product" data as "csv" to the file "products_export.csv" with the cli-command
Then I should see "Exported" in the output
17 changes: 17 additions & 0 deletions features/export/ui/exporting_products.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@managing_products
Feature: Export Products from grid
In order to have my products exported to an external target
As an Administrator
I want to be able to export product data to csv file from backOffice

Background:
Given I am logged in as an administrator
And the store has a product "T-shirt cool"

@ui
Scenario: Exporting products should export all of them
When I open the product admin index page
And I should see 1 products in the list
Then I go to "/admin/export/sylius.product/csv" homepage
And response should contain "Code,Locale,Name,Description,Short_description,Meta_description,Meta_keywords,Main_taxon,Taxons,Channels,Enabled"
And response should contain 'T_SHIRT_COOL,en_US,"T-shirt cool",,,,,,,,1'
21 changes: 21 additions & 0 deletions features/export/ui/exporting_products_with_attributs.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@managing_products
Feature: Export Products with attributes from grid
In order to have my products exported to an external target
As an Administrator
I want to be able to export product data and her attributes to csv file from backOffice

Background:
Given I am logged in as an administrator
And the store has a select product attribute "Attribute select" with values "select1" and "select2"
And the store has a product "T-shirt cool"
And this product has text attribute "Attribute text" with value "Banana"
And this product has textarea attribute "Attribute textarea" with value "Banana <br /> Bananaaaa !!!"
And this product has percent attribute "Attribute percent" with value 22%

@ui
Scenario: Exporting products should export all of them
When I open the product admin index page
And I should see 1 products in the list
Then I go to "/admin/export/sylius.product/csv" homepage
And response should contain "Attribute_text,Attribute_textarea,Attribute_percent"
And response should contain 'Banana,"Banana <br /> Bananaaaa !!!",0.22'
16 changes: 16 additions & 0 deletions features/import/cli/importing_products_from_csv_via_cli.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@managing_products
Feature: Importing products from csv with the command-line interface
In order to have my products from external source
As a developer
I want to be able to import data from csv file from the commandline

Background:
Given I have a working command-line interface

@cli_importer_exporter
Scenario: Importing defined products with the cli-command
When I import "product" data from csv file "products.csv" file with the cli-command
Then I should see "Imported" in the output
And I should have at least the following product ids in the database:
| 123456 |
| 222333 |
17 changes: 17 additions & 0 deletions features/import/ui/importing_products.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@managing_products
Feature: Import Products from grid
In order to have my products exported to an external target
As an Administrator
I want to be able to import product data to csv file from backOffice

Background:
Given I am logged in as an administrator

@ui
Scenario: Import products should create all of them
When I open the product admin index page
And I import product data from "products.csv" csv file
Then I should see a notification that the import was successful
And I should see 2 products in the list
And the first product on the list should have name "Product 1"
And the last product on the list should have name "Product 2"
19 changes: 19 additions & 0 deletions features/import/ui/importing_products_update.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@managing_products
Feature: Import Products from grid
In order to have my products exported to an external target
As an Administrator
I want to be able to import product data to csv file from backOffice

Background:
Given I am logged in as an administrator

@ui
Scenario: Import products should update them
When I open the product admin index page
And I import product data from "products.csv" csv file
Then I should see a notification that the import was successful
And I import product data from "products_update.csv" csv file
Then I should see a notification that the import was successful
And I should see 2 products in the list
And the first product on the list should have name "Product 1"
And the last product on the list should have name "Product 2 update"
21 changes: 21 additions & 0 deletions features/import/ui/importing_products_with_attributes.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@managing_products
Feature: Import Products with attributes from grid
In order to have my products exported to an external target
As an Administrator
I want to be able to import product data and her attributes to csv file from backOffice

Background:
Given I am logged in as an administrator
Given the store has locale "en_US"
And the store has a text product attribute "Attribute text"
And the store has a textarea product attribute "Attribute textarea"
And the store has a percent product attribute "Attribute percent"

@ui
Scenario: Exporting products should export all of them
When I open the product admin index page
And I import product data from "products_attr.csv" csv file
Then I should see a notification that the import was successful
And I should see 2 products in the list
Then the product "Product 1" should appear in the registry
And attribute "Attribute text" of product "Product 1" should be "Banana" in "en_US"
53 changes: 53 additions & 0 deletions spec/Exporter/Transformer/Handler/ArrayToStringHandlerSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace spec\FriendsOfSylius\SyliusImportExportPlugin\Exporter\Transformer\Handler;

use FriendsOfSylius\SyliusImportExportPlugin\Exporter\Transformer\Handler;
use FriendsOfSylius\SyliusImportExportPlugin\Exporter\Transformer\Handler\ArrayToStringHandler;
use FriendsOfSylius\SyliusImportExportPlugin\Exporter\Transformer\HandlerInterface;
use FriendsOfSylius\SyliusImportExportPlugin\Exporter\Transformer\Pool;
use PhpSpec\ObjectBehavior;
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Webmozart\Assert\Assert;

class ArrayToStringHandlerSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(ArrayToStringHandler::class);
}

function it_extends()
{
$this->shouldHaveType(Handler::class);
}

function it_should_implement()
{
$this->shouldImplement(HandlerInterface::class);
}

function it_should_process_directly()
{
$array = ['a', 'b', 'c'];
$this->handle('test', $array)->shouldBeString();
$this->handle('test', $array)->shouldBe('a|b|c');
}

function it_should_process_via_pool()
{
$array = ['a', 'b', 'c'];

$generator = new RewindableGenerator(function () {
return [$this->getWrappedObject()];
}, $count = 1);

$pool = new Pool($generator);

$result = $pool->handle('test', $array);

Assert::same('a|b|c', $result);
}
}
5 changes: 3 additions & 2 deletions spec/Importer/ImporterResultSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@

use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImporterResult;
use PhpSpec\ObjectBehavior;
use Psr\Log\LoggerInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\Stopwatch\StopwatchEvent;

class ImporterResultSpec extends ObjectBehavior
{
function let(Stopwatch $stopwatch)
function let(Stopwatch $stopwatch, LoggerInterface $logger)
{
$this->beConstructedWith($stopwatch);
$this->beConstructedWith($stopwatch, $logger);
}

function it_is_initializable()
Expand Down
3 changes: 2 additions & 1 deletion spec/Importer/JsonResourceImporterSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Doctrine\Common\Persistence\ObjectManager;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImporterResultInterface;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImportResultLoggerInterface;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\JsonResourceImporter;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\ResourceImporter;
use FriendsOfSylius\SyliusImportExportPlugin\Processor\ResourceProcessorInterface;
Expand All @@ -17,7 +18,7 @@ class JsonResourceImporterSpec extends ObjectBehavior
function let(
ObjectManager $objectManager,
ResourceProcessorInterface $resourceProcessor,
ImporterResultInterface $importerResult
ImportResultLoggerInterface $importerResult
) {
$this->beConstructedWith($objectManager, $resourceProcessor, $importerResult, 0, false, false);
}
Expand Down
3 changes: 2 additions & 1 deletion spec/Importer/ResourceImporterSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\Common\Persistence\ObjectManager;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImporterInterface;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImporterResultInterface;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImportResultLoggerInterface;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\ResourceImporter;
use FriendsOfSylius\SyliusImportExportPlugin\Processor\ResourceProcessorInterface;
use PhpSpec\ObjectBehavior;
Expand All @@ -21,7 +22,7 @@ function let(
ReaderFactory $readerFactory,
ObjectManager $objectManager,
ResourceProcessorInterface $resourceProcessor,
ImporterResultInterface $importerResult
ImportResultLoggerInterface $importerResult
) {
$this->beConstructedWith($readerFactory, $objectManager, $resourceProcessor, $importerResult, false, false, false);
}
Expand Down
15 changes: 14 additions & 1 deletion src/Controller/ImportDataController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use FriendsOfSylius\SyliusImportExportPlugin\Form\ImportType;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImporterInterface;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImporterRegistry;
use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImporterResult;
use Sylius\Component\Registry\ServiceRegistryInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
Expand Down Expand Up @@ -84,14 +85,22 @@ private function importData(string $importer, FormInterface $form): void
$this->flashBag->add('error', $message);
}

/** @var UploadedFile $file */
/** @var UploadedFile|null $file */
$file = $form->get('import-data')->getData();
/** @var ImporterInterface $service */
$service = $this->registry->get($name);

if (null === $file) {
throw new ImporterException('No file selected');
}

$path = $file->getRealPath();

if (false === $path) {
throw new ImporterException(sprintf('File %s could not be loaded', $file->getClientOriginalName()));
}

/** @var ImporterResult $result */
$result = $service->import($path);

$message = sprintf(
Expand All @@ -104,5 +113,9 @@ private function importData(string $importer, FormInterface $form): void
);

$this->flashBag->add('success', $message);

if ($result->getMessage() !== null) {
$this->flashBag->add('error', $result->getMessage());
}
}
}
12 changes: 6 additions & 6 deletions src/Exporter/Plugin/PluginPool.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@

class PluginPool implements PluginPoolInterface
{
/** @var PluginInterface[] */
private $plugins;

/** @var array */
private $exportKeys;
protected $exportKeys;

/** @var array */
private $exportKeysNotFound;
protected $exportKeysAvailable = [];

/** @var PluginInterface[] */
private $plugins;

/** @var array */
private $exportKeysAvailable = [];
private $exportKeysNotFound;

/**
* @param PluginInterface[] $plugins
Expand Down
35 changes: 35 additions & 0 deletions src/Exporter/Plugin/ProductPluginPool.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace FriendsOfSylius\SyliusImportExportPlugin\Exporter\Plugin;

use FriendsOfSylius\SyliusImportExportPlugin\Service\AttributeCodesProviderInterface;
use FriendsOfSylius\SyliusImportExportPlugin\Service\ImageTypesProviderInterface;

final class ProductPluginPool extends PluginPool
{
/** @var ImageTypesProviderInterface */
private $imageTypesProvider;
/** @var AttributeCodesProviderInterface */
private $attributeCodesProvider;

public function __construct(
array $plugins,
array $exportKeys,
AttributeCodesProviderInterface $attributeCodesProvider,
ImageTypesProviderInterface $imageTypesProvider
) {
parent::__construct($plugins, $exportKeys);
$this->attributeCodesProvider = $attributeCodesProvider;
$this->imageTypesProvider = $imageTypesProvider;
}

public function initPlugins(array $ids): void
{
$this->exportKeys = \array_merge($this->exportKeys, $this->attributeCodesProvider->getAttributeCodesList());
$this->exportKeys = \array_merge($this->exportKeys, $this->imageTypesProvider->getProductImagesCodesWithPrefixList());
$this->exportKeysAvailable = $this->exportKeys;
parent::initPlugins($ids);
}
}
Loading

0 comments on commit 0557db8

Please sign in to comment.