Initial Variation and Attribute implementations

This commit is contained in:
Paweł Jędrzejewski 2014-03-23 22:43:07 +01:00
parent 9656d73ff3
commit dde33cf4ac
431 changed files with 5106 additions and 3709 deletions

View file

@ -19,7 +19,7 @@ sylius_money:
currency: EUR
locale: en_US
sylius_payments:
sylius_payment:
gateways:
cc: Credit Card
test: Test

View file

@ -0,0 +1,145 @@
@products
Feature: Product attributes
In order to show specific product parameters to customer
As a store owner
I want to be able to configure product attributes
Background:
Given I am logged in as administrator
And there are following attributes:
| name | presentation |
| T-Shirt collection | Collection |
| T-Shirt fabric | T-Shirt fabric |
Scenario: Seeing index of all attributes
Given I am on the dashboard page
When I follow "Configure attributes"
Then I should be on the product attribute index page
And I should see 2 attributes in the list
Scenario: Seeing empty index of attributes
Given there are no product attributes
When I am on the product attribute index page
Then I should see "There are no attributes configured"
Scenario: Accessing the product attribute creation form
Given I am on the dashboard page
When I follow "Configure attributes"
And I follow "Create product attribute"
Then I should be on the product attribute creation page
Scenario: Submitting form without specifying the name
Given I am on the product attribute creation page
When I press "Create"
Then I should still be on the product attribute creation page
And I should see "Please enter attribute name"
Scenario: Submitting form without specifying the presentation
Given I am on the product attribute creation page
When I fill in "Internal name" with "Book author"
And I press "Create"
Then I should still be on the product attribute creation page
And I should see "Please enter attribute presentation"
Scenario: Creating new attribute
Given I am on the product attribute creation page
When I fill in "Internal name" with "Book author"
And I fill in "Presentation" with "Author"
And I press "Create"
Then I should still be on the product attribute index page
And I should see "Attribute has been successfully created."
Scenario: Created attributes appear in the list
Given I created attribute "Food"
When I go to the product attribute index page
Then I should see 3 attributes in the list
And I should see attribute with name "Food" in that list
Scenario: Accessing the editing form from the list
Given I am on the product attribute index page
When I click "edit" near "T-Shirt collection"
Then I should be editing product attribute "T-Shirt collection"
Scenario: Updating the attribute
Given I am editing product attribute "T-Shirt collection"
When I fill in "Internal name" with "T-Shirt edition"
And I press "Save changes"
Then I should still be on the product attribute index page
And I should see "Attribute has been successfully updated."
@javascript
Scenario: Deleted attribute disappears from the list
Given I am on the product attribute index page
When I click "delete" near "T-Shirt fabric"
And I click "delete" from the confirmation modal
Then I should still be on the product attribute index page
And I should see "Attribute has been successfully deleted."
And I should not see attribute with name "T-Shirt fabric" in that list
Scenario: Creating string attribute by default
Given I am on the product attribute creation page
When I fill in "Internal name" with "Book author"
And I fill in "Presentation" with "Author"
And I press "Create"
Then I should still be on the product attribute index page
And I should see "Attribute has been successfully created."
And product attribute with following data should be created:
| name | Book author |
| type | text |
Scenario Outline: Creating new attribute for type
Given I am on the product attribute creation page
When I fill in "Internal name" with "Book author"
And I fill in "Presentation" with "Author"
And I select "<label>" from "Type"
And I press "Create"
Then I should still be on the product attribute index page
And I should see "Attribute has been successfully created."
And product attribute with following data should be created:
| name | Book author |
| presentation | Author |
| type | <value> |
Examples:
| label | value |
| Checkbox | checkbox |
| Text | text |
| Choice | choice |
| Number | number |
@javascript
Scenario: Create new choice attribute with many choices
Given I am on the product attribute creation page
When I fill in "Internal name" with "Book author"
And I fill in "Presentation" with "Author"
And I select "Choice" from "Type"
And I click "Add choice"
And I fill in "Choice 0" with "J.R.R Tolken"
And I click "Add choice"
And I fill in "Choice 1" with "Jaroslaw Grzedowicz"
And I press "Create"
Then product attribute with following data should be created:
| name | Book author |
| presentation | Author |
| type | choice |
| choices | J.R.R Tolken,Jaroslaw Grzedowicz |
And I should see "Attribute has been successfully created."
@javascript
Scenario: Remove choice attribute choice
Given I am on the product attribute creation page
When I fill in "Internal name" with "Book author"
And I fill in "Presentation" with "Author"
And I select "Choice" from "Type"
And I click "Add choice"
And I fill in "Choice 0" with "J.R.R Tolken"
And I click "Add choice"
And I fill in "Choice 1" with "Jaroslaw Grzedowicz"
And I remove attribute choice number 0
And I press "Create"
Then product attribute with following data should be created:
| name | Book author |
| presentation | Author |
| type | choice |
| choices | Jaroslaw Grzedowicz |
And I should see "Attribute has been successfully created."

View file

@ -14,56 +14,56 @@ Feature: Product options
Scenario: Seeing index of all options
Given I am on the dashboard page
When I follow "Manage product options"
Then I should be on the option index page
Then I should be on the product option index page
And I should see 2 options in the list
Scenario: Option names are listed
Given I am on the dashboard page
When I follow "Manage product options"
Then I should be on the option index page
Then I should be on the product option index page
And I should see option with name "T-Shirt color" in the list
Scenario: Option presentation is displayed in the list
Given I am on the dashboard page
When I follow "Manage product options"
Then I should be on the option index page
Then I should be on the product option index page
And I should see option with presentation "Color" in the list
Scenario: Seeing empty index of options
Given there are no options
When I go to the option index page
Given there are no product options
When I go to the product option index page
Then I should see "There are no options configured"
Scenario: Accessing the option creation form
Given I am on the dashboard page
When I follow "Manage product options"
And I follow "Create option"
Then I should be on the option creation page
Then I should be on the product option creation page
Scenario: Submitting form without specifying the name
Given I am on the option creation page
Given I am on the product option creation page
When I press "Create"
Then I should still be on the option creation page
Then I should still be on the product option creation page
And I should see "Please enter option name."
Scenario: Submitting form without specifying the presentation
Given I am on the option creation page
Given I am on the product option creation page
When I fill in "Internal name" with "Bag color"
And I press "Create"
Then I should still be on the option creation page
Then I should still be on the product option creation page
And I should see "Please enter option presentation."
Scenario: Trying to create option without at least 2 values
Given I am on the option creation page
Given I am on the product option creation page
When I fill in "Internal name" with "Bag color"
And I fill in "Presentation" with "Color"
And I press "Create"
Then I should still be on the option creation page
Then I should still be on the product option creation page
And I should see "Please add at least 2 option values."
@javascript
Scenario: Creating option with 4 possible values
Given I am on the option creation page
Given I am on the product option creation page
When I fill in "Internal name" with "Bag color"
And I fill in "Presentation" with "Color"
And I add following option values:
@ -72,12 +72,12 @@ Feature: Product options
| Brown |
| Purple |
And I press "Create"
Then I should be on the option index page
Then I should be on the product option index page
And I should see "Option has been successfully created."
@javascript
Scenario: Values are listed after creating the option
Given I am on the option creation page
Given I am on the product option creation page
When I fill in "Internal name" with "Mug type"
And I fill in "Presentation" with "Type"
And I add following option values:
@ -85,42 +85,42 @@ Feature: Product options
| Large mug |
| MONSTER mug |
And I press "Create"
Then I should be on the option index page
Then I should be on the product option index page
And I should see option with value "Normal mug" in that list
@javascript
Scenario: Adding values to existing option
Given I am editing option "T-Shirt size"
Given I am editing product option "T-Shirt size"
And I add following option values:
| XL |
| XXL |
And I press "Save changes"
Then I should be on the option index page
Then I should be on the product option index page
And "Option has been successfully updated." should appear on the page
And I should see option with value "XXL" in the list
Scenario: Created options appear in the list
Given I created option "Hat size" with values "S, M, L"
When I go to the option index page
When I go to the product option index page
Then I should see 3 options in the list
And I should see option with name "Hat size" in that list
Scenario: Accessing the editing form from the list
Given I am on the option index page
Given I am on the product option index page
When I click "edit" near "T-Shirt color"
Then I should be editing option "T-Shirt color"
Then I should be editing product option "T-Shirt color"
Scenario: Updating the option
Given I am editing option "T-Shirt size"
Given I am editing product option "T-Shirt size"
When I fill in "Internal name" with "T-Shirt sex"
And I press "Save changes"
Then I should be on the option index page
Then I should be on the product option index page
And I should see "Option has been successfully updated."
@javascript
Scenario: Deleted option disappears from the list
Given I am on the option index page
Given I am on the product option index page
When I click "delete" near "T-Shirt color"
And I click "delete" from the confirmation modal
Then I should be on the option index page
Then I should be on the product option index page
And I should not see option with name "T-Shirt color" in that list

View file

@ -1,145 +0,0 @@
@products
Feature: Product properties
In order to show specific product parameters to customer
As a store owner
I want to be able to configure product properties
Background:
Given I am logged in as administrator
And there are following properties:
| name | presentation |
| T-Shirt collection | Collection |
| T-Shirt fabric | T-Shirt fabric |
Scenario: Seeing index of all properties
Given I am on the dashboard page
When I follow "Configure properties"
Then I should be on the property index page
And I should see 2 properties in the list
Scenario: Seeing empty index of properties
Given there are no properties
When I am on the property index page
Then I should see "There are no properties configured"
Scenario: Accessing the property creation form
Given I am on the dashboard page
When I follow "Configure properties"
And I follow "Create property"
Then I should be on the property creation page
Scenario: Submitting form without specifying the name
Given I am on the property creation page
When I press "Create"
Then I should still be on the property creation page
And I should see "Please enter property name"
Scenario: Submitting form without specifying the presentation
Given I am on the property creation page
When I fill in "Internal name" with "Book author"
And I press "Create"
Then I should still be on the property creation page
And I should see "Please enter property presentation"
Scenario: Creating new property
Given I am on the property creation page
When I fill in "Internal name" with "Book author"
And I fill in "Presentation" with "Author"
And I press "Create"
Then I should still be on the property index page
And I should see "Property has been successfully created."
Scenario: Created properties appear in the list
Given I created property "Food"
When I go to the property index page
Then I should see 3 properties in the list
And I should see property with name "Food" in that list
Scenario: Accessing the editing form from the list
Given I am on the property index page
When I click "edit" near "T-Shirt collection"
Then I should be editing property "T-Shirt collection"
Scenario: Updating the property
Given I am editing property "T-Shirt collection"
When I fill in "Internal name" with "T-Shirt edition"
And I press "Save changes"
Then I should still be on the property index page
And I should see "Property has been successfully updated."
@javascript
Scenario: Deleted property disappears from the list
Given I am on the property index page
When I click "delete" near "T-Shirt fabric"
And I click "delete" from the confirmation modal
Then I should still be on the property index page
And I should see "Property has been successfully deleted."
And I should not see property with name "T-Shirt fabric" in that list
Scenario: Creating string property by default
Given I am on the property creation page
When I fill in "Internal name" with "Book author"
And I fill in "Presentation" with "Author"
And I press "Create"
Then I should still be on the property index page
And I should see "Property has been successfully created."
And property with following data should be created:
| name | Book author |
| type | text |
Scenario Outline: Creating new property for type
Given I am on the property creation page
When I fill in "Internal name" with "Book author"
And I fill in "Presentation" with "Author"
And I select "<label>" from "Type"
And I press "Create"
Then I should still be on the property index page
And I should see "Property has been successfully created."
And property with following data should be created:
| name | Book author |
| presentation | Author |
| type | <value> |
Examples:
| label | value |
| Checkbox | checkbox |
| Text | text |
| Choice | choice |
| Number | number |
@javascript
Scenario: Create new choice property with many choices
Given I am on the property creation page
When I fill in "Internal name" with "Book author"
And I fill in "Presentation" with "Author"
And I select "Choice" from "Type"
And I click "Add choice"
And I fill in "Choice 0" with "J.R.R Tolken"
And I click "Add choice"
And I fill in "Choice 1" with "Jaroslaw Grzedowicz"
And I press "Create"
Then property with following data should be created:
| name | Book author |
| presentation | Author |
| type | choice |
| choices | J.R.R Tolken,Jaroslaw Grzedowicz |
And I should see "Property has been successfully created."
@javascript
Scenario: Remove choice property choice
Given I am on the property creation page
When I fill in "Internal name" with "Book author"
And I fill in "Presentation" with "Author"
And I select "Choice" from "Type"
And I click "Add choice"
And I fill in "Choice 0" with "J.R.R Tolken"
And I click "Add choice"
And I fill in "Choice 1" with "Jaroslaw Grzedowicz"
And I remove property choice number 0
And I press "Create"
Then property with following data should be created:
| name | Book author |
| presentation | Author |
| type | choice |
| choices | Jaroslaw Grzedowicz |
And I should see "Property has been successfully created."

View file

@ -11,14 +11,14 @@ Feature: Product prototypes
| T-Shirt color | Color | Red, Blue, Green |
| T-Shirt size | Size | S, M, L |
| Bag color | Color | Black, Light balsamic |
And there are following properties:
And there are following attributes:
| name | presentation |
| T-Shirt collection | Collection |
| T-Shirt fabric | T-Shirt fabric |
| Bag material | Material |
And there is prototype "T-Shirt" with following configuration:
| options | T-Shirt color, T-Shirt size |
| properties | T-Shirt collection, T-Shirt fabric |
| attributes | T-Shirt collection, T-Shirt fabric |
Scenario: Seeing index of all prototypes
Given I am on the dashboard page
@ -44,17 +44,17 @@ Feature: Product prototypes
And I should see "Please enter prototype name."
Scenario: Creating Bag prototype with color as option
and material as property
and material as attribute
Given I am on the prototype creation page
When I fill in "Name" with "Bag"
And I select "Bag color" from "Options"
And I select "Bag material" from "Properties"
And I select "Bag material" from "attributes"
And I press "Create"
Then I should be on the prototype index page
And I should see "Prototype has been successfully created."
Scenario: Creating simple T-Shirt prototype with color and size
as options but without properties
as options but without attributes
Given I am on the prototype creation page
When I fill in "Name" with "Simple T-Shirt"
And I select "T-Shirt color" from "Options"

View file

@ -10,16 +10,13 @@ Feature: Product variants
| name | presentation | values |
| T-Shirt color | Color | Red, Blue, Green |
| T-Shirt size | Size | S, M, L |
And there are following properties:
| name | presentation |
| T-Shirt fabric | T-Shirt |
And the following products exist:
| name | price | options | properties |
| Super T-Shirt | 19.99 | T-Shirt size, T-Shirt color | T-Shirt fabric: Wool |
| Black T-Shirt | 19.99 | T-Shirt size | T-Shirt fabric: Cotton |
| Sylius T-Shirt | 12.99 | T-Shirt size, T-Shirt color | T-Shirt fabric: Cotton |
| Mug | 5.99 | | |
| Sticker | 10.00 | | |
| name | price | options |
| Super T-Shirt | 19.99 | T-Shirt size, T-Shirt color |
| Black T-Shirt | 19.99 | T-Shirt size |
| Sylius T-Shirt | 12.99 | T-Shirt size, T-Shirt color |
| Mug | 5.99 | |
| Sticker | 10.00 | |
And product "Super T-Shirt" is available in all variations
Scenario: Viewing a product without options

View file

@ -10,14 +10,14 @@ Feature: Products
| name | presentation | values |
| T-Shirt color | Color | Red, Blue, Green |
| T-Shirt size | Size | S, M, L |
And there are following properties:
And there are following attributes:
| name | presentation | type | choices |
| T-Shirt fabric | T-Shirt | text | |
| T-Shirt fare trade | Faretrade product | checkbox | |
| Color | color | choice | red, blue |
| Size | size | number | |
And the following products exist:
| name | price | options | properties |
| name | price | options | attributes |
| Super T-Shirt | 19.99 | T-Shirt size, T-Shirt color | T-Shirt fabric: Wool |
| Black T-Shirt | 19.99 | T-Shirt size | T-Shirt fabric: Cotton |
| Mug | 5.99 | | |
@ -89,7 +89,7 @@ Feature: Products
Then I should still be on the product creation page
And I should see "Price must not be negative."
Scenario: Creating simple product without any properties and options
Scenario: Creating simple product without any attributes and options
Given I am on the product creation page
When I fill in the following:
| Name | Book about Everything |
@ -127,15 +127,15 @@ Feature: Products
And "Options matching" should appear on the page
@javascript
Scenario: Creating product with string property
Scenario: Creating product with string attribute
Given I am on the product creation page
When I fill in the following:
| Name | Manchester United tee |
| Description | Interesting description |
| Price | 59.99 |
And go to "Properties" tab
And I click "Add property"
And I select "T-Shirt fabric" from "Property"
And go to "attributes" tab
And I click "Add attribute"
And I select "T-Shirt fabric" from "Attribute"
And I fill in "Value" with "Cotton"
And I press "Create"
Then I should be on the page of product "Manchester United tee"
@ -143,45 +143,45 @@ Feature: Products
And I should see "Cotton"
@javascript
Scenario: Creating product with boolean property
Scenario: Creating product with boolean attribute
Given I am on the product creation page
When I fill in the following:
| Name | Manchester United tee |
| Description | Interesting description |
| Price | 59.99 |
And go to "Properties" tab
And I click "Add property"
And I select "T-Shirt fare trade" from "Property"
And go to "attributes" tab
And I click "Add attribute"
And I select "T-Shirt fare trade" from "Attribute"
And I check "Value"
When I press "Create"
Then I should be on the page of product "Manchester United tee"
And "Product has been successfully created." should appear on the page
@javascript
Scenario: Creating product with properties to choose
Scenario: Creating product with attributes to choose
Given I am on the product creation page
When I fill in the following:
| Name | Manchester United tee |
| Description | Interesting description |
| Price | 59.99 |
And go to "Properties" tab
And I click "Add property"
And I select "Color" from "Property"
And go to "attributes" tab
And I click "Add attribute"
And I select "Color" from "Attribute"
And I select "red" from "Value"
When I press "Create"
Then I should be on the page of product "Manchester United tee"
And "Product has been successfully created." should appear on the page
@javascript
Scenario: Creating product with number property
Scenario: Creating product with number attribute
Given I am on the product creation page
When I fill in the following:
| Name | Manchester United tee |
| Description | Interesting description |
| Price | 59.99 |
And go to "Properties" tab
And I click "Add property"
And I select "Color" from "Property"
And go to "Attributes" tab
And I click "Add attribute"
And I select "Color" from "Attribute"
And I fill in "Value" with "12"
When I press "Create"
Then I should be on the page of product "Manchester United tee"

View file

@ -1,9 +1,10 @@
suites:
Addressing : { namespace: Sylius, spec_path: src/Sylius/Component/Addressing }
Attribute : { namespace: Sylius, spec_path: src/Sylius/Component/Attribute }
Cart : { namespace: Sylius, spec_path: src/Sylius/Component/Cart }
Core : { namespace: Sylius, spec_path: src/Sylius/Component/Core }
Inventory : { namespace: Sylius, spec_path: src/Sylius/Component/Inventory }
Installer : { namespace: Sylius, spec_path: src/Sylius/Component/Installer }
Inventory : { namespace: Sylius, spec_path: src/Sylius/Component/Inventory }
Money : { namespace: Sylius, spec_path: src/Sylius/Component/Money }
Omnipay : { namespace: Sylius, spec_path: src/Sylius/Component/Omnipay }
Order : { namespace: Sylius, spec_path: src/Sylius/Component/Order }
@ -16,13 +17,14 @@ suites:
Shipping : { namespace: Sylius, spec_path: src/Sylius/Component/Shipping }
Taxation : { namespace: Sylius, spec_path: src/Sylius/Component/Taxation }
Taxonomies : { namespace: Sylius, spec_path: src/Sylius/Component/Taxonomies }
VariableProduct : { namespace: Sylius, spec_path: src/Sylius/Component/VariableProduct }
Variation : { namespace: Sylius, spec_path: src/Sylius/Component/Variation }
AddressingBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/AddressingBundle }
AttributeBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/AttributeBundle }
CartBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/CartBundle }
CoreBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/CoreBundle }
InventoryBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/InventoryBundle }
InstallerBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/InstallerBundle }
InventoryBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/InventoryBundle }
MoneyBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/MoneyBundle }
OmnipayBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/OmnipayBundle }
OrderBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/OrderBundle }
@ -35,4 +37,4 @@ suites:
ShippingBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/ShippingBundle }
TaxationBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/TaxationBundle }
TaxonomiesBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/TaxonomiesBundle }
VariableProductBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/VariableProductBundle }
VariationBundle : { namespace: Sylius, spec_path: src/Sylius/Bundle/VariationBundle }

View file

@ -0,0 +1,6 @@
CHANGELOG
=========
### v0.10.0
* Initial dev release.

View file

@ -0,0 +1,116 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\AttributeBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This class contains the configuration information for the bundle.
*
* This information is solely responsible for how the different configuration
* sections are normalized, and merged.
*
* @author Paweł Jędrzejewski <pjedrzejewski@diweb.pl>
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('sylius_attribute');
$rootNode
->addDefaultsIfNotSet()
->children()
->scalarNode('driver')->isRequired()->cannotBeEmpty()->end()
->end()
;
$this->addClassesSection($rootNode);
$this->addValidationGroupsSection($rootNode);
return $treeBuilder;
}
/**
* Adds `validation_groups` section.
*
* @param ArrayNodeDefinition $node
*/
private function addValidationGroupsSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('validation_groups')
->useAttributeAsKey('name')
->prototype('array')
->children()
->arrayNode('property')
->prototype('scalar')->end()
->defaultValue(array('sylius'))
->end()
->arrayNode('product_property')
->prototype('scalar')->end()
->defaultValue(array('sylius'))
->end()
->end()
->end()
->end()
->end()
;
}
/**
* Adds `classes` section.
*
* @param ArrayNodeDefinition $node
*/
private function addClassesSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('classes')
->useAttributeAsKey('name')
->prototype('array')
->children()
->scalarNode('subject')->isRequired()->end()
->arrayNode('attribute')
->addDefaultsIfNotSet()
->children()
->scalarNode('model')->defaultValue('Sylius\Component\Attribute\Model\Attribute')->end()
->scalarNode('controller')->defaultValue('Sylius\Bundle\ResourceBundle\Controller\ResourceController')->end()
->scalarNode('repository')->cannotBeEmpty()->end()
->scalarNode('form')->defaultValue('Sylius\Bundle\AttributeBundle\Form\Type\AttributeType')->end()
->end()
->end()
->arrayNode('attribute_value')
->isRequired()
->addDefaultsIfNotSet()
->children()
->scalarNode('model')->isRequired()->end()
->scalarNode('controller')->defaultValue('Sylius\Bundle\ResourceBundle\Controller\ResourceController')->end()
->scalarNode('repository')->cannotBeEmpty()->end()
->scalarNode('form')->defaultValue('Sylius\Bundle\AttributeBundle\Form\Type\AttributeValueType')->end()
->end()
->end()
->end()
->end()
->end()
->end()
;
}
}

View file

@ -0,0 +1,124 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\AttributeBundle\DependencyInjection;
use Sylius\Bundle\ResourceBundle\DependencyInjection\AbstractResourceExtension;
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
/**
* Sylius attributes system extension.
*
* @author Paweł Jędrzejewski <pjedrzejewski@diweb.pl>
*/
class SyliusAttributeExtension extends AbstractResourceExtension
{
/**
* {@inheritdoc}
*/
public function load(array $config, ContainerBuilder $container)
{
$this->configure($config, new Configuration(), $container, self::CONFIGURE_LOADER | self::CONFIGURE_DATABASE | self::CONFIGURE_PARAMETERS | self::CONFIGURE_VALIDATORS);
}
/**
* {@inheritdoc}
*/
public function process(array $config, ContainerBuilder $container)
{
$convertedConfig = array();
$subjects = array();
foreach ($config['classes'] as $subject => $parameters) {
$subjects[] = $parameters;
unset($parameters['subject']);
foreach ($parameters as $resource => $classes) {
$convertedConfig[$subject.'_'.$resource] = $classes;
}
$this->createSubjectServices($container, $config['driver'], $subject, $convertedConfig);
if (!isset($config['validation_groups'][$subject]['attribute'])) {
$config['validation_groups'][$subject]['attribute'] = array('sylius');
}
if (!isset($config['validation_groups'][$subject]['attribute_value'])) {
$config['validation_groups'][$subject]['attribute_value'] = array('sylius');
}
}
$container->setParameter('sylius.attribute.subjects', $subjects);
$config['classes'] = $convertedConfig;
$convertedConfig = array();
foreach ($config['validation_groups'] as $subject => $parameters) {
foreach ($parameters as $resource => $validationGroups) {
$convertedConfig[$subject.'_'.$resource] = $validationGroups;
}
}
$config['validation_groups'] = $convertedConfig;
return $config;
}
/**
* Create services for every subject.
*
* @param ContainerBuilder $container
* @param string $driver
* @param string $subject
* @param array $config
*/
private function createSubjectServices(ContainerBuilder $container, $driver, $subject, array $config)
{
$attributeAlias = $subject.'_'.'attribute';
$attributeValueAlias = $subject.'_'.'attribute_value';
$attributeClasses = $config[$attributeAlias];
$attributeValueClasses = $config[$attributeValueAlias];
$attributeFormType = new Definition($attributeClasses['form']);
$attributeFormType
->setArguments(array($subject, $attributeClasses['model'], '%sylius.validation_group.'.$attributeAlias.'%'))
->addTag('form.type', array('alias' => 'sylius_'.$attributeAlias))
;
$container->setDefinition('sylius.form.type.'.$attributeAlias, $attributeFormType);
$choiceTypeClasses = array(
SyliusResourceBundle::DRIVER_DOCTRINE_ORM => 'Sylius\Bundle\AttributeBundle\Form\Type\AttributeEntityChoiceType'
);
$attributeChoiceFormType = new Definition($choiceTypeClasses[$driver]);
$attributeChoiceFormType
->setArguments(array($subject, $attributeClasses['model']))
->addTag('form.type', array('alias' => 'sylius_'.$attributeAlias.'_choice'))
;
$container->setDefinition('sylius.form.type.'.$attributeAlias.'_choice', $attributeChoiceFormType);
$attributeValueFormType = new Definition($attributeValueClasses['form']);
$attributeValueFormType
->setArguments(array($subject, $attributeValueClasses['model'], '%sylius.validation_group.'.$attributeValueAlias.'%'))
->addTag('form.type', array('alias' => 'sylius_'.$attributeValueAlias))
;
$container->setDefinition('sylius.form.type.'.$attributeValueAlias, $attributeValueFormType);
}
}

View file

@ -0,0 +1,93 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\AttributeBundle\EventListener;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
/**
* Doctrine listener used to manipulate mappings.
*
* @author Paweł Jędrzejewski <pawel@sylius.org>
*/
class LoadMetadataSubscriber implements EventSubscriber
{
/**
* @var array
*/
protected $subjects;
/**
* Constructor
*
* @param array $subjects
*/
public function __construct($subjects)
{
$this->subjects = $subjects;
}
/**
* @return array
*/
public function getSubscribedEvents()
{
return array(
'loadClassMetadata'
);
}
/**
* @param LoadClassMetadataEventArgs $eventArgs
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
$metadata = $eventArgs->getClassMetadata();
$configuration = $eventArgs->getEntityManager()->getConfiguration();
foreach ($this->subjects as $class) {
if ($class['attribute_value']['model'] !== $metadata->getName()) {
continue;
}
$subjectMapping = array(
'fieldName' => 'subject',
'targetEntity' => $class['subject'],
'inversedBy' => 'attributes',
'joinColumns' => array(array(
'name' => 'subject_id',
'referencedColumnName' => 'id',
'nullable' => false,
'onDelete' => 'CASCADE'
))
);
$metadata->mapManyToOne($subjectMapping);
$attributeMapping = array(
'fieldName' => 'attribute',
'targetEntity' => $class['attribute']['model'],
'inversedBy' => 'attributes',
'joinColumns' => array(array(
'name' => 'attribute_id',
'referencedColumnName' => 'id',
'nullable' => false,
'onDelete' => 'CASCADE'
))
);
$metadata->mapManyToOne($attributeMapping);
}
}
}

View file

@ -9,20 +9,20 @@
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\ProductBundle\Form\EventListener;
namespace Sylius\Bundle\AttributeBundle\Form\EventListener;
use Sylius\Component\Product\Model\PropertyTypes;
use Sylius\Component\Attribute\Model\AttributeTypes;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormFactoryInterface;
/**
* Form event listener that builds choices for property form.
* Form event listener that builds choices for attribute form.
*
* @author Leszek Prabucki <leszek.prabucki@gmail.com>
*/
class BuildPropertyFormChoicesListener implements EventSubscriberInterface
class BuildattributeFormChoicesListener implements EventSubscriberInterface
{
/**
* Form factory.
@ -50,19 +50,20 @@ class BuildPropertyFormChoicesListener implements EventSubscriberInterface
}
/**
* Builds choices for property form
* Builds choices for attribute form.
*
* @param FormEvent $event
*/
public function buildChoices(FormEvent $event)
{
$property = $event->getData();
if (null === $property) {
$attribute = $event->getData();
if (null === $attribute) {
return;
}
$type = $property->getType();
if (null === $type || PropertyTypes::CHOICE === $type) {
$type = $attribute->getType();
if (null === $type || AttributeTypes::CHOICE === $type) {
$event->getForm()->add(
$this->factory->createNamed('choices', 'collection', null, array(
'type' => 'text',

View file

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\ProductBundle\Form\EventListener;
namespace Sylius\Bundle\AttributeBundle\Form\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvent;
@ -21,8 +21,9 @@ use Symfony\Component\Form\FormFactoryInterface;
*
* @author Saša Stamenković <umpirsky@gmail.com>
* @author Leszek Prabucki <leszek.prabucki@gmail.com>
* @author Paweł Jędrzejewski <pawel@sylius.org>
*/
class BuildProductPropertyFormListener implements EventSubscriberInterface
class BuildAttributeValueFormListener implements EventSubscriberInterface
{
/**
* Form factory.
@ -56,25 +57,25 @@ class BuildProductPropertyFormListener implements EventSubscriberInterface
*/
public function buildForm(FormEvent $event)
{
$productProperty = $event->getData();
$attributeValue = $event->getData();
$form = $event->getForm();
if (null === $productProperty) {
if (null === $attributeValue) {
$form->add($this->factory->createNamed('value', 'text', null, array('auto_initialize' => false)));
return;
}
$options = array('label' => $productProperty->getName(), 'auto_initialize' => false);
$options = array('label' => $attributeValue->getName(), 'auto_initialize' => false);
if (is_array($productProperty->getConfiguration())) {
$options = array_merge($options, $productProperty->getConfiguration());
if (is_array($attributeValue->getConfiguration())) {
$options = array_merge($options, $attributeValue->getConfiguration());
}
// If we're editing the product property, let's just render the value field, not full selection.
// If we're editing the attribute value, let's just render the value field, not full selection.
$form
->remove('property')
->add($this->factory->createNamed('value', $productProperty->getType(), null, $options))
->remove('attribute')
->add($this->factory->createNamed('value', $attributeValue->getType(), null, $options))
;
}
}

View file

@ -9,20 +9,27 @@
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\ProductBundle\Form\Type;
namespace Sylius\Bundle\AttributeBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
/**
* Property choice form type.
* Attribute choice form type.
*
* @author Paweł Jędrzejewski <pjedrzejewski@diweb.pl>
*/
abstract class PropertyChoiceType extends AbstractType
abstract class AttributeChoiceType extends AbstractType
{
/**
* Property class name.
* Name of the attributes subject.
*
* @var string
*/
protected $subjectName;
/**
* Attribute class name.
*
* @var string
*/
@ -31,10 +38,12 @@ abstract class PropertyChoiceType extends AbstractType
/**
* Constructor.
*
* @param string $subjectName
* @param string $className
*/
public function __construct($className)
public function __construct($subjectName, $className)
{
$this->subjectName = $subjectName;
$this->className = $className;
}
@ -55,6 +64,6 @@ abstract class PropertyChoiceType extends AbstractType
*/
public function getName()
{
return 'sylius_property_choice';
return sprintf('sylius_%s_attribute_choice', $this->subjectName);
}
}

View file

@ -9,14 +9,14 @@
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\ProductBundle\Form\Type;
namespace Sylius\Bundle\AttributeBundle\Form\Type;
/**
* Property choice form type.
* Attribute choice form type.
*
* @author Paweł Jędrzejewski <pjedrzejewski@diweb.pl>
*/
class PropertyEntityChoiceType extends PropertyChoiceType
class AttributeEntityChoiceType extends AttributeChoiceType
{
/**
* {@inheritdoc}

View file

@ -9,22 +9,29 @@
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\ProductBundle\Form\Type;
namespace Sylius\Bundle\AttributeBundle\Form\Type;
use Sylius\Bundle\ProductBundle\Form\EventListener\BuildPropertyFormChoicesListener;
use Sylius\Component\Product\Model\PropertyTypes;
use Sylius\Bundle\AttributeBundle\Form\EventListener\BuildAttributeFormChoicesListener;
use Sylius\Component\Attribute\Model\AttributeTypes;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
/**
* Property type.
* Attribute type.
*
* @author Paweł Jędrzejewski <pjedrzejewski@diweb.pl>
* @author Leszek Prabucki <leszek.prabucki@gmail.com>
*/
class PropertyType extends AbstractType
class AttributeType extends AbstractType
{
/**
* Subject name.
*
* @var string
*/
protected $subjectName;
/**
* Data class.
*
@ -42,11 +49,13 @@ class PropertyType extends AbstractType
/**
* Constructor.
*
* @param string $subjectName
* @param string $dataClass
* @param array $validationGroups
*/
public function __construct($dataClass, array $validationGroups)
public function __construct($subjectName, $dataClass, array $validationGroups)
{
$this->subjectName = $subjectName;
$this->dataClass = $dataClass;
$this->validationGroups = $validationGroups;
}
@ -58,15 +67,15 @@ class PropertyType extends AbstractType
{
$builder
->add('name', 'text', array(
'label' => 'sylius.label.property.name'
'label' => 'sylius.form.attribute.name'
))
->add('presentation', 'text', array(
'label' => 'sylius.label.property.presentation'
'label' => 'sylius.form.attribute.presentation'
))
->add('type', 'choice', array(
'choices' => PropertyTypes::getChoices()
'choices' => AttributeTypes::getChoices()
))
->addEventSubscriber(new BuildPropertyFormChoicesListener($builder->getFormFactory()))
->addEventSubscriber(new BuildAttributeFormChoicesListener($builder->getFormFactory()))
;
}
@ -88,6 +97,6 @@ class PropertyType extends AbstractType
*/
public function getName()
{
return 'sylius_property';
return sprintf('sylius_%s_attribute', $this->subjectName);
}
}

View file

@ -9,9 +9,9 @@
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\ProductBundle\Form\Type;
namespace Sylius\Bundle\AttributeBundle\Form\Type;
use Sylius\Bundle\ProductBundle\Form\EventListener\BuildProductPropertyFormListener;
use Sylius\Bundle\AttributeBundle\Form\EventListener\BuildAttributeValueFormListener;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
@ -19,12 +19,19 @@ use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
/**
* Product property form type.
* Attribute value form type.
*
* @author Paweł Jędrzejewski <pjedrzejewski@diweb.pl>
*/
class ProductPropertyType extends AbstractType
class AttributeValueType extends AbstractType
{
/**
* Attributes subject name.
*
* @var string
*/
protected $subjectName;
/**
* Data class.
*
@ -42,11 +49,13 @@ class ProductPropertyType extends AbstractType
/**
* Constructor.
*
* @param string $subjectName
* @param string $dataClass
* @param array $validationGroups
*/
public function __construct($dataClass, array $validationGroups)
public function __construct($subjectName, $dataClass, array $validationGroups)
{
$this->subjectName = $subjectName;
$this->dataClass = $dataClass;
$this->validationGroups = $validationGroups;
}
@ -57,13 +66,13 @@ class ProductPropertyType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('property', 'sylius_property_choice')
->addEventSubscriber(new BuildProductPropertyFormListener($builder->getFormFactory()))
->add('attribute', sprintf('sylius_%s_attribute_choice', $this->subjectName))
->addEventSubscriber(new BuildAttributeValueFormListener($builder->getFormFactory()))
;
$prototypes = array();
foreach ($this->getProperties($builder) as $property) {
$prototypes[] = $builder->create('value', $property->getType(), $property->getConfiguration())->getForm();
foreach ($this->getAttributes($builder) as $attribute) {
$prototypes[] = $builder->create('value', $attribute->getType(), $attribute->getConfiguration())->getForm();
}
$builder->setAttribute('prototypes', $prototypes);
@ -99,11 +108,18 @@ class ProductPropertyType extends AbstractType
*/
public function getName()
{
return 'sylius_product_property';
return sprintf('sylius_%s_attribute_value', $this->subjectName);
}
private function getProperties(FormBuilderInterface $builder)
/**
* Get attributes
*
* @param FormBuilderInterface $builder
*
* @return AttributeInterface[]
*/
private function getAttributes(FormBuilderInterface $builder)
{
return $builder->get('property')->getOption('choice_list')->getChoices();
return $builder->get('attribute')->getOption('choice_list')->getChoices();
}
}

View file

@ -0,0 +1,74 @@
SyliusAttributeBundle [![Build status...](https://secure.travis-ci.org/Sylius/SyliusAttributeBundle.png?branch=master)](http://travis-ci.org/Sylius/SyliusAttributeBundle)
=====================
Attributes system for entities in Symfony2 applications.
Sylius
------
**Sylius** - Modern ecommerce for Symfony2. Visit [Sylius.org](http://sylius.org).
[phpspec](http://phpspec.net) examples
--------------------------------------
```bash
$ composer install
$ bin/phpspec run -fpretty
```
Documentation
-------------
Documentation is available on [**docs.sylius.org**](http://docs.sylius.org/en/latest/bundles/SyliusAttributeBundle/index.html).
Contributing
------------
All informations about contributing to Sylius can be found on [this page](http://docs.sylius.org/en/latest/contributing/index.html).
Mailing lists
-------------
### Users
Questions? Feel free to ask on [users mailing list](http://groups.google.com/group/sylius).
### Developers
To contribute and develop this bundle, use the [developers mailing list](http://groups.google.com/group/sylius-dev).
Sylius twitter account
----------------------
If you want to keep up with updates, [follow the official Sylius account on twitter](http://twitter.com/Sylius).
Bug tracking
------------
This bundle uses [GitHub issues](https://github.com/Sylius/SyliusAttributeBundle/issues).
If you have found bug, please create an issue.
Versioning
----------
Releases will be numbered with the format `major.minor.patch`.
And constructed with the following guidelines.
* Breaking backwards compatibility bumps the major.
* New additions without breaking backwards compatibility bumps the minor.
* Bug fixes and misc changes bump the patch.
For more information on SemVer, please visit [semver.org website](http://semver.org/).
This versioning method is same for all **Sylius** bundles and applications.
MIT License
-----------
License can be found [here](https://github.com/Sylius/SyliusAttributeBundle/blob/master/Resources/meta/LICENSE).
Authors
-------
The bundle was originally created by [Paweł Jędrzejewski](http://pjedrzejewski.com).
See the list of [contributors](https://github.com/Sylius/SyliusAttributeBundle/contributors).

View file

@ -14,7 +14,7 @@
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping">
<mapped-superclass name="Sylius\Component\Product\Model\Property" table="sylius_property">
<mapped-superclass name="Sylius\Component\Attribute\Model\Attribute" table="sylius_attribute">
<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>

View file

@ -16,18 +16,11 @@
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<mapped-superclass name="Sylius\Component\Product\Model\ProductProperty" table="sylius_product_property">
<mapped-superclass name="Sylius\Component\Attribute\Model\AttributeValue" table="sylius_attribute_value">
<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<many-to-one field="product" target-entity="Sylius\Component\Product\Model\ProductInterface" inversed-by="properties">
<join-column name="product_id" referenced-column-name="id" nullable="false" />
</many-to-one>
<many-to-one field="property" target-entity="Sylius\Component\Product\Model\PropertyInterface">
<join-column name="property_id" referenced-column-name="id" nullable="false" />
</many-to-one>
<field name="value" column="value" type="text" />
</mapped-superclass>

View file

@ -17,7 +17,15 @@
http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="sylius.builder.prototype.class">Sylius\Component\Product\Builder\Variable\PrototypeBuilder</parameter>
<parameter key="sylius.event_subscriber.attribute.load_metadata.class">Sylius\Bundle\AttributeBundle\EventListener\LoadMetadataSubscriber</parameter>
</parameters>
<services>
<service id="sylius.event_subscriber.attribute.load_metadata" class="%sylius.event_subscriber.attribute.load_metadata.class%">
<tag name="doctrine.event_subscriber" />
<argument>%sylius.attribute.subjects%</argument>
</service>
</services>
</container>

View file

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is part of the Sylius package.
(c) Paweł Jędrzejewski
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
-->
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
http://symfony.com/schema/dic/services/constraint-mapping-1.0.xsd">
<class name="Sylius\Component\Attribute\Model\Attribute">
<property name="name">
<constraint name="NotBlank">
<option name="message">sylius.attribute.name.not_blank</option>
<option name="groups">sylius</option>
</constraint>
<constraint name="Length">
<option name="min">2</option>
<option name="minMessage">sylius.attribute.name.min_length</option>
<option name="max">255</option>
<option name="maxMessage">sylius.attribute.name.max_length</option>
<option name="groups">sylius</option>
</constraint>
</property>
<property name="presentation">
<constraint name="NotBlank">
<option name="message">sylius.attribute.presentation.not_blank</option>
<option name="groups">sylius</option>
</constraint>
<constraint name="Length">
<option name="min">2</option>
<option name="minMessage">sylius.attribute.presentation.min_length</option>
<option name="max">255</option>
<option name="maxMessage">sylius.attribute.presentation.max_length</option>
<option name="groups">sylius</option>
</constraint>
</property>
</class>
<class name="Sylius\Component\Attribute\Model\AttributeValue">
<property name="attribute">
<constraint name="NotBlank">
<option name="message">sylius.attribute_value.attribute.not_blank</option>
<option name="groups">sylius</option>
</constraint>
</property>
<property name="value">
<constraint name="NotBlank">
<option name="message">sylius.attribute_value.value.not_blank</option>
<option name="groups">sylius</option>
</constraint>
</property>
</class>
</constraint-mapping>

View file

@ -0,0 +1,16 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
label:
product:
description: Beschreibung
properties: Eigenschaften
available_on: Verfügbar ab
meta_keywords: Meta Keywords
meta_description: Meta Beschreibung
property:
name: Interner Name
presentation: Präsentation
prototype:
properties: Eigenschaften

View file

@ -0,0 +1,5 @@
sylius:
form:
attribute:
name: Internal name
presentation: Presentation

View file

@ -0,0 +1,18 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
label:
product:
name: Nombre
description: Descripción
properties: Propiedades
available_on: Disponible desde
meta_keywords: Meta palabras clave
meta_description: Meta descripción
property:
name: Nombre interno
presentation: Presentación
prototype:
name: Nombre
properties: Propiedades

View file

@ -0,0 +1,18 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
label:
product:
name: Nom
description: Description
properties: Propriétés
available_on: Disponible sur
meta_keywords: Mots clés
meta_description: Méta description
property:
name: Nom interne
presentation: Présentation
prototype:
name: Nom
properties: Propriétés

View file

@ -0,0 +1,7 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
label:
product:
description: Descrizione

View file

@ -0,0 +1,8 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
label:
product:
meta_keywords: Metaタグ(keywords)
meta_description: metaタグ(description)

View file

@ -0,0 +1,18 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
label:
product:
name: Naam
description: Omschrijving
properties: Eigenschappen
available_on: Beschikbaar op
meta_keywords: Meta sleutelwoorden
meta_description: Meta omschrijving
property:
name: Interne naam
presentation: Weergave
prototype:
name: Naam
properties: Eigenschappen

View file

@ -0,0 +1,18 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
label:
product:
name: Nazwa
description: Opis
properties: Właściwości
available_on: Dostępny od
meta_keywords: Słowa kluczowe w sekcji Meta
meta_description: Opis w sekcji Meta
property:
name: Nazwa w systemie
presentation: Nazwa publiczna
prototype:
name: Nazwa
properties: Właściwości

View file

@ -0,0 +1,18 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
label:
product:
name: Название
description: Описание
properties: Свойства
available_on: Доступно с
meta_keywords: Ключевые слова метаданных
meta_description: Описание метаданных
property:
name: Внутреннее название
presentation: Публичное название
prototype:
name: Название
properties: Свойства

View file

@ -0,0 +1,14 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
label:
product:
name: Názov
description: Popis
properties: Vlastnosti
meta_keywords: Meta kľúčové slová
meta_description: Meta popis
prototype:
name: Názov
properties: Vlastnosti

View file

@ -0,0 +1,9 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
label:
product:
name: Ime
prototype:
name: Ime

View file

@ -0,0 +1,53 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
product:
sku:
not_blank: Bitte geben Sie die Produkt Bestandseinheit an.
unique: Die Produkt Bestandseinheit muss eindeutig sein.
name:
not_blank: Bitte gib Sie einen Produktnamen an.
min_length: 'Der Produktname muss mindestens 1 Zeichen lang sein.|Der Produktname muss mindestens {{ limit }} Zeichen lang sein.'
max_length: 'Der Produktname darf nicht länger als 1 Zeichen sein.|Der Produktname darf nicht länger als {{ limit }} Zeichen sein.'
description:
not_blank: Bitte geben Sie eine Produktbeschreibung an.
min_length: 'Die Produktbeschreibung muss mindestens 1 Zeichen lang sein.|Die Produktbeschreibung muss mindestens {{ limit }} Zeichen lang sein.'
variant:
sku:
not_blank: Bitte geben Sie die Bestandseinheit der Variante an.
unique: Die Bestandseinheit der Variante muss einzigartig sein.
combination: Die Variation mit den gewählten Einstellungen existiert schon.
option:
name:
not_blank: Bitte geben Sie einen Namen für die Option ein.
min_length: 'Der Name der Option muss mindestens 1 Zeichen lang sein.|Der Name der Option muss mindestens {{ limit }} Zeichen lang sein.'
max_length: 'Der Name der Option darf nicht länger als 1 Zeichen sein.|Der Name der Option darf nicht länger als {{ limit }} Zeichen sein.'
presentation:
not_blank: Bitte geben Sie die Option für die Gestaltung an.
min_length: 'Die Option für die Gestaltung muss mindestens 1 Zeichen lang sein.|Die Option für die Gestaltung muss mindestens {{ limit }} Zeichen lang sein.'
max_length: 'Die Option für die Gestaltung darf nicht länger als 1 Zeichen sein.|Die Option für die Gestaltung darf nicht länger als {{ limit }} Zeichen lang sein.'
values:
min_count: 'Bitte geben Sie mindestens {{ limit }} Wert für diese Option ein.|Bitte geben Sie mindestens {{ limit }} Werte für diese Option ein.'
option_value:
value:
not_blank: Bitte geben Sie einen Wert für diese Option ein.
property:
name:
not_blank: Bitte geben Sie einen Namen für diese Einstellung ein.
min_length: 'Der Name dieser Einstellung muss mindestens 1 Zeichen lang sein.|Der Name dieser Einstellung muss mindestens {{ limit }} Zeichen lang sein.'
max_length: 'Der Name dieser Einstellung darf nicht länger als 1 Zeichen sein.|Der Name dieser Einstellung darf nicht länger als {{ limit }} Zeichen sein.'
presentation:
not_blank: Bitte geben Sie den Wert für die Gestaltung an.
min_length: 'Der Wert für die Gestaltung muss mindestens 1 Zeichen lang sein.|Der Wert für die Gestaltung muss mindestens {{ limit }} Zeichen lang sein.'
max_length: 'Der Wert für die Gestaltung darf nicht länger als 1 Zeichen lang sein.|Der Wert für die Gestaltung darf nicht länger als {{ limit }} Zeichen lang sein.'
product_property:
property:
not_blank: Bitte wählen Sie eine Einstellung.
value:
not_blank: Bitte geben Sie einen Wert für diese Einstellung an.
prototype:
name:
not_blank: Bitte geben Sie einen Namen für dieses Muster an.
min_length: 'Der Name des Musters muss mindestens 1 Zeichen lang sein.|Der Name des Musters muss mindestens {{ limit }} Zeichen lang sein.'
max_length: 'Der Name des Musters darf nicht länger als 1 Zeichen lang sein.|Der Name des Muster darf nicht länger als {{ limit }} Zeichen lang sein.'

View file

@ -0,0 +1,15 @@
sylius:
attribute:
name:
not_blank: Please enter attribute name.
min_length: Attribute name must be at least 1 character long.|Attribute name must be at least {{ limit }} characters long.
max_length: Attribute name must not be longer than 1 character.|Attribute name must not be longer than {{ limit }} characters.
presentation:
not_blank: Please enter attribute presentation.
min_length: Attribute presentation must be at least 1 character long.|Attribute presentation must be at least {{ limit }} characters long.
max_length: Attribute presentation must not be longer than 1 character.|Attribute presentation must not be longer than {{ limit }} characters.
attribute_value:
attribute:
not_blank: Please select attribute.
value:
not_blank: Please enter attribute value.

View file

@ -0,0 +1,53 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
product:
sku:
not_blank: Por favor introduzca SKU del producto.
unique: El SKU del producto debe ser único.
name:
not_blank: Por favor introduzca el nombre del producto.
min_length: 'El nombre del producto debe tener al menos 1 carácter.|El nombre de producto debe tener al menos {{ limit }} caracteres.'
max_length: 'El nombre de producto debe tener como máximo 1 carácter.|El nombre de producto no debe tener más de {{ limit }} caracteres.'
description:
not_blank: Por favor introduzca la descripción del producto.
min_length: 'La descripción de producto debe tener al menos 1 carácter.|La descripción de producto debe tener al menos {{ limit }} caracteres.'
variant:
sku:
not_blank: Por favor introduzca el SKU de la variante.
unique: El SKU de la variante debe ser único.
combination: Ya existe una variante con este conjunto de opciones.
option:
name:
not_blank: Por favor introduzca el nombre de la opción.
min_length: 'El nombre de la opción debe tener al menos 1 carácter.|El nombre de opción debe tener al menos {{ limit }} caracteres.'
max_length: 'El nombre de la opción debe tener como máximo 1 carácter.|El nombre de la opción no debe tener más de {{ limit }} caracteres.'
presentation:
not_blank: Por favor complete la presentación de la opción.
min_length: 'La presentación de la opción debe tener al menos 1 carácter.|La presentación de la opción debe tener al menos {{ limit }} caracteres.'
max_length: 'La presentación de la opción debe tener como máximo 1 carácter.|La presentación de la opción no debe tener más de {{ limit }} caracteres.'
values:
min_count: 'Por favor añada al menos {{ limit }} valor para la opción.|Por favor añada al menos {{ limit }} valores para la opción.'
option_value:
value:
not_blank: Por favor inserte un valor de opción.
property:
name:
not_blank: Por favor inserte el nombre de la propiedad.
min_length: 'El nombre de la propiedad debe tener al menos 1 carácter.|El nombre de la propiedad debe tener al menos {{ limit }} caracteres.'
max_length: 'El nombre de la propiedad debe tener como máximo 1 carácter.|El nombre de la propiedad no debe ser más largo de {{ limit }} caracteres.'
presentation:
not_blank: Por favor complete la presentación de la propiedad.
min_length: 'La presentación de la propiedad debe tener al menos 1 carácter.|La presentación la propiedad debe tener al menos {{ limit }} caracteres.'
max_length: 'La presentación de la propiedad debe tener como máximo 1 carácter.|La presentación de la propiedad no debe tener más de {{ limit }} caracteres.'
product_property:
property:
not_blank: Por favor seleccione una propiedad.
value:
not_blank: Por favor introduzca un valor para la propiedad.
prototype:
name:
not_blank: Por favor introduzca el nombre del prototipo.
min_length: 'El nombre del prototipo debe tener al menos 1 carácter.|El nombre del prototipo debe tener al menos {{ limit }} caracteres.'
max_length: 'El nombre del prototipo debe tener como máximo 1 carácter.|El nombre del prototipo no debe ser más largo de {{ limit }} caracteres.'

View file

@ -0,0 +1,53 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
product:
sku:
not_blank: "Veuillez saisir l'UGS (SKU) du produit."
unique: "L'UGS du produit doit être unique."
name:
not_blank: Veuillez saisir le nom du produit.
min_length: 'Le nom du produit doit contenir au moins 1 caractère.|Le nom du produit ne doit pas dépasser {{ limit }} caractères.'
max_length: 'Le nom du produit ne doit pas dépasser 1 caractère.|Le nom du produit ne doit pas dépasser {{ limit }} caractères.'
description:
not_blank: Veuillez saisir la description du produit.
min_length: 'La description du produit doit contenir au moins 1 caractère.|La description du produit ne doit pas dépasser {{ limit }} caractères.'
variant:
sku:
not_blank: "Veuillez saisir l'UGS (SKU) de la variante."
unique: "L'UGS de la variante doit être unique."
combination: La variante avec cette option existe déjà.
option:
name:
not_blank: "Veuillez saisir le nom de l'option."
min_length: "Le nom de l'option doit contenir au moins 1 caractère.|Le nom de l'option ne doit pas dépasser les {{ limit }} caractères."
max_length: "Le nom de l'option ne doit pas dépasser 1 caractère.|Le nom de l'option ne doit pas dépasser les {{ limit }} caractères."
presentation:
not_blank: "Veuillez saisir la présentation de l'option."
min_length: "La présentation de l'option doit contenir au moins 1 caractère.|La présentation de l'option ne doit pas dépasser les {{ limit }} caractères."
max_length: "La présentation de l'option ne doit pas dépasser 1 caractère.|La présentation de l'option ne doit pas dépasser les {{ limit }} caractères."
values:
min_count: "Veuillez ajouter au moins {{ limit }} valeur pour l'option.|Veuillez ajouter au moins {{ limit }} valeurs pour l'option."
option_value:
value:
not_blank: "Veuillez saisir la valeur de l'option."
property:
name:
not_blank: Veuillez saisir une propriété.
min_length: 'La propriété ne doit pas dépasser 1 caractère.|La propriété ne doit pas dépasser les {{ limit }} caractères.'
max_length: 'La propriété ne doit pas dépasser 1 caractère.|La propriété ne doit pas dépasser les {{ limit }} caractères.'
presentation:
not_blank: Veuillez saisir la présentation de la propriété.
min_length: 'La présentation de la propriété ne doit pas dépasser 1 caractère.|La présentation de la propriété ne doit pas dépasser les {{ limit }} caractères.'
max_length: 'La présentation de la propriété ne doit pas dépasser 1 caractère.|La présentation de la propriété ne doit pas dépasser les {{ limit }} caractères.'
product_property:
property:
not_blank: Veuillez choisir une propriété.
value:
not_blank: Veuillez saisir la propriété du produit.
prototype:
name:
not_blank: Veuillez saisir le nom du prototype.
min_length: 'Le nom du prototype de la propriété ne doit pas dépasser 1 caractère.|Le nom du prototype ne doit pas dépasser les {{ limit }} caractères.'
max_length: 'Le nom du prototype ne doit pas dépasser 1 caractère.|Le nom du prototype ne doit pas dépasser les {{ limit }} caractères.'

View file

@ -0,0 +1,53 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
product:
sku:
not_blank: Voer een product SKU in.
unique: Product SKU moet uniek zijn.
name:
not_blank: Voer een productnaam in.
min_length: 'Productnaam moet minstens 1 teken lang zijn.|Productnaam moet minstens {{ limit }} tekens lang zijn.'
max_length: 'Productnaam mag niet langer zijn dan 1 teken.|Productnaam mag niet langer zijn dan {{ limit }} tekens.'
description:
not_blank: Voer een product omschrijving in.
min_length: 'Product omschrijving moet minstens 1 teken lang zijn.|Product omschrijving moet minstens {{ limit }} tekens lang zijn.'
variant:
sku:
not_blank: Voer een variant SKU in.
unique: Variant SKU moet uniek zijn.
combination: Er bestaat al een variant met deze set opties.
option:
name:
not_blank: Voer een optie naam in.
min_length: 'Optie naam moet minstens 1 teken lang zijn.|Optie naam moet minstens {{ limit }} tekens lang zijn.'
max_length: 'Optie naam mag niet langer zijn dan 1 teken.|Optie naam mag niet langer zijn dan {{ limit }} tekens.'
presentation:
not_blank: Voer een optie weergave in.
min_length: 'Optie weergave moet minstens 1 teken lang zijn.|Optie weergave moet minstens {{ limit }} tekens lang zijn.'
max_length: 'Optie weergave mag niet langer zijn dan 1 teken.|Optie weergave mag niet langer zijn dan {{ limit }} tekens.'
values:
min_count: 'Voeg minstens {{ limit }} optie waarde toe.|Voeg minstens {{ limit }} optie waardes toe.'
option_value:
value:
not_blank: Voer een optie waarde in.
property:
name:
not_blank: Voer een eigenschap naam in.
min_length: 'Eigenschap naam moet minstens 1 teken lang zijn.|Eigenschap naam moet minstens {{ limit }} tekens lang zijn.'
max_length: 'Eigenschap naam mag niet langer zijn dan 1 teken.|Eigenschap naam mag niet langer zijn dan {{ limit }} tekens.'
presentation:
not_blank: Voer een eigenschap weergave in.
min_length: 'Eigenschap weergave moet minstens 1 teken lang zijn.|Eigenschap weergave moet minstens {{ limit }} tekens lang zijn.'
max_length: 'Eigenschap weergave mag niet langer zijn dan 1 teken.|Eigenschap weergave mag niet langer zijn dan {{ limit }} tekens.'
product_property:
property:
not_blank: Selecteer een eigenschap.
value:
not_blank: Voer een eigenschap waarde in.
prototype:
name:
not_blank: Voer een prototype naam in.
min_length: 'Prototype naam moet minstens 1 teken lang zijn.|Prototype naam moet minstens {{ limit }} tekens lang zijn.'
max_length: 'Prototype naam mag niet langer zijn dan 1 teken.|Prototype naam mag niet langer zijn dan {{ limit }} tekens.'

View file

@ -0,0 +1,28 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
product:
sku:
not_blank: Proszę podać SKU produktu.
unique: Wartość SKU musi być unikatowa.
name:
not_blank: Proszę podać nazwę produktu.
min_length: 'Nazwa produktu musi składać się z co najmniej 1 znaku. |Nazwa produktu musi składać się z co najmniej {{ limit }} znaków.'
max_length: 'Nazwa produktu nie może być dłuższa niż 1 znak. |Nazwa produktu nie może przekraczać {{ limit }} znaków.'
description:
not_blank: Proszę wprowadzić opis produktu.
min_length: 'Opis produktu musi składać się z co najmniej 1 znaku. |Opis produktu musi składać się z co najmniej {{ limit }} znaków.'
variant:
sku:
not_blank: Proszę podać SKU wariantu.
unique: Wartość SKU wariantu musi być unikatowa.
option:
name:
not_blank: Proszę wprowadzić nazwę opcji.
min_length: 'Nazwa opcji powinna być dłuższa niż jeden znak.|Nazwa opcji musi zawierać co najmniej {{ limit }} znaków.'
max_length: 'Nazwa opcji nie może być dłuższa niż jeden znak. |Nazwa opcji nie może przekraczać {{ limit }} znaków.'
presentation:
not_blank: Proszę wprowadzić nazwę publiczną.
min_length: 'Nazwa publiczna powinna zawierać co najmniej jeden znak. |Nazwa publiczna nie może przekraczać {{ limit }} znaków.'
max_length: 'Nazwa publiczna nie może być dłuższy niż jeden znak. |Nazwa publiczna nie może być dłuższa niż {{ limit }} znaków.'

View file

@ -0,0 +1,53 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
product:
sku:
not_blank: Пожалуйста введите идентификатор товарной позиции продукта.
unique: Идентификатор товарной позиции продукта должен быть уникальным.
name:
not_blank: Пожалуйста введите название продукта.
min_length: 'Название продукта должно быть не менее 1 символа.|Название продукта должно быть не менее {{ limit }} символов.'
max_length: 'Название продукта должно быть длиннее 1 символа.|Название продукта должно быть длиннее {{ limit }} символов.'
description:
not_blank: Пожалуйста введите описание продукта.
min_length: 'Описание продукта должно быть не менее 1 символа.|Описание продукта должно быть не менее {{ limit }} символов.'
variant:
sku:
not_blank: Пожалуйста введите идентификатор товарной позиции варианта.
unique: Идентификатор товарной позиции варианта должен быть уникальным.
combination: Вариант с этой опцией уже существует.
option:
name:
not_blank: Пожалуйста введите название опции.
min_length: 'Название опции должно быть не менее 1 символа.|Название опции должно быть не менее {{ limit }} символов.'
max_length: 'Название опции должно быть длиннее 1 символа.|Название опции должно быть длиннее {{ limit }} символов.'
presentation:
not_blank: Пожалуйста введите публичное название опции.
min_length: 'Публичное название опции должно быть не менее 1 символа.|Публичное название опции должно быть не менее {{ limit }} символов.'
max_length: 'Публичное название опции должно быть длиннее 1 символа.|Публичное название опции должно быть длиннее {{ limit }} символов.'
values:
min_count: 'Пожалуйста введите не меннее {{ limit }} значения опции.|Пожалуйста введите не меннее {{ limit }} значений опции.'
option_value:
value:
not_blank: Пожалуйста введите значение опции.
property:
name:
not_blank: Пожалуйста введите название свойства.
min_length: 'Название свойства должно быть не менее 1 символа.|Название свойства должно быть не менее {{ limit }} символов.'
max_length: 'Название свойства должно быть длиннее 1 символа.|Название свойства должно быть длиннее {{ limit }} символов.'
presentation:
not_blank: Пожалуйста введите публичное название свойства.
min_length: 'Публичное название свойства должно быть не менее 1 символа.|Публичное название свойства должно быть не менее {{ limit }} символов.'
max_length: 'Публичное название свойства должно быть длиннее 1 символа.|Публичное название свойства должно быть длиннее {{ limit }} символов.'
product_property:
property:
not_blank: Пожалуйста выберите свойство.
value:
not_blank: Пожалуйста выберите значение свойства.
prototype:
name:
not_blank: Пожалуйста введите название прототипа.
min_length: 'Название прототипа должно быть не менее 1 символа.|Название прототипа должно быть не менее {{ limit }} символов.'
max_length: 'Название прототипа должно быть длиннее 1 символа.|Название прототипа должно быть длиннее {{ limit }} символов.'

View file

@ -0,0 +1,10 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
product:
sku:
unique: Kód produktu musí byť unikátny.
variant:
sku:
unique: Kód variácie musí byť unikátny.

View file

@ -0,0 +1,48 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\AttributeBundle;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler\ResolveDoctrineTargetEntitiesPass;
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
/**
* @author Paweł Jędrzejewski <pjedrzejewski@diweb.pl>
*/
class SyliusAttributeBundle extends Bundle
{
/**
* Return array with currently supported drivers.
*
* @return array
*/
public static function getSupportedDrivers()
{
return array(
SyliusResourceBundle::DRIVER_DOCTRINE_ORM
);
}
/**
* {@inheritdoc}
*/
public function build(ContainerBuilder $container)
{
$mappings = array(
realpath(__DIR__ . '/Resources/config/doctrine/model') => 'Sylius\Component\Attribute\Model',
);
$container->addCompilerPass(DoctrineOrmMappingsPass::createXmlMappingDriver($mappings, array('doctrine.orm.entity_manager'), 'sylius_attribute.driver.doctrine/orm'));
}
}

View file

@ -0,0 +1,45 @@
{
"name": "sylius/attribute-bundle",
"type": "symfony-bundle",
"description": "Managing object attributes for Symfony2 applications.",
"keywords": ["shop", "ecommerce", "products", "product", "assortment"],
"homepage": "http://sylius.org",
"license": "MIT",
"authors": [
{
"name": "Paweł Jędrzejewski",
"homepage": "http://pjedrzejewski.com"
},
{
"name": "Sylius project",
"homepage": "http://sylius.org"
},
{
"name": "Community contributions",
"homepage": "http://github.com/Sylius/Sylius/contributors"
}
],
"require": {
"php": ">=5.3.3",
"symfony/framework-bundle": "~2.3",
"sylius/resource-bundle": "1.0.*@dev",
"stof/doctrine-extensions-bundle": "1.1.*"
},
"require-dev": {
"phpspec/phpspec": "~2.0",
"symfony/form": "~2.3"
},
"config": {
"bin-dir": "bin"
},
"autoload": {
"psr-0": { "Sylius\\Bundle\\AttributeBundle\\": "" }
},
"target-dir": "Sylius/Bundle/AttributeBundle",
"extra": {
"branch-alias": {
"dev-master": "0.10-dev"
}
}
}

View file

@ -9,12 +9,12 @@
* file that was distributed with this source code.
*/
namespace spec\Sylius\Bundle\ProductBundle\Form\EventListener;
namespace spec\Sylius\Bundle\AttributeBundle\Form\EventListener;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Component\Product\Model\ProductPropertyInterface;
use Sylius\Component\Product\Model\PropertyTypes;
use Sylius\Component\Attribute\Model\AttributeInterface;
use Sylius\Component\Attribute\Model\AttributeTypes;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormFactoryInterface;
@ -22,7 +22,7 @@ use Symfony\Component\Form\FormFactoryInterface;
/**
* @author Leszek Prabucki <leszek.prabucki@gmail.com>
*/
class BuildPropertyFormChoicesListenerSpec extends ObjectBehavior
class BuildAttributeFormChoicesListenerSpec extends ObjectBehavior
{
function let(FormFactoryInterface $formFactory)
{
@ -55,15 +55,15 @@ class BuildPropertyFormChoicesListenerSpec extends ObjectBehavior
function it_builds_choices_collection_for_new_object_without_type(
FormEvent $event,
Form $form,
ProductPropertyInterface $property,
AttributeInterface $attribute,
Form $collectionField,
$formFactory
)
{
$event->getData()->willReturn($property);
$event->getData()->willReturn($attribute);
$event->getForm()->willReturn($form);
$property->getType()->willReturn(null);
$attribute->getType()->willReturn(null);
$formFactory
->createNamed('choices', 'collection', null, array(
@ -80,18 +80,18 @@ class BuildPropertyFormChoicesListenerSpec extends ObjectBehavior
$this->buildChoices($event);
}
function it_builds_choices_collection_for_choice_property(
function it_builds_choices_collection_for_choice_attribute(
FormEvent $event,
Form $form,
ProductPropertyInterface $property,
AttributeInterface $attribute,
Form $collectionField,
$formFactory
)
{
$event->getData()->willReturn($property);
$event->getData()->willReturn($attribute);
$event->getForm()->willReturn($form);
$property->getType()->willReturn(PropertyTypes::CHOICE);
$attribute->getType()->willReturn(AttributeTypes::CHOICE);
$formFactory
->createNamed('choices', 'collection', null, array(
@ -108,17 +108,17 @@ class BuildPropertyFormChoicesListenerSpec extends ObjectBehavior
$this->buildChoices($event);
}
function it_does_not_build_choices_collection_for_other_than_choice_property_types(
function it_does_not_build_choices_collection_for_other_than_choice_attribute_types(
FormEvent $event,
Form $form,
ProductPropertyInterface $property,
AttributeInterface $attribute,
Form $collectionField,
$formFactory
)
{
$property->getType()->willReturn(PropertyTypes::TEXT);
$attribute->getType()->willReturn(AttributeTypes::TEXT);
$event->getData()->willReturn($property);
$event->getData()->willReturn($attribute);
$event->getForm()->willReturn($form);
$formFactory

View file

@ -9,11 +9,11 @@
* file that was distributed with this source code.
*/
namespace spec\Sylius\Bundle\ProductBundle\Form\EventListener;
namespace spec\Sylius\Bundle\AttributeBundle\Form\EventListener;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Component\Product\Model\ProductPropertyInterface;
use Sylius\Component\Attribute\Model\AttributeValueInterface;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormFactoryInterface;
@ -21,7 +21,7 @@ use Symfony\Component\Form\FormFactoryInterface;
/**
* @author Leszek Prabucki <leszek.prabucki@gmail.com>
*/
class BuildProductPropertyFormListenerSpec extends ObjectBehavior
class BuildAttributeValueFormListenerSpec extends ObjectBehavior
{
function let(FormFactoryInterface $formFactory)
{
@ -33,7 +33,7 @@ class BuildProductPropertyFormListenerSpec extends ObjectBehavior
self::getSubscribedEvents()->shouldReturn(array('form.pre_set_data' => 'buildForm'));
}
function it_builds_form_with_property_and_value_when_new_product_property(
function it_builds_form_with_attribute_and_value_when_new_product_attribute(
FormEvent $event,
Form $form,
Form $valueField,
@ -49,47 +49,47 @@ class BuildProductPropertyFormListenerSpec extends ObjectBehavior
$this->buildForm($event);
}
function it_builds_value_field_base_on_product_property(
function it_builds_value_field_base_on_product_attribute(
FormEvent $event,
Form $form,
ProductPropertyInterface $productProperty,
AttributeValueInterface $productAttribute,
Form $valueField,
$formFactory
)
{
$productProperty->getType()->willReturn('checkbox');
$productProperty->getName()->willReturn('My name');
$productProperty->getConfiguration()->willReturn(array());
$productAttribute->getType()->willReturn('checkbox');
$productAttribute->getName()->willReturn('My name');
$productAttribute->getConfiguration()->willReturn(array());
$event->getData()->willReturn($productProperty);
$event->getData()->willReturn($productAttribute);
$event->getForm()->willReturn($form);
$formFactory->createNamed('value', 'checkbox', null, array('label' => 'My name', 'auto_initialize' => false))->willReturn($valueField)->shouldBeCalled();
$form->remove('property')->shouldBeCalled()->willReturn($form);
$form->remove('attribute')->shouldBeCalled()->willReturn($form);
$form->add($valueField)->shouldBeCalled()->willReturn($form);
$this->buildForm($event);
}
function it_builds_options_base_on_product_property(
function it_builds_options_base_on_product_attribute(
FormEvent $event,
Form $form,
ProductPropertyInterface $productProperty,
AttributeValueInterface $productAttribute,
Form $valueField,
$formFactory
)
{
$productProperty->getType()->willReturn('choice');
$productProperty->getConfiguration()->willReturn(array(
$productAttribute->getType()->willReturn('choice');
$productAttribute->getConfiguration()->willReturn(array(
'choices' => array(
'red' => 'Red',
'blue' => 'Blue'
)
));
$productProperty->getName()->willReturn('My name');
$productAttribute->getName()->willReturn('My name');
$event->getData()->willReturn($productProperty);
$event->getData()->willReturn($productAttribute);
$event->getForm()->willReturn($form);
$formFactory
@ -103,7 +103,7 @@ class BuildProductPropertyFormListenerSpec extends ObjectBehavior
->shouldBeCalled()
;
$form->remove('property')->shouldBeCalled()->willReturn($form);
$form->remove('attribute')->shouldBeCalled()->willReturn($form);
$form->add($valueField)->shouldBeCalled()->willReturn($form);
$this->buildForm($event);

Some files were not shown because too many files have changed in this diff Show more