mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 09:02:12 +00:00
Merge pull request #3350 from pamil/metadata-formulas
[Metadata] Complete component & bundle integrated with Sylius Core
This commit is contained in:
commit
90ccc116dd
135 changed files with 7924 additions and 27 deletions
43
app/migrations/Version20150817113941.php
Normal file
43
app/migrations/Version20150817113941.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?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\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class Version20150817113941 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
|
||||
|
||||
$this->addSql('CREATE TABLE sylius_metadata (id INT AUTO_INCREMENT NOT NULL, `key` VARCHAR(255) NOT NULL, metadata LONGTEXT NOT NULL COMMENT \'(DC2Type:object)\', UNIQUE INDEX UNIQ_B0AF6FFB4E645A7E (`key`), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
|
||||
|
||||
$this->addSql('DROP TABLE sylius_metadata');
|
||||
}
|
||||
}
|
||||
|
|
@ -144,6 +144,19 @@ default:
|
|||
filters:
|
||||
tags: "@localization"
|
||||
|
||||
metadata:
|
||||
contexts:
|
||||
- Behat\MinkExtension\Context\MinkContext
|
||||
- Sylius\Bundle\CoreBundle\Behat\HookContext
|
||||
- Sylius\Bundle\CoreBundle\Behat\CoreContext
|
||||
- Sylius\Bundle\ChannelBundle\Behat\ChannelContext
|
||||
- Sylius\Bundle\ResourceBundle\Behat\FixtureContext
|
||||
- Sylius\Bundle\WebBundle\Behat\WebContext
|
||||
- Sylius\Bundle\ProductBundle\Behat\ProductContext
|
||||
- Sylius\Bundle\CoreBundle\Behat\MetadataContext
|
||||
filters:
|
||||
tags: "@metadata"
|
||||
|
||||
oauth:
|
||||
contexts:
|
||||
- Behat\MinkExtension\Context\MinkContext
|
||||
|
|
|
|||
75
features/backend/metadata/metadata_customization.feature
Normal file
75
features/backend/metadata/metadata_customization.feature
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
@metadata @ui
|
||||
Feature: Metadata customization
|
||||
In order to customize metadata
|
||||
As a store owner
|
||||
I want to have user-friendly metadata customization form
|
||||
|
||||
Background:
|
||||
Given store has default configuration
|
||||
And I am logged in as administrator
|
||||
|
||||
Scenario: Showing customization form
|
||||
When I am customizing metadata
|
||||
Then I should see metadata customization form
|
||||
|
||||
Scenario: Creating page metadata without Twitter metadata
|
||||
Given I am customizing metadata with identifier "FOO-BAR"
|
||||
When I fill in "Title" with "Lorem ipsum"
|
||||
And I fill in "Keywords" with "sylius, ecommerce"
|
||||
And I press "Save changes"
|
||||
Then I should be on the page of metadata container with id "FOO-BAR"
|
||||
And I should see the following metadata:
|
||||
| Title | Lorem ipsum |
|
||||
| Keywords | sylius, ecommerce |
|
||||
| Description | <empty> |
|
||||
| Twitter | <empty> |
|
||||
|
||||
@javascript
|
||||
Scenario: Managing dynamic Twitter form
|
||||
Given I am customizing metadata
|
||||
When I select "Application" from "Twitter Card"
|
||||
Then I should see Twitter's application card form
|
||||
|
||||
@javascript
|
||||
Scenario: Removing dynamic Twitter form content when select is empty
|
||||
Given I am customizing metadata
|
||||
And I select "Application" from "Twitter Card"
|
||||
When I deselect "Twitter Card"
|
||||
Then I should not see Twitter's application card form
|
||||
|
||||
@javascript
|
||||
Scenario: Creating page metadata with Twitter metadata
|
||||
Given I am customizing metadata with identifier "TWEET-IT"
|
||||
When I fill in "Title" with "Lorem ipsum"
|
||||
And I select "Player" from "Twitter Card"
|
||||
And I fill in "Site" with "@sylius"
|
||||
And I press "Save changes"
|
||||
Then I should be on the page of metadata container with id "TWEET-IT"
|
||||
And I should see the following metadata:
|
||||
| Title | Lorem ipsum |
|
||||
| Twitter.Site | @sylius |
|
||||
|
||||
@javascript
|
||||
Scenario: Setting Twitter metadata as empty after filling a few fields removes Twitter metadata
|
||||
Given I am customizing metadata with identifier "DEFAULT"
|
||||
When I fill in "Title" with "Lorem ipsum"
|
||||
And I select "Player" from "Twitter Card"
|
||||
And I fill in "Site" with "@sylius"
|
||||
And I deselect "Twitter Card"
|
||||
And I press "Save changes"
|
||||
Then I should be on the page of metadata container with id "DEFAULT"
|
||||
And I should see the following metadata:
|
||||
| Title | Lorem ipsum |
|
||||
| Twitter | <empty> |
|
||||
|
||||
@javascript
|
||||
Scenario: Setting Twitter metadata as empty removes it
|
||||
Given there is the following metadata "YOLO-616":
|
||||
| Twitter.Card | Summary |
|
||||
| Twitter.Title | Lorem ipsum |
|
||||
And I am customizing metadata with identifier "YOLO-616"
|
||||
When I deselect "Twitter Card"
|
||||
And I press "Save changes"
|
||||
Then I should be on the page of metadata container with id "YOLO-616"
|
||||
And I should see the following metadata:
|
||||
| Twitter | <empty> |
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
@metadata
|
||||
Feature: Metadata management
|
||||
In order to manage metadata on my store
|
||||
As a store owner
|
||||
I want to have easy and intuitive access to managing metadata
|
||||
|
||||
Background:
|
||||
Given store has default configuration
|
||||
And I am logged in as administrator
|
||||
|
||||
Scenario: Accessing default metadata customization page
|
||||
Given I am on the metadata container index page
|
||||
When I click "Customize default metadata"
|
||||
Then I should be customizing default metadata
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
@metadata
|
||||
Feature: Metadata management
|
||||
In order to manage metadata on my store
|
||||
As a store owner
|
||||
I want to have easy and intuitive access to managing metadata
|
||||
|
||||
Background:
|
||||
Given store has default configuration
|
||||
And there are following options:
|
||||
| code | name | presentation | values |
|
||||
| TSC | T-Shirt color | Color | Red[R], Blue[B], Green[G] |
|
||||
And the following products exist:
|
||||
| code | name | price | options |
|
||||
| STS | Super T-Shirt | 19.99 | T-Shirt color |
|
||||
And product "Super T-Shirt" is available in all variations
|
||||
And I am logged in as administrator
|
||||
|
||||
Scenario: Accessing specific product variant metadata customization page
|
||||
Given I am on the page of product "Super T-Shirt"
|
||||
When I click "Customize metadata" near "Color: Red"
|
||||
Then I should be customizing specific product variant metadata
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
@metadata
|
||||
Feature: Metadata management
|
||||
In order to manage metadata on my store
|
||||
As a store owner
|
||||
I want to have easy and intuitive access to managing metadata
|
||||
|
||||
Background:
|
||||
Given store has default configuration
|
||||
And there are products:
|
||||
| name | price |
|
||||
| Banana | 4.20 |
|
||||
And I am logged in as administrator
|
||||
|
||||
Scenario: Accessing products metadata customization page
|
||||
Given I am on the product index page
|
||||
When I click "Customize products metadata"
|
||||
Then I should be customizing products metadata
|
||||
|
||||
Scenario: Accessing specific product metadata customization page via index page
|
||||
Given I am on the product index page
|
||||
When I click "Customize metadata" near "Banana"
|
||||
Then I should be customizing specific product metadata
|
||||
|
||||
Scenario: Accessing specific product metadata customization page via product page
|
||||
Given I am on the page of product "Banana"
|
||||
When I click "Customize metadata"
|
||||
Then I should be customizing specific product metadata
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
@metadata
|
||||
Feature: Metadata rendering
|
||||
In order to manage metadata on my store
|
||||
As a store owner
|
||||
I want to have easy and intuitive access to managing metadata
|
||||
|
||||
Background:
|
||||
Given store has default configuration
|
||||
And there are products:
|
||||
| name | price |
|
||||
| Banana | 4.20 |
|
||||
And product "Banana" has the following page metadata:
|
||||
| Title | Tasty banana |
|
||||
| Description | The best you have ever eaten! |
|
||||
| Keywords | banana, fruit, healthy food |
|
||||
| Twitter.Card | Summary |
|
||||
| Twitter.Site | @example |
|
||||
| Twitter.Image | http://example.com/image.jpg |
|
||||
And all products are assigned to the default channel
|
||||
|
||||
Scenario: Rendering page metadata
|
||||
When I am on the product page for "Banana"
|
||||
Then I should see "Tasty banana" as page title
|
||||
And the page keywords should contain "fruit"
|
||||
|
||||
Scenario: Rendering page Twitter metadata
|
||||
When I am on the product page for "Banana"
|
||||
Then there should be Twitter summary card metadata on this page
|
||||
And Twitter site should be "@example"
|
||||
And Twitter image should be "http://example.com/image.jpg"
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
@metadata
|
||||
Feature: Metadata rendering & processing
|
||||
In order to render metadata dynamically
|
||||
As a store owner
|
||||
I want to be able to use expressions and Twig templating engine in metadata properties
|
||||
|
||||
Background:
|
||||
Given store has default configuration
|
||||
And there are products:
|
||||
| name | price |
|
||||
| Banana | 4.20 |
|
||||
And product "Banana" has the following page metadata:
|
||||
| Title | {{ subject.name }} - Sylius |
|
||||
And all products are assigned to the default channel
|
||||
|
||||
Scenario: Rendering processed page metadata
|
||||
When I am on the product page for "Banana"
|
||||
Then I should see "Banana - Sylius" as page title
|
||||
|
|
@ -10,6 +10,7 @@ suites:
|
|||
Inventory: { namespace: Sylius\Component\Inventory, psr4_prefix: Sylius\Component\Inventory, spec_path: src/Sylius/Component/Inventory, src_path: src/Sylius/Component/Inventory }
|
||||
Locale: { namespace: Sylius\Component\Locale, psr4_prefix: Sylius\Component\Locale, spec_path: src/Sylius/Component/Locale, src_path: src/Sylius/Component/Locale }
|
||||
Mailer: { namespace: Sylius\Component\Mailer, psr4_prefix: Sylius\Component\Mailer, spec_path: src/Sylius/Component/Mailer, src_path: src/Sylius/Component/Mailer }
|
||||
Metadata: { namespace: Sylius\Component\Metadata, psr4_prefix: Sylius\Component\Metadata, spec_path: src/Sylius/Component/Metadata, src_path: src/Sylius/Component/Metadata }
|
||||
Order: { namespace: Sylius\Component\Order, psr4_prefix: Sylius\Component\Order, spec_path: src/Sylius/Component/Order, src_path: src/Sylius/Component/Order }
|
||||
Originator: { namespace: Sylius\Component\Originator, psr4_prefix: Sylius\Component\Originator, spec_path: src/Sylius/Component/Originator, src_path: src/Sylius/Component/Originator }
|
||||
Payment: { namespace: Sylius\Component\Payment, psr4_prefix: Sylius\Component\Payment, spec_path: src/Sylius/Component/Payment, src_path: src/Sylius/Component/Payment }
|
||||
|
|
@ -45,6 +46,7 @@ suites:
|
|||
InventoryBundle: { namespace: Sylius\Bundle\InventoryBundle, psr4_prefix: Sylius\Bundle\InventoryBundle, spec_path: src/Sylius/Bundle/InventoryBundle, src_path: src/Sylius/Bundle/InventoryBundle }
|
||||
LocaleBundle: { namespace: Sylius\Bundle\LocaleBundle, psr4_prefix: Sylius\Bundle\LocaleBundle, spec_path: src/Sylius/Bundle/LocaleBundle, src_path: src/Sylius/Bundle/LocaleBundle }
|
||||
MailerBundle: { namespace: Sylius\Bundle\MailerBundle, psr4_prefix: Sylius\Bundle\MailerBundle, spec_path: src/Sylius/Bundle/MailerBundle, src_path: src/Sylius/Bundle/MailerBundle }
|
||||
MetadataBundle: { namespace: Sylius\Bundle\MetadataBundle, psr4_prefix: Sylius\Bundle\MetadataBundle, spec_path: src/Sylius/Bundle/MetadataBundle, src_path: src/Sylius/Bundle/MetadataBundle }
|
||||
MoneyBundle: { namespace: Sylius\Bundle\MoneyBundle, psr4_prefix: Sylius\Bundle\MoneyBundle, spec_path: src/Sylius/Bundle/MoneyBundle, src_path: src/Sylius/Bundle/MoneyBundle }
|
||||
OrderBundle: { namespace: Sylius\Bundle\OrderBundle, psr4_prefix: Sylius\Bundle\OrderBundle, spec_path: src/Sylius/Bundle/OrderBundle, src_path: src/Sylius/Bundle/OrderBundle }
|
||||
PaymentBundle: { namespace: Sylius\Bundle\PaymentBundle, psr4_prefix: Sylius\Bundle\PaymentBundle, spec_path: src/Sylius/Bundle/PaymentBundle, src_path: src/Sylius/Bundle/PaymentBundle }
|
||||
|
|
|
|||
393
src/Sylius/Bundle/CoreBundle/Behat/MetadataContext.php
Normal file
393
src/Sylius/Bundle/CoreBundle/Behat/MetadataContext.php
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
<?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\CoreBundle\Behat;
|
||||
|
||||
use Behat\Behat\Tester\Exception\PendingException;
|
||||
use Behat\Gherkin\Node\TableNode;
|
||||
use Behat\Mink\Element\ElementInterface;
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Sylius\Bundle\ResourceBundle\Behat\DefaultContext;
|
||||
use Sylius\Component\Core\Model\ProductInterface;
|
||||
use Sylius\Component\Metadata\Model\Custom\PageMetadata;
|
||||
use Sylius\Component\Metadata\Model\Custom\PageMetadataInterface;
|
||||
use Sylius\Component\Metadata\Model\MetadataContainerInterface;
|
||||
use Sylius\Component\Metadata\Model\Twitter\AppCard;
|
||||
use Sylius\Component\Metadata\Model\Twitter\CardInterface;
|
||||
use Sylius\Component\Metadata\Model\Twitter\PlayerCard;
|
||||
use Sylius\Component\Metadata\Model\Twitter\SummaryCard;
|
||||
use Sylius\Component\Metadata\Model\Twitter\SummaryLargeImageCard;
|
||||
use Symfony\Component\PropertyAccess\PropertyAccessor;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class MetadataContext extends DefaultContext
|
||||
{
|
||||
/**
|
||||
* @var PropertyAccessor
|
||||
*/
|
||||
private $propertyAccessor;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct($applicationName = null)
|
||||
{
|
||||
parent::__construct($applicationName);
|
||||
|
||||
$this->propertyAccessor = new PropertyAccessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I am customizing metadata
|
||||
* @When I am customizing metadata with identifier :identifier
|
||||
*/
|
||||
public function iAmCustomizingMetadata($identifier = 'FooBar')
|
||||
{
|
||||
$this->getSession()->visit($this->generateUrl('sylius_backend_metadata_container_customize', ['id' => $identifier]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should see metadata customization form
|
||||
*/
|
||||
public function iShouldSeeMetadataCustomizationForm()
|
||||
{
|
||||
$this->assertThereIsFormWithFields(
|
||||
$this->getSession()->getPage(),
|
||||
['Title', 'Description', 'Keywords', 'Twitter Card']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should see the following metadata:
|
||||
*/
|
||||
public function iShouldSeeTheFollowingMetadata(TableNode $metadata)
|
||||
{
|
||||
/** @var NodeElement $table */
|
||||
$table = $this->getSession()->getPage()->find('css', '#content > table');
|
||||
|
||||
/** @var NodeElement $row */
|
||||
$row = $table->findAll('css', 'tr')[1];
|
||||
|
||||
/** @var NodeElement[] $columns */
|
||||
$columns = $row->findAll('css', 'td');
|
||||
|
||||
$contentIndex = $this->getColumnIndex($table, 'Content');
|
||||
|
||||
/** @var NodeElement $list */
|
||||
$list = $columns[$contentIndex];
|
||||
foreach ($metadata->getRowsHash() as $key => $value) {
|
||||
$currentElement = $list;
|
||||
$parts = explode('.', $key);
|
||||
|
||||
foreach ($parts as $part) {
|
||||
$currentElement = $currentElement->find('xpath', sprintf('/ul/li[starts-with(normalize-space(.), "%s:")]', $part));
|
||||
}
|
||||
|
||||
$exploded = explode(':', $currentElement->getText());
|
||||
$text = trim(end($exploded));
|
||||
|
||||
$expectedValue = $value;
|
||||
if ('<empty>' === $expectedValue) {
|
||||
$expectedValue = 'empty';
|
||||
} elseif (false !== strpos($expectedValue, ',')) {
|
||||
$expectedValue = str_replace([', ', ','], [' ', ' '], $expectedValue);
|
||||
}
|
||||
|
||||
if ($text !== $expectedValue) {
|
||||
throw new \Exception(sprintf(
|
||||
'Expected "%s", got "%s" (item: "%s", original value: "%s")',
|
||||
$expectedValue,
|
||||
$text,
|
||||
$key,
|
||||
$value
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should be customizing default metadata
|
||||
*/
|
||||
public function iShouldBeCustomizingDefaultMetadata()
|
||||
{
|
||||
$this->assertItIsMetadataCustomizationPage(
|
||||
$this->getSession()->getPage(),
|
||||
'/DefaultPage/'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should be customizing products metadata
|
||||
*/
|
||||
public function iShouldBeCustomizingProductsMetadata()
|
||||
{
|
||||
$this->assertItIsMetadataCustomizationPage(
|
||||
$this->getSession()->getPage(),
|
||||
'/Product(?!\-)/'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should be customizing specific product metadata
|
||||
*/
|
||||
public function iShouldBeCustomizingSpecificProductMetadata()
|
||||
{
|
||||
$this->assertItIsMetadataCustomizationPage(
|
||||
$this->getSession()->getPage(),
|
||||
'/Product-\d+/'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should be customizing specific product variant metadata
|
||||
*/
|
||||
public function iShouldBeCustomizingSpecificProductVariantMetadata()
|
||||
{
|
||||
$this->assertItIsMetadataCustomizationPage(
|
||||
$this->getSession()->getPage(),
|
||||
'/ProductVariant-\d+/'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should see Twitter's application card form
|
||||
*/
|
||||
public function iShouldSeeTwitterApplicationCardForm()
|
||||
{
|
||||
$this->assertSession()->fieldExists('Iphone application name');
|
||||
$this->assertSession()->fieldExists('Ipad application url');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should not see Twitter's application card form
|
||||
*/
|
||||
public function iShouldNotSeeTwitterApplicationCardForm()
|
||||
{
|
||||
$this->assertSession()->fieldNotExists('Iphone application name');
|
||||
$this->assertSession()->fieldNotExists('Ipad application url');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given there is the following metadata :metadataName:
|
||||
*/
|
||||
public function thereIsTheFollowingMetadata($metadataName, TableNode $table)
|
||||
{
|
||||
/** @var MetadataContainerInterface $metadata */
|
||||
$metadata = $this->getFactory('metadata_container')->createNew();
|
||||
|
||||
$pageMetadata = new PageMetadata();
|
||||
|
||||
$metadata->setId($metadataName);
|
||||
$metadata->setMetadata($pageMetadata);
|
||||
|
||||
foreach ($table->getRowsHash() as $key => $value) {
|
||||
if ($this->createNewMetadataObjectIfNeeded($pageMetadata, $key, $value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false !== strpos($value, ',')) {
|
||||
$value = array_map('trim', explode(',', $value));
|
||||
}
|
||||
|
||||
$this->propertyAccessor->setValue($pageMetadata, $key, $value);
|
||||
}
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
$em->persist($metadata);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given product :productName has the following page metadata:
|
||||
*/
|
||||
public function productHasTheFollowingPageMetadata($productName, TableNode $table)
|
||||
{
|
||||
/** @var ProductInterface $product */
|
||||
$product = $this->getRepository('product')->findOneBy(['name' => $productName]);
|
||||
|
||||
$this->thereIsTheFollowingMetadata($product->getMetadataIdentifier(), $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then I should see :title as page title
|
||||
*/
|
||||
public function iShouldSeeAsPageTitle($title)
|
||||
{
|
||||
$this->assertSession()->elementTextContains('css', 'title', $title);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then the page keywords should contain :keyword
|
||||
*/
|
||||
public function thePageKeywordsShouldContain($keyword)
|
||||
{
|
||||
$this->assertSession()->elementExists('css', sprintf('meta[name="keywords"][content*="%s"]', $keyword));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then there should be Twitter summary card metadata on this page
|
||||
*/
|
||||
public function thereShouldBeTwitterSummaryCardMetadataOnThisPage()
|
||||
{
|
||||
$this->assertSession()->elementExists('css', 'meta[name="twitter:card"][content="summary"]');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then Twitter site should be :site
|
||||
*/
|
||||
public function twitterSiteShouldBe($site)
|
||||
{
|
||||
$this->assertSession()->elementExists('css', sprintf('meta[name="twitter:site"][content="%s"]', $site));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then Twitter image should be :image
|
||||
*/
|
||||
public function twitterImageShouldBe($image)
|
||||
{
|
||||
$this->assertSession()->elementExists('css', sprintf('meta[name="twitter:image"][content="%s"]', $image));
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /I deselect "([^"]+)"/
|
||||
*/
|
||||
public function iDeselectSelectField($fieldName)
|
||||
{
|
||||
$this->selectOption($fieldName, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ElementInterface $element
|
||||
* @param string $regexp
|
||||
*
|
||||
* @throws \Exception If assertion failed
|
||||
*/
|
||||
private function assertItIsMetadataCustomizationPage(ElementInterface $element, $regexp)
|
||||
{
|
||||
if (!$this->isItMetadataCustomizationPage($element, $regexp)) {
|
||||
throw new \Exception(sprintf("It is not metadata customziation page (regexp: %s)", $regexp));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ElementInterface $element
|
||||
* @param string $regexp
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isItMetadataCustomizationPage(ElementInterface $element, $regexp)
|
||||
{
|
||||
$header = $element->find('css', '.page-header h1');
|
||||
|
||||
if (null === $header) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === strpos($header->getText(), "Customizing metadata")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === (bool) preg_match($regexp, $header->getText())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ElementInterface $element
|
||||
* @param array $fields
|
||||
*
|
||||
* @throws \Exception If assertion failed
|
||||
*/
|
||||
private function assertThereIsFormWithFields(ElementInterface $element, array $fields)
|
||||
{
|
||||
if (null === $this->getFormWithFields($element, $fields)) {
|
||||
throw new \Exception(sprintf("Could not found table with fields: %s", implode(', ', $fields)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ElementInterface $element
|
||||
* @param string[] $fields
|
||||
*
|
||||
* @return ElementInterface|null
|
||||
*/
|
||||
private function getFormWithFields(ElementInterface $element, array $fields)
|
||||
{
|
||||
/** @var NodeElement[] $forms */
|
||||
$forms = $element->findAll('css', 'form');
|
||||
|
||||
foreach ($forms as $form) {
|
||||
$found = true;
|
||||
foreach ($fields as $field) {
|
||||
if (null === $form->findField($field)) {
|
||||
$found = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($found) {
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return CardInterface
|
||||
*/
|
||||
protected function createTwitterCardFromString($value)
|
||||
{
|
||||
switch (strtolower($value)) {
|
||||
case 'summary':
|
||||
return new SummaryCard();
|
||||
|
||||
case 'summary with large image':
|
||||
case 'summary large image':
|
||||
case 'summarylargeimage':
|
||||
return new SummaryLargeImageCard();
|
||||
|
||||
case 'player':
|
||||
return new PlayerCard();
|
||||
|
||||
case 'app':
|
||||
case 'application':
|
||||
return new AppCard();
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException(sprintf('Unknown card type "%s"!', $value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PageMetadataInterface $pageMetadata
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*
|
||||
* @return boolean True if created new metadata object
|
||||
*/
|
||||
protected function createNewMetadataObjectIfNeeded(PageMetadataInterface $pageMetadata, $key, $value)
|
||||
{
|
||||
if ('twitter.card' === strtolower($key)) {
|
||||
$pageMetadata->setTwitter($this->createTwitterCardFromString($value));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -77,6 +77,7 @@ class SyliusCoreExtension extends AbstractResourceExtension implements PrependEx
|
|||
'reports.xml',
|
||||
'state_machine.xml',
|
||||
'email.xml',
|
||||
'metadata.xml',
|
||||
);
|
||||
|
||||
$env = $container->getParameter('kernel.environment');
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ abstract class Kernel extends BaseKernel
|
|||
new \Sylius\Bundle\UserBundle\SyliusUserBundle(),
|
||||
new \Sylius\Bundle\UiBundle\SyliusUiBundle(),
|
||||
new \Sylius\Bundle\AdminBundle\SyliusAdminBundle(),
|
||||
new \Sylius\Bundle\MetadataBundle\SyliusMetadataBundle(),
|
||||
|
||||
new \Sylius\Bundle\CoreBundle\SyliusCoreBundle(),
|
||||
new \Sylius\Bundle\WebBundle\SyliusWebBundle(),
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ sylius_archetype:
|
|||
product:
|
||||
archetype:
|
||||
classes:
|
||||
model: Sylius\Component\Product\Model\Archetype
|
||||
model: Sylius\Component\Core\Model\Archetype
|
||||
translation:
|
||||
classes:
|
||||
model: Sylius\Component\Product\Model\ArchetypeTranslation
|
||||
|
|
@ -345,6 +345,13 @@ sylius_rbac:
|
|||
sylius.group.create: Create group
|
||||
sylius.group.update: Edit group
|
||||
sylius.group.delete: Delete group
|
||||
|
||||
sylius.manage.metadata: Manage metadatas
|
||||
sylius.metadata.show: Show metadata
|
||||
sylius.metadata.index: List metadatas
|
||||
sylius.metadata.create: Create metadata
|
||||
sylius.metadata.update: Edit metadata
|
||||
sylius.metadata.delete: Delete metadata
|
||||
|
||||
sylius.manage.channel: Manage channels
|
||||
sylius.channel.show: Show channel
|
||||
|
|
@ -648,6 +655,7 @@ sylius_rbac:
|
|||
sylius.taxes: Manage taxes
|
||||
sylius.support: Manage customer support
|
||||
permissions_hierarchy:
|
||||
sylius.manage.metadata: [sylius.metadata.show, sylius.metadata.index, sylius.metadata.create, sylius.metadata.update, sylius.metadata.delete]
|
||||
sylius.manage.channel: [sylius.channel.show, sylius.channel.index, sylius.channel.create, sylius.channel.update, sylius.channel.delete]
|
||||
sylius.manage.customer: [sylius.customer.show, sylius.customer.index, sylius.customer.create, sylius.customer.update, sylius.customer.delete]
|
||||
sylius.manage.group: [sylius.group.show, sylius.group.index, sylius.group.create, sylius.group.update, sylius.group.delete]
|
||||
|
|
@ -691,12 +699,11 @@ sylius_rbac:
|
|||
sylius.manage.contact_request: [sylius.contact_request.show, sylius.contact_request.index, sylius.contact_request.create, sylius.contact_request.update, sylius.contact_request.delete]
|
||||
sylius.manage.contact_topic: [sylius.contact_topic.show, sylius.contact_topic.index, sylius.contact_topic.create, sylius.contact_topic.update, sylius.contact_topic.delete]
|
||||
sylius.manage.settings: [sylius.settings.sylius_general, sylius.settings.sylius_security, sylius.settings.sylius_taxation]
|
||||
|
||||
sylius.catalog: [sylius.manage.product, sylius.manage.product_attribute, sylius.manage.product_option, sylius.manage.product_archetype, sylius.manage.product_variant, sylius.manage.taxonomy, sylius.manage.taxon]
|
||||
sylius.catalog: [sylius.manage.product, sylius.manage.product_attribute, sylius.manage.product_option, sylius.manage.product_archetype, sylius.manage.product_variant, sylius.manage.taxonomy, sylius.manage.taxon, sylius.manage.metadata]
|
||||
sylius.marketing: [sylius.manage.promotion, sylius.manage.promotion_coupon, sylius.manage.email, sylius.manage.metadata]
|
||||
sylius.sales: [sylius.manage.order, sylius.manage.order_item, sylius.manage.adjustment, sylius.manage.payment, sylius.manage.report]
|
||||
sylius.marketing: [sylius.manage.promotion, sylius.manage.promotion_coupon, sylius.manage.email]
|
||||
sylius.shipping: [sylius.manage.shipment, sylius.manage.shipping_method, sylius.manage.shipping_category]
|
||||
sylius.content: [sylius.manage.static_content, sylius.manage.route, sylius.manage.simple_block, sylius.manage.menu, sylius.manage.slideshow, sylius.manage.string_block, sylius.manage.slideshow_block, sylius.manage.imagine_block]
|
||||
sylius.content: [sylius.manage.static_content, sylius.manage.route, sylius.manage.simple_block, sylius.manage.menu, sylius.manage.slideshow, sylius.manage.string_block, sylius.manage.slideshow_block, sylius.manage.imagine_block, sylius.manage.metadata]
|
||||
sylius.security: [sylius.manage.permission, sylius.manage.role, sylius.manage.customer, sylius.manage.group, sylius.accounts]
|
||||
sylius.accounts: [sylius.manage.customer, sylius.manage.group]
|
||||
sylius.taxes: [sylius.manage.tax_rate, sylius.manage.tax_category]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
|
||||
<mapped-superclass name="Sylius\Component\Core\Model\Archetype" table="sylius_product_archetype" />
|
||||
|
||||
</doctrine-mapping>
|
||||
41
src/Sylius/Bundle/CoreBundle/Resources/config/metadata.xml
Normal file
41
src/Sylius/Bundle/CoreBundle/Resources/config/metadata.xml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
|
||||
<container xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||||
http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<parameters>
|
||||
<parameter key="sylius.metadata.hierarchy_provider.product.class">Sylius\Component\Core\Metadata\HierarchyProvider\ProductHierarchyProvider</parameter>
|
||||
<parameter key="sylius.metadata.hierarchy_provider.product_variant.class">Sylius\Component\Core\Metadata\HierarchyProvider\ProductVariantHierarchyProvider</parameter>
|
||||
|
||||
<parameter key="sylius.metadata.provider.core.class">Sylius\Component\Core\Metadata\Provider\MetadataProvider</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
<service id="sylius.metadata.provider.core" class="%sylius.metadata.provider.core.class%" decorates="sylius.metadata.provider" public="false">
|
||||
<argument type="service" id="sylius.metadata.provider.core.inner" />
|
||||
<argument type="service" id="sylius.metadata.hierarchy_provider" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.hierarchy_provider.product" class="%sylius.metadata.hierarchy_provider.product.class%" public="false">
|
||||
<tag name="sylius.metadata_hierarchy_provider" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.hierarchy_provider.product_variant" class="%sylius.metadata.hierarchy_provider.product_variant.class%" public="false">
|
||||
<tag name="sylius.metadata_hierarchy_provider" />
|
||||
</service>
|
||||
</services>
|
||||
|
||||
</container>
|
||||
7
src/Sylius/Bundle/MetadataBundle/.gitignore
vendored
Normal file
7
src/Sylius/Bundle/MetadataBundle/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
vendor/
|
||||
bin/
|
||||
|
||||
composer.phar
|
||||
composer.lock
|
||||
|
||||
phpspec.yml
|
||||
15
src/Sylius/Bundle/MetadataBundle/.travis.yml
Normal file
15
src/Sylius/Bundle/MetadataBundle/.travis.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
language: php
|
||||
|
||||
sudo: false
|
||||
|
||||
php:
|
||||
- 7.0
|
||||
- 5.6
|
||||
- 5.5
|
||||
|
||||
before_script:
|
||||
- phpenv config-rm xdebug.ini || true
|
||||
- composer install --no-interaction --prefer-source
|
||||
|
||||
script:
|
||||
- vendor/bin/phpspec run -f pretty --verbose
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?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\MetadataBundle\Controller;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class MetadataController extends ResourceController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function customizeAction(Request $request)
|
||||
{
|
||||
try {
|
||||
return $this->updateAction($request);
|
||||
} catch (NotFoundHttpException $exception) {
|
||||
return $this->createAction($request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
<?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\MetadataBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class DynamicFormsChoicesMapCompilerPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* @var ContainerBuilder
|
||||
*/
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
if (!$container->hasDefinition('sylius.metadata.dynamic_forms_choices_map')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition('sylius.metadata.dynamic_forms_choices_map');
|
||||
|
||||
$taggedServices = $container->findTaggedServiceIds('sylius.metadata.dynamic_form_choice');
|
||||
|
||||
foreach ($taggedServices as $id => $tags) {
|
||||
$formDefinition = $container->getDefinition($id);
|
||||
|
||||
$dataClass = $this->getFormDataClass($formDefinition);
|
||||
$formName = $this->getFormName($formDefinition);
|
||||
|
||||
$definition->addMethodCall('addForm', [
|
||||
$tags[0]['group'],
|
||||
$dataClass,
|
||||
$formName,
|
||||
isset($tags[0]['label']) ? $tags[0]['label'] : $formName
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Definition $formDefinition
|
||||
*
|
||||
* @return string Form data class
|
||||
*/
|
||||
private function getFormDataClass(Definition $formDefinition)
|
||||
{
|
||||
$tags = $formDefinition->getTag('sylius.metadata.dynamic_form_choice');
|
||||
$class = isset($tags[0]['class']) ? $tags[0]['class'] : null;
|
||||
|
||||
if (null === $class) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Definition "%s" tagged by "%s" should define class attribute in tag definition',
|
||||
$formDefinition->getClass(),
|
||||
'sylius.metadata.dynamic_form'
|
||||
));
|
||||
}
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Definition $formDefinition
|
||||
*
|
||||
* @return string Form name
|
||||
*/
|
||||
private function getFormName(Definition $formDefinition)
|
||||
{
|
||||
$tags = $formDefinition->getTag('form.type');
|
||||
$formName = isset($tags[0]['alias']) ? $tags[0]['alias'] : null;
|
||||
|
||||
if (null === $formName) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Definition "%s" tagged by "%s" should also be tagged by "%s" with attribute "%s"',
|
||||
$formDefinition->getClass(),
|
||||
'sylius.metadata.dynamic_form',
|
||||
'form.type',
|
||||
'alias'
|
||||
));
|
||||
}
|
||||
|
||||
return $formName;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?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\MetadataBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class MetadataHierarchyProviderCompilerPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition('sylius.metadata.hierarchy_provider')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition('sylius.metadata.hierarchy_provider');
|
||||
|
||||
$taggedServices = $container->findTaggedServiceIds('sylius.metadata_hierarchy_provider');
|
||||
|
||||
$hierarchyProviders = $definition->getArgument(0) ?: [];
|
||||
foreach ($taggedServices as $id => $tags) {
|
||||
$hierarchyProviders[] = new Reference($id);
|
||||
}
|
||||
|
||||
$definition->replaceArgument(0, $hierarchyProviders);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?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\MetadataBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class MetadataRendererCompilerPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition('sylius.metadata.renderer')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition('sylius.metadata.renderer');
|
||||
|
||||
$taggedServices = $container->findTaggedServiceIds('sylius.metadata_renderer');
|
||||
|
||||
$renderers = [];
|
||||
foreach ($taggedServices as $id => $tags) {
|
||||
$renderers[] = new Reference($id);
|
||||
}
|
||||
|
||||
$definition->setArguments([$renderers]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<?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\MetadataBundle\DependencyInjection;
|
||||
|
||||
use Sylius\Bundle\MetadataBundle\Controller\MetadataController;
|
||||
use Sylius\Bundle\MetadataBundle\Form\Type\MetadataContainerType;
|
||||
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
|
||||
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
|
||||
use Sylius\Bundle\MetadataBundle\Model\MetadataContainer;
|
||||
use Sylius\Component\Metadata\Factory\MetadataContainerFactory;
|
||||
use Sylius\Component\Metadata\Model\MetadataContainerInterface;
|
||||
use Sylius\Component\Resource\Factory\Factory;
|
||||
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 Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class Configuration implements ConfigurationInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfigTreeBuilder()
|
||||
{
|
||||
$treeBuilder = new TreeBuilder();
|
||||
$rootNode = $treeBuilder->root('sylius_metadata');
|
||||
|
||||
$rootNode
|
||||
->children()
|
||||
->scalarNode('driver')->defaultValue(SyliusResourceBundle::DRIVER_DOCTRINE_ORM)->end()
|
||||
->end()
|
||||
;
|
||||
|
||||
$this->addResourcesSection($rootNode);
|
||||
|
||||
return $treeBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ArrayNodeDefinition $node
|
||||
*/
|
||||
private function addResourcesSection(ArrayNodeDefinition $node)
|
||||
{
|
||||
$resourcesBuilder = $node
|
||||
->fixXmlConfig('resource')
|
||||
->children()
|
||||
->arrayNode('resources')
|
||||
->addDefaultsIfNotSet()
|
||||
->children()
|
||||
;
|
||||
|
||||
$resourcesBuilder
|
||||
->arrayNode('metadata_container')
|
||||
->addDefaultsIfNotSet()
|
||||
->children()
|
||||
->variableNode('options')->end()
|
||||
->arrayNode('classes')
|
||||
->addDefaultsIfNotSet()
|
||||
->children()
|
||||
->scalarNode('model')->defaultValue(MetadataContainer::class)->cannotBeEmpty()->end()
|
||||
->scalarNode('interface')->defaultValue(MetadataContainerInterface::class)->cannotBeEmpty()->end()
|
||||
->scalarNode('controller')->defaultValue(MetadataController::class)->cannotBeEmpty()->end()
|
||||
->scalarNode('repository')->cannotBeEmpty()->end()
|
||||
->scalarNode('factory')->defaultValue(MetadataContainerFactory::class)->end()
|
||||
->arrayNode('form')
|
||||
->addDefaultsIfNotSet()
|
||||
->children()
|
||||
->scalarNode('default')->defaultValue(MetadataContainerType::class)->cannotBeEmpty()->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->arrayNode('validation_groups')
|
||||
->addDefaultsIfNotSet()
|
||||
->children()
|
||||
->arrayNode('default')
|
||||
->prototype('scalar')->end()
|
||||
->defaultValue(array('sylius'))
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<?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\MetadataBundle\DependencyInjection;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\DependencyInjection\Extension\AbstractResourceExtension;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
|
||||
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class SyliusMetadataExtension extends AbstractResourceExtension implements PrependExtensionInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(array $config, ContainerBuilder $container)
|
||||
{
|
||||
$config = $this->processConfiguration(new Configuration(), $config);
|
||||
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
|
||||
|
||||
$this->registerResources('sylius', $config['driver'], $config['resources'], $container);
|
||||
|
||||
$loader->load('services.xml');
|
||||
$loader->load('forms.xml');
|
||||
|
||||
$container
|
||||
->getDefinition('sylius.form.type.page_metadata')
|
||||
->addArgument(new Reference('sylius.metadata.dynamic_form_choice_builder'))
|
||||
;
|
||||
|
||||
$this->addDynamicChoiceTagToForm($container, 'twitter', 'twitter_summary_card');
|
||||
$this->addDynamicChoiceTagToForm($container, 'twitter', 'twitter_summary_large_image_card');
|
||||
$this->addDynamicChoiceTagToForm($container, 'twitter', 'twitter_player_card');
|
||||
$this->addDynamicChoiceTagToForm($container, 'twitter', 'twitter_app_card');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepend(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasExtension('twig')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$container->prependExtensionConfig('twig', [
|
||||
'form_themes' => [
|
||||
'SyliusMetadataBundle:Form:dynamic_form_theme.html.twig',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContainerBuilder $container
|
||||
* @param string $group
|
||||
* @param string $formName
|
||||
*/
|
||||
private function addDynamicChoiceTagToForm(ContainerBuilder $container, $group, $formName)
|
||||
{
|
||||
$serviceName = 'sylius.form.type.' . $formName;
|
||||
|
||||
if (!$container->hasDefinition($serviceName)) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Service "%s" was not found!',
|
||||
$serviceName
|
||||
));
|
||||
}
|
||||
|
||||
$formDefinition = $container->getDefinition($serviceName);
|
||||
$formDefinition->addTag('sylius.metadata.dynamic_form_choice', [
|
||||
'group' => $group,
|
||||
'label' => 'sylius.metadata.type.' . $formName,
|
||||
'class' => $formDefinition->getArgument(0),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
<?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\MetadataBundle\DynamicForm;
|
||||
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
final class DynamicFormBuilder implements DynamicFormBuilderInterface
|
||||
{
|
||||
/**
|
||||
* @var DynamicFormsChoicesMapInterface
|
||||
*/
|
||||
private $dynamicFormsChildrenMap;
|
||||
|
||||
/**
|
||||
* @var PropertyAccessorInterface
|
||||
*/
|
||||
private $propertyAccessor;
|
||||
|
||||
/**
|
||||
* @param DynamicFormsChoicesMapInterface $dynamicFormsChildrenMap
|
||||
* @param PropertyAccessorInterface $propertyAccessor
|
||||
*/
|
||||
public function __construct(DynamicFormsChoicesMapInterface $dynamicFormsChildrenMap, PropertyAccessorInterface $propertyAccessor)
|
||||
{
|
||||
$this->dynamicFormsChildrenMap = $dynamicFormsChildrenMap;
|
||||
$this->propertyAccessor = $propertyAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildDynamicForm(FormBuilderInterface $builder, $name, $type, array $options = [])
|
||||
{
|
||||
$builder->add($name, $type, $options);
|
||||
|
||||
$this->addModelDataListener($builder, $name, $builder->get($name)->getOption('group'));
|
||||
$this->addSubmittedDataListener($builder, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface $dynamicFormBuilder
|
||||
* @param FormInterface $dynamicForm
|
||||
* @param string $formName
|
||||
*/
|
||||
private function addEmbeddedFormField(FormBuilderInterface $dynamicFormBuilder, FormInterface $dynamicForm, $formName)
|
||||
{
|
||||
$embeddedForm = $dynamicFormBuilder->getFormFactory()->createNamed(
|
||||
$dynamicFormBuilder->getName(),
|
||||
$formName,
|
||||
null,
|
||||
['auto_initialize' => false]
|
||||
);
|
||||
|
||||
$dynamicForm->add($embeddedForm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param string $name
|
||||
* @param string $group
|
||||
*/
|
||||
private function addModelDataListener(FormBuilderInterface $builder, $name, $group)
|
||||
{
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($builder, $name, $group) {
|
||||
try {
|
||||
$data = $this->propertyAccessor->getValue($event->getData(), $name);
|
||||
} catch (\RuntimeException $exception) {
|
||||
$data = null;
|
||||
}
|
||||
|
||||
if (null === $data || !is_object($data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$formName = $this->dynamicFormsChildrenMap->getFormNameByGroupAndDataClass($group, get_class($data));
|
||||
|
||||
$options = $event->getForm()->get($name)->get('_form')->getConfig()->getOptions();
|
||||
$event->getForm()->get($name)->add('_form', 'choice', array_merge($options, ['data' => $formName]));
|
||||
|
||||
$this->addEmbeddedFormField($builder->get($name), $event->getForm()->get($name), $formName);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param string $name
|
||||
*/
|
||||
private function addSubmittedDataListener(FormBuilderInterface $builder, $name)
|
||||
{
|
||||
$builder->get($name)->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($builder, $name) {
|
||||
$formName = $event->getData()['_form'];
|
||||
if (empty($formName)) {
|
||||
$event->setData([$name => null]);
|
||||
}
|
||||
|
||||
$this->addEmbeddedFormField($builder->get($name), $event->getForm(), $formName ?: 'text');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?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\MetadataBundle\DynamicForm;
|
||||
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface DynamicFormBuilderInterface
|
||||
{
|
||||
/**
|
||||
* Adds dynamic form field to given builder's form, sets up events
|
||||
* and transformers to handle it properly.
|
||||
*
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param array $options
|
||||
*/
|
||||
public function buildDynamicForm(FormBuilderInterface $builder, $name, $type, array $options = []);
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
<?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\MetadataBundle\DynamicForm;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
final class DynamicFormsChoicesMap implements DynamicFormsChoicesMapInterface
|
||||
{
|
||||
/**
|
||||
* Maps data class to form name.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private $forms;
|
||||
|
||||
/**
|
||||
* Maps form name to label.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private $labels;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addForm($group, $dataClass, $formName, $label)
|
||||
{
|
||||
$this->forms[$group][$dataClass] = $formName;
|
||||
$this->labels[$formName] = $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormsNamesByGroup($group)
|
||||
{
|
||||
return isset($this->forms[$group]) ? $this->forms[$group] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormNameByGroupAndDataClass($group, $dataClass)
|
||||
{
|
||||
foreach ($this->getFormsNamesByGroup($group) as $currentDataClass => $formName) {
|
||||
if ($currentDataClass === $dataClass) {
|
||||
return $formName;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDataClassByGroupAndFormName($group, $formName)
|
||||
{
|
||||
foreach ($this->getFormsNamesByGroup($group) as $dataClass => $currentFormName) {
|
||||
if ($currentFormName === $formName) {
|
||||
return $dataClass;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLabelByFormName($formName)
|
||||
{
|
||||
return isset($this->labels[$formName]) ? $this->labels[$formName] : $formName;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?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\MetadataBundle\DynamicForm;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface DynamicFormsChoicesMapInterface
|
||||
{
|
||||
/**
|
||||
* @param string $group
|
||||
* @param string $dataClass
|
||||
* @param string $formName
|
||||
* @param string $label
|
||||
*/
|
||||
public function addForm($group, $dataClass, $formName, $label);
|
||||
|
||||
/**
|
||||
* @param string $group
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getFormsNamesByGroup($group);
|
||||
|
||||
/**
|
||||
* @param string $group
|
||||
* @param string $dataClass
|
||||
*
|
||||
* @return string|null
|
||||
*
|
||||
*/
|
||||
public function getFormNameByGroupAndDataClass($group, $dataClass);
|
||||
|
||||
/**
|
||||
* @param string $group
|
||||
* @param string $formName
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDataClassByGroupAndFormName($group, $formName);
|
||||
|
||||
/**
|
||||
* @param string $formName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLabelByFormName($formName);
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
<?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\MetadataBundle\DynamicForm\Type;
|
||||
|
||||
use Sylius\Bundle\MetadataBundle\DynamicForm\DynamicFormsChoicesMapInterface;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class DynamicFormChoiceType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* @var DynamicFormsChoicesMapInterface
|
||||
*/
|
||||
protected $dynamicFormsChildrenMap;
|
||||
|
||||
/**
|
||||
* @param DynamicFormsChoicesMapInterface $dynamicFormsChildrenMap
|
||||
*/
|
||||
public function __construct(DynamicFormsChoicesMapInterface $dynamicFormsChildrenMap)
|
||||
{
|
||||
$this->dynamicFormsChildrenMap = $dynamicFormsChildrenMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
parent::buildForm($builder, $options);
|
||||
|
||||
$availableFormsNames = $this->dynamicFormsChildrenMap->getFormsNamesByGroup($options['group']);
|
||||
|
||||
$this->addAvailableFormsField($builder, $availableFormsNames, $options);
|
||||
$this->addAvailableFormsPrototypes($builder, $availableFormsNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||
{
|
||||
$this->exportAvailableFormsPrototypesToView($view, $form);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
parent::configureOptions($resolver);
|
||||
|
||||
$resolver
|
||||
->setDefaults([
|
||||
'inherit_data' => true,
|
||||
'select' => [],
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'sylius_dynamic_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param string[] $availableFormsNames
|
||||
*/
|
||||
private function addAvailableFormsField(FormBuilderInterface $builder, $availableFormsNames, array $options)
|
||||
{
|
||||
$choices = [];
|
||||
foreach ($availableFormsNames as $availableFormName) {
|
||||
$choices[$availableFormName] = $this->dynamicFormsChildrenMap->getLabelByFormName($availableFormName);
|
||||
}
|
||||
|
||||
$options = array_merge(
|
||||
['choices' => $choices, 'mapped' => false],
|
||||
$options['select']
|
||||
);
|
||||
|
||||
$builder->add('_form', 'choice', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param string[] $availableFormsNames
|
||||
*/
|
||||
private function addAvailableFormsPrototypes(FormBuilderInterface $builder, $availableFormsNames)
|
||||
{
|
||||
$prototypes = [];
|
||||
foreach ($availableFormsNames as $availableFormName) {
|
||||
$prototypes[$availableFormName] = $builder->create($builder->getName(), $availableFormName)->getForm();
|
||||
}
|
||||
|
||||
$builder->setAttribute('prototypes', $prototypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormView $view
|
||||
* @param FormInterface $form
|
||||
*/
|
||||
private function exportAvailableFormsPrototypesToView(FormView $view, FormInterface $form)
|
||||
{
|
||||
/** @var FormInterface[] $prototypes */
|
||||
$prototypes = $form->getConfig()->getAttribute('prototypes');
|
||||
|
||||
$view->vars['prototypes'] = [];
|
||||
foreach ($prototypes as $type => $prototype) {
|
||||
$view->vars['prototypes'][$type] = $prototype->createView($view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
<?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\MetadataBundle\Form\Type\Custom;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
|
||||
use Sylius\Bundle\MetadataBundle\DynamicForm\DynamicFormBuilderInterface;
|
||||
use Symfony\Component\Form\CallbackTransformer;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class PageMetadataType extends AbstractResourceType
|
||||
{
|
||||
/**
|
||||
* @var DynamicFormBuilderInterface
|
||||
*/
|
||||
private $dynamicFormBuilder;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @var DynamicFormBuilderInterface $dynamicFormBuilder
|
||||
*/
|
||||
public function __construct($dataClass, array $validationGroups = [], DynamicFormBuilderInterface $dynamicFormBuilder)
|
||||
{
|
||||
parent::__construct($dataClass, $validationGroups);
|
||||
|
||||
$this->dynamicFormBuilder = $dynamicFormBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('title', 'text', ['label' => 'sylius.metadata.page.title'])
|
||||
->add('description', 'textarea', ['label' => 'sylius.metadata.page.description'])
|
||||
->add('keywords', 'text', ['label' => 'sylius.metadata.page.keywords'])
|
||||
;
|
||||
|
||||
$this->dynamicFormBuilder->buildDynamicForm(
|
||||
$builder,
|
||||
'twitter',
|
||||
'sylius_twitter_card',
|
||||
[
|
||||
'select' => [
|
||||
'label' => 'sylius.metadata.page.twitter',
|
||||
'required' => false,
|
||||
'placeholder' => 'sylius.metadata.type.none',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addKeywordsTransformer($builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'sylius_page_metadata';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface $builder
|
||||
*/
|
||||
private function addKeywordsTransformer(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->get('keywords')->addModelTransformer(new CallbackTransformer(
|
||||
function ($originalKeywords) {
|
||||
if (!is_array($originalKeywords)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return join(', ', $originalKeywords);
|
||||
},
|
||||
function ($submittedKeywords) {
|
||||
$keywords = explode(',', $submittedKeywords);
|
||||
|
||||
array_walk($keywords, function ($keyword) {
|
||||
return trim($keyword);
|
||||
});
|
||||
|
||||
return $keywords;
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?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\MetadataBundle\Form\Type;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class MetadataContainerType extends AbstractResourceType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('id', 'text', ['read_only' => true])
|
||||
->add('metadata', 'sylius_page_metadata')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'sylius_metadata_container';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?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\MetadataBundle\Form\Type\Twitter;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class AppCardType extends AbstractResourceType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('description', 'textarea', ['label' => 'sylius.metadata.twitter.description'])
|
||||
->add('site', 'text', ['label' => 'sylius.metadata.twitter.site'])
|
||||
->add('siteId', 'text', ['label' => 'sylius.metadata.twitter.site_id'])
|
||||
->add('appNameIphone', 'text', ['label' => 'sylius.metadata.twitter.app_name_iphone'])
|
||||
->add('appIdIphone', 'text', ['label' => 'sylius.metadata.twitter.app_id_iphone'])
|
||||
->add('appUrlIphone', 'text', ['label' => 'sylius.metadata.twitter.app_url_iphone'])
|
||||
->add('appNameIpad', 'text', ['label' => 'sylius.metadata.twitter.app_name_ipad'])
|
||||
->add('appIdIpad', 'text', ['label' => 'sylius.metadata.twitter.app_id_ipad'])
|
||||
->add('appUrlIpad', 'text', ['label' => 'sylius.metadata.twitter.app_url_ipad'])
|
||||
->add('appNameGooglePlay', 'text', ['label' => 'sylius.metadata.twitter.app_name_googleplay'])
|
||||
->add('appIdGooglePlay', 'text', ['label' => 'sylius.metadata.twitter.app_id_googleplay'])
|
||||
->add('appUrlGooglePlay', 'text', ['label' => 'sylius.metadata.twitter.app_url_googleplay'])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'sylius_twitter_app_card';
|
||||
}
|
||||
}
|
||||
|
|
@ -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\MetadataBundle\Form\Type\Twitter;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class PlayerCardType extends AbstractResourceType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('title', 'text', ['label' => 'sylius.metadata.twitter.title'])
|
||||
->add('description', 'textarea', ['label' => 'sylius.metadata.twitter.description'])
|
||||
->add('image', 'text', ['label' => 'sylius.metadata.twitter.image'])
|
||||
->add('player', 'textarea', ['label' => 'sylius.metadata.twitter.player'])
|
||||
->add('site', 'text', ['label' => 'sylius.metadata.twitter.site'])
|
||||
->add('siteId', 'text', ['label' => 'sylius.metadata.twitter.site_id'])
|
||||
->add('playerWidth', 'number', ['label' => 'sylius.metadata.twitter.player_width'])
|
||||
->add('playerHeight', 'number', ['label' => 'sylius.metadata.twitter.player_height'])
|
||||
->add('playerStream', 'text', ['label' => 'sylius.metadata.twitter.player_stream'])
|
||||
->add('playerStreamContentType', 'text', ['label' => 'sylius.metadata.twitter.player_stream_content_type'])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'sylius_twitter_player_card';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?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\MetadataBundle\Form\Type\Twitter;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class SummaryCardType extends AbstractResourceType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('title', 'text', ['label' => 'sylius.metadata.twitter.title'])
|
||||
->add('description', 'textarea', ['label' => 'sylius.metadata.twitter.description'])
|
||||
->add('image', 'text', ['label' => 'sylius.metadata.twitter.image'])
|
||||
->add('site', 'text', ['label' => 'sylius.metadata.twitter.site'])
|
||||
->add('siteId', 'text', ['label' => 'sylius.metadata.twitter.site_id'])
|
||||
->add('creatorId', 'text', ['label' => 'sylius.metadata.twitter.creator_id'])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'sylius_twitter_summary_card';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?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\MetadataBundle\Form\Type\Twitter;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class SummaryLargeImageCardType extends AbstractResourceType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('title', 'text', ['label' => 'sylius.metadata.twitter.title'])
|
||||
->add('description', 'textarea', ['label' => 'sylius.metadata.twitter.description'])
|
||||
->add('image', 'text', ['label' => 'sylius.metadata.twitter.image'])
|
||||
->add('site', 'text', ['label' => 'sylius.metadata.twitter.site'])
|
||||
->add('siteId', 'text', ['label' => 'sylius.metadata.twitter.site_id'])
|
||||
->add('creator', 'text', ['label' => 'sylius.metadata.twitter.creator'])
|
||||
->add('creatorId', 'text', ['label' => 'sylius.metadata.twitter.creator_id'])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'sylius_twitter_summary_large_image_card';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?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\MetadataBundle\Form\Type\Twitter;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class TwitterCardType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver
|
||||
->setDefaults([
|
||||
'group' => null,
|
||||
])
|
||||
->setNormalizer(
|
||||
'group',
|
||||
function () {
|
||||
return 'twitter';
|
||||
}
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return 'sylius_dynamic_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'sylius_twitter_card';
|
||||
}
|
||||
}
|
||||
43
src/Sylius/Bundle/MetadataBundle/Model/MetadataContainer.php
Normal file
43
src/Sylius/Bundle/MetadataBundle/Model/MetadataContainer.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Sylius\Bundle\MetadataBundle\Model;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataInterface;
|
||||
use Sylius\Component\Metadata\Model\MetadataContainer as BaseMetadataContainer;
|
||||
use Sylius\Component\Metadata\Model\MetadataContainerInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class MetadataContainer extends BaseMetadataContainer implements MetadataContainerInterface
|
||||
{
|
||||
/**
|
||||
* @var MetadataInterface
|
||||
*/
|
||||
protected $metadataAsObject;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadata()
|
||||
{
|
||||
if (null !== $this->metadataAsObject) {
|
||||
return $this->metadataAsObject;
|
||||
}
|
||||
|
||||
return unserialize($this->metadata) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMetadata(MetadataInterface $metadata)
|
||||
{
|
||||
$this->metadataAsObject = $metadata;
|
||||
}
|
||||
|
||||
public function serializeMetadata()
|
||||
{
|
||||
$this->metadata = serialize($this->metadataAsObject);
|
||||
}
|
||||
}
|
||||
63
src/Sylius/Bundle/MetadataBundle/README.md
Normal file
63
src/Sylius/Bundle/MetadataBundle/README.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
SyliusMetadataBundle [](http://travis-ci.org/Sylius/SyliusMetadataBundle)
|
||||
==================
|
||||
|
||||
[**Symfony2**](http://symfony.com) integration of Sylius Metadata processing component.
|
||||
|
||||
Sylius
|
||||
------
|
||||
|
||||
**Sylius** - Modern ecommerce for Symfony2. Visit [Sylius.org](http://sylius.org).
|
||||
|
||||
[phpspec](http://phpspec.net) examples
|
||||
--------------------------------------
|
||||
|
||||
```bash
|
||||
$ composer install
|
||||
$ bin/phpspec run -f pretty
|
||||
```
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Documentation is available on [**docs.sylius.org**](http://sylius.org/en/latest/bundles/SyliusMetadataBundle/index.html).
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
All informations about contributing to Sylius can be found on [this page](http://docs.sylius.org/en/latest/contributing/index.html).
|
||||
|
||||
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/SyliusMetadataBundle/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/SyliusMetadataBundle/blob/master/Resources/meta/LICENSE).
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
The bundle was originally created by [Kamil Kokot](http://kamil.kokot.me).
|
||||
See the list of [contributors](https://github.com/Sylius/SyliusMetadataBundle/contributors).
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping">
|
||||
|
||||
<mapped-superclass name="Sylius\Bundle\MetadataBundle\Model\MetadataContainer" table="sylius_metadata">
|
||||
<id name="id" column="id" type="string" />
|
||||
|
||||
<field name="metadata" column="metadata" type="text" />
|
||||
|
||||
<lifecycle-callbacks>
|
||||
<lifecycle-callback type="prePersist" method="serializeMetadata" />
|
||||
<lifecycle-callback type="preUpdate" method="serializeMetadata" />
|
||||
</lifecycle-callbacks>
|
||||
</mapped-superclass>
|
||||
|
||||
</doctrine-mapping>
|
||||
94
src/Sylius/Bundle/MetadataBundle/Resources/config/forms.xml
Normal file
94
src/Sylius/Bundle/MetadataBundle/Resources/config/forms.xml
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
|
||||
<container xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||||
http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<parameters>
|
||||
<parameter key="sylius.metadata.dynamic_form_choice_builder.class">Sylius\Bundle\MetadataBundle\DynamicForm\DynamicFormBuilder</parameter>
|
||||
<parameter key="sylius.metadata.dynamic_forms_choices_map.class">Sylius\Bundle\MetadataBundle\DynamicForm\DynamicFormsChoicesMap</parameter>
|
||||
<parameter key="sylius.metadata.form.type.dynamic_form_choice.class">Sylius\Bundle\MetadataBundle\DynamicForm\Type\DynamicFormChoiceType</parameter>
|
||||
|
||||
<parameter key="sylius.form.type.page_metadata.class">Sylius\Bundle\MetadataBundle\Form\Type\Custom\PageMetadataType</parameter>
|
||||
<parameter key="sylius.form.type.twitter_card.class">Sylius\Bundle\MetadataBundle\Form\Type\Twitter\TwitterCardType</parameter>
|
||||
<parameter key="sylius.form.type.twitter_summary_card.class">Sylius\Bundle\MetadataBundle\Form\Type\Twitter\SummaryCardType</parameter>
|
||||
<parameter key="sylius.form.type.twitter_summary_large_image_card.class">Sylius\Bundle\MetadataBundle\Form\Type\Twitter\SummaryLargeImageCardType</parameter>
|
||||
<parameter key="sylius.form.type.twitter_player_card.class">Sylius\Bundle\MetadataBundle\Form\Type\Twitter\PlayerCardType</parameter>
|
||||
<parameter key="sylius.form.type.twitter_app_card.class">Sylius\Bundle\MetadataBundle\Form\Type\Twitter\AppCardType</parameter>
|
||||
|
||||
<parameter key="sylius.model.page_metadata.class">Sylius\Component\Metadata\Model\Custom\PageMetadata</parameter>
|
||||
<parameter key="sylius.model.twitter_summary_card.class">Sylius\Component\Metadata\Model\Twitter\SummaryCard</parameter>
|
||||
<parameter key="sylius.model.twitter_summary_large_image_card.class">Sylius\Component\Metadata\Model\Twitter\SummaryLargeImageCard</parameter>
|
||||
<parameter key="sylius.model.twitter_player_card.class">Sylius\Component\Metadata\Model\Twitter\PlayerCard</parameter>
|
||||
<parameter key="sylius.model.twitter_app_card.class">Sylius\Component\Metadata\Model\Twitter\AppCard</parameter>
|
||||
|
||||
<parameter key="sylius.validation_groups.page_metadata" type="collection"><parameter>Default</parameter></parameter>
|
||||
<parameter key="sylius.validation_groups.twitter_summary_card" type="collection"><parameter>Default</parameter></parameter>
|
||||
<parameter key="sylius.validation_groups.twitter_summary_large_image_card" type="collection"><parameter>Default</parameter></parameter>
|
||||
<parameter key="sylius.validation_groups.twitter_player_card" type="collection"><parameter>Default</parameter></parameter>
|
||||
<parameter key="sylius.validation_groups.twitter_app_card" type="collection"><parameter>Default</parameter></parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
<service id="sylius.metadata.dynamic_form_choice_builder" class="%sylius.metadata.dynamic_form_choice_builder.class%" public="false">
|
||||
<argument type="service" id="sylius.metadata.dynamic_forms_choices_map" />
|
||||
<argument type="service" id="property_accessor" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.dynamic_forms_choices_map" class="%sylius.metadata.dynamic_forms_choices_map.class%" public="false">
|
||||
<argument type="collection" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.form.type.dynamic_form_choice" class="%sylius.metadata.form.type.dynamic_form_choice.class%">
|
||||
<argument type="service" id="sylius.metadata.dynamic_forms_choices_map" />
|
||||
<tag name="form.type" alias="sylius_dynamic_form" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.form.type.page_metadata" class="%sylius.form.type.page_metadata.class%">
|
||||
<argument>%sylius.model.page_metadata.class%</argument>
|
||||
<argument>%sylius.validation_groups.page_metadata%</argument>
|
||||
<tag name="form.type" alias="sylius_page_metadata" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.form.type.twitter_card" class="%sylius.form.type.twitter_card.class%">
|
||||
<tag name="form.type" alias="sylius_twitter_card" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.form.type.twitter_summary_card" class="%sylius.form.type.twitter_summary_card.class%">
|
||||
<argument>%sylius.model.twitter_summary_card.class%</argument>
|
||||
<argument>%sylius.validation_groups.twitter_summary_card%</argument>
|
||||
<tag name="form.type" alias="sylius_twitter_summary_card" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.form.type.twitter_summary_large_image_card" class="%sylius.form.type.twitter_summary_large_image_card.class%">
|
||||
<argument>%sylius.model.twitter_summary_large_image_card.class%</argument>
|
||||
<argument>%sylius.validation_groups.twitter_summary_large_image_card%</argument>
|
||||
<tag name="form.type" alias="sylius_twitter_summary_large_image_card" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.form.type.twitter_player_card" class="%sylius.form.type.twitter_player_card.class%">
|
||||
<argument>%sylius.model.twitter_player_card.class%</argument>
|
||||
<argument>%sylius.validation_groups.twitter_player_card%</argument>
|
||||
<tag name="form.type" alias="sylius_twitter_player_card" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.form.type.twitter_app_card" class="%sylius.form.type.twitter_app_card.class%">
|
||||
<argument>%sylius.model.twitter_app_card.class%</argument>
|
||||
<argument>%sylius.validation_groups.twitter_app_card%</argument>
|
||||
<tag name="form.type" alias="sylius_twitter_app_card" />
|
||||
</service>
|
||||
</services>
|
||||
|
||||
</container>
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
<?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.
|
||||
|
||||
-->
|
||||
|
||||
<container xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||||
http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<parameters>
|
||||
<parameter key="sylius.metadata.compiler.class">Sylius\Component\Metadata\Compiler\MetadataCompiler</parameter>
|
||||
<parameter key="sylius.metadata.processor.class">Sylius\Component\Metadata\Processor\TwigMetadataProcessor</parameter>
|
||||
<parameter key="sylius.metadata.accessor.class">Sylius\Component\Metadata\Accessor\MetadataAccessor</parameter>
|
||||
<parameter key="sylius.metadata.twig_extension.class">Sylius\Component\Metadata\Twig\MetadataExtension</parameter>
|
||||
|
||||
<parameter key="sylius.metadata.renderer.options_resolver.class">Symfony\Component\OptionsResolver\OptionsResolver</parameter>
|
||||
<parameter key="sylius.metadata.renderer.class">Sylius\Component\Metadata\Renderer\CompositeMetadataRenderer</parameter>
|
||||
<parameter key="sylius.metadata.renderer.custom_page.class">Sylius\Component\Metadata\Renderer\Custom\PageMetadataRenderer</parameter>
|
||||
<parameter key="sylius.metadata.renderer.twitter.class">Sylius\Component\Metadata\Renderer\Twitter\GenericTwitterMetadataRenderer</parameter>
|
||||
|
||||
<parameter key="sylius.metadata.provider.class">Sylius\Component\Metadata\Provider\MetadataProvider</parameter>
|
||||
<parameter key="sylius.metadata.provider.processed.class">Sylius\Component\Metadata\Provider\ProcessedMetadataProvider</parameter>
|
||||
|
||||
<parameter key="sylius.metadata.hierarchy_provider.class">Sylius\Component\Metadata\HierarchyProvider\CompositeMetadataHierarchyProvider</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
<service id="sylius.metadata.compiler" class="%sylius.metadata.compiler.class%" public="false" />
|
||||
|
||||
<service id="sylius.metadata.processor" class="%sylius.metadata.processor.class%" public="false">
|
||||
<argument type="service" id="twig" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.accessor" class="%sylius.metadata.accessor.class%">
|
||||
<argument type="service" id="sylius.metadata.provider" />
|
||||
<argument type="service" id="property_accessor" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.twig_extension" class="%sylius.metadata.twig_extension.class%" public="false">
|
||||
<argument type="service" id="sylius.metadata.accessor" />
|
||||
<argument type="service" id="sylius.metadata.renderer" />
|
||||
<tag name="twig.extension" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.renderer.options_resolver" class="%sylius.metadata.renderer.options_resolver.class%" scope="prototype" public="false" />
|
||||
|
||||
<service id="sylius.metadata.renderer" class="%sylius.metadata.renderer.class%">
|
||||
<argument type="collection" /> <!-- Metadata renderers array -->
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.renderer.custom_page" class="%sylius.metadata.renderer.custom_page.class%" public="false">
|
||||
<argument type="service" id="sylius.metadata.renderer.twitter" />
|
||||
<argument type="service" id="sylius.metadata.renderer.options_resolver" strict="false" />
|
||||
<argument type="service" id="property_accessor" />
|
||||
<tag name="sylius.metadata_renderer" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.renderer.twitter" class="%sylius.metadata.renderer.twitter.class%" public="false">
|
||||
<argument type="service" id="sylius.metadata.renderer.options_resolver" strict="false" />
|
||||
<tag name="sylius.metadata_renderer" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.provider" class="%sylius.metadata.provider.class%" public="false">
|
||||
<argument type="service" id="sylius.repository.metadata_container" />
|
||||
<argument type="service" id="sylius.metadata.compiler" />
|
||||
<argument type="service" id="sylius.metadata.hierarchy_provider" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.provider.processed" class="%sylius.metadata.provider.processed.class%" decorates="sylius.metadata.provider" public="false">
|
||||
<argument type="service" id="sylius.metadata.provider.processed.inner" />
|
||||
<argument type="service" id="sylius.metadata.processor" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.metadata.hierarchy_provider" class="%sylius.metadata.hierarchy_provider.class%">
|
||||
<argument type="collection" /> <!-- Metadata hierarchy provider array -->
|
||||
</service>
|
||||
</services>
|
||||
|
||||
</container>
|
||||
19
src/Sylius/Bundle/MetadataBundle/Resources/meta/LICENSE
Normal file
19
src/Sylius/Bundle/MetadataBundle/Resources/meta/LICENSE
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2011-2016 Paweł Jędrzejewski
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
(function ($) {
|
||||
'use strict';
|
||||
|
||||
var methods = {
|
||||
init: function(options) {
|
||||
var settings = $.extend({
|
||||
'prototypePrefix': false,
|
||||
'prototypeElementPrefix': '<hr />',
|
||||
'containerSelector': false
|
||||
}, options);
|
||||
|
||||
return this.each(function() {
|
||||
show($(this), false);
|
||||
$(this).change(function() {
|
||||
show($(this), true);
|
||||
});
|
||||
|
||||
function show(element, replace) {
|
||||
var id = element.attr('id');
|
||||
var selectedValue = element.val();
|
||||
var prototypePrefix = id;
|
||||
if (false != settings.prototypePrefix) {
|
||||
prototypePrefix = settings.prototypePrefix;
|
||||
}
|
||||
|
||||
var prototypeElement = $('#' + prototypePrefix + '_' + selectedValue);
|
||||
var container;
|
||||
|
||||
if (settings.containerSelector) {
|
||||
container = $(settings.containerSelector);
|
||||
} else {
|
||||
container = $(element.data('container'));
|
||||
}
|
||||
|
||||
if (!container.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prototypeElement.length) {
|
||||
container.empty();
|
||||
return;
|
||||
}
|
||||
|
||||
if (replace || !container.html().trim()) {
|
||||
container.html(settings.prototypeElementPrefix + prototypeElement.data('prototype'));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.handlePrototypes = function(method) {
|
||||
if (methods[method]) {
|
||||
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
} else if (typeof method === 'object' || !method) {
|
||||
return methods.init.apply(this, arguments);
|
||||
} else {
|
||||
$.error( 'Method ' + method + ' does not exist on jQuery.handlePrototypes' );
|
||||
}
|
||||
};
|
||||
|
||||
$('select[data-dynamic-form]').handlePrototypes();
|
||||
})(jQuery);
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
sylius:
|
||||
metadata:
|
||||
type:
|
||||
none: " - NONE - "
|
||||
twitter_summary_card: Summary
|
||||
twitter_summary_large_image_card: Summary with large image
|
||||
twitter_player_card: Player
|
||||
twitter_app_card: Application
|
||||
page:
|
||||
title: Title
|
||||
description: Description
|
||||
keywords: Keywords
|
||||
twitter: Twitter Card
|
||||
twitter:
|
||||
title: Title
|
||||
description: Description
|
||||
site: Site
|
||||
site_id: Site ID
|
||||
creator: Creator
|
||||
creator_id: Creator ID
|
||||
image: Image
|
||||
player: Player
|
||||
player_width: Player width
|
||||
player_height: Player height
|
||||
player_stream: Player stream
|
||||
player_stream_content_type: Player stream content type
|
||||
app_name_iphone: Iphone application name
|
||||
app_id_iphone: Iphone application ID
|
||||
app_url_iphone: Iphone application url
|
||||
app_name_ipad: Ipad application name
|
||||
app_id_ipad: Ipad application ID
|
||||
app_url_ipad: Ipad application url
|
||||
app_name_googleplay: Google Play application name
|
||||
app_id_googleplay: Google Play application ID
|
||||
app_url_googleplay: Google Play application url
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{% block sylius_dynamic_form_row %}
|
||||
{{ form_row(form._form, { 'attr': { 'data-dynamic-form': true, 'data-container': "#dynamic-form-" ~ name } }) }}
|
||||
|
||||
{% for prototypeName, prototype in form.vars.prototypes %}
|
||||
<div id="{{ form._form.vars.id }}_{{ prototypeName }}" data-prototype="{{ form_widget(prototype)|e }}">
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div id="dynamic-form-{{ name }}">
|
||||
{# Render nested form (if possible) #}
|
||||
{% if attribute(form.children, name) is defined %}
|
||||
{{ form_widget(attribute(form.children, name)) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
66
src/Sylius/Bundle/MetadataBundle/SyliusMetadataBundle.php
Normal file
66
src/Sylius/Bundle/MetadataBundle/SyliusMetadataBundle.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?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\MetadataBundle;
|
||||
|
||||
use Sylius\Bundle\ResourceBundle\AbstractResourceBundle;
|
||||
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
|
||||
use Sylius\Bundle\MetadataBundle\DependencyInjection\Compiler\DynamicFormsChoicesMapCompilerPass;
|
||||
use Sylius\Bundle\MetadataBundle\DependencyInjection\Compiler\MetadataHierarchyProviderCompilerPass;
|
||||
use Sylius\Bundle\MetadataBundle\DependencyInjection\Compiler\MetadataRendererCompilerPass;
|
||||
use Sylius\Component\Metadata\Model\MetadataContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class SyliusMetadataBundle extends AbstractResourceBundle
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function build(ContainerBuilder $container)
|
||||
{
|
||||
parent::build($container);
|
||||
|
||||
$container->addCompilerPass(new MetadataRendererCompilerPass());
|
||||
$container->addCompilerPass(new MetadataHierarchyProviderCompilerPass());
|
||||
$container->addCompilerPass(new DynamicFormsChoicesMapCompilerPass());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSupportedDrivers()
|
||||
{
|
||||
return [
|
||||
SyliusResourceBundle::DRIVER_DOCTRINE_ORM,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getModelInterfaces()
|
||||
{
|
||||
return [
|
||||
MetadataContainerInterface::class => 'sylius.model.metadata_container.class',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getModelNamespace()
|
||||
{
|
||||
return 'Sylius\Bundle\MetadataBundle\Model';
|
||||
}
|
||||
}
|
||||
41
src/Sylius/Bundle/MetadataBundle/composer.json
Normal file
41
src/Sylius/Bundle/MetadataBundle/composer.json
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "sylius/metadata-bundle",
|
||||
"type": "symfony-bundle",
|
||||
"description": "Metadata management for Symfony2 projects.",
|
||||
"keywords": ["metadata"],
|
||||
"homepage": "http://sylius.org",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kamil Kokot",
|
||||
"homepage": "http://kamil.kokot.me"
|
||||
},
|
||||
{
|
||||
"name": "Sylius project",
|
||||
"homepage": "http://sylius.org"
|
||||
},
|
||||
{
|
||||
"name": "Community contributions",
|
||||
"homepage": "http://github.com/Sylius/Sylius/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.5.9|^7.0",
|
||||
|
||||
"sylius/metadata": "0.17.*@dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^2.4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Sylius\\Bundle\\MetadataBundle\\": "" }
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": { "Sylius\\Bundle\\MetadataBundle\\spec\\": "spec/" }
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.17-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
src/Sylius/Bundle/MetadataBundle/phpspec.yml.dist
Normal file
5
src/Sylius/Bundle/MetadataBundle/phpspec.yml.dist
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
suites:
|
||||
main:
|
||||
namespace: Sylius\Bundle\MetadataBundle
|
||||
psr4_prefix: Sylius\Bundle\MetadataBundle
|
||||
src_path: .
|
||||
|
|
@ -46,10 +46,11 @@ abstract class DefaultContext extends RawMinkContext implements Context, KernelA
|
|||
* @var array
|
||||
*/
|
||||
protected $actions = array(
|
||||
'viewing' => 'show',
|
||||
'creation' => 'create',
|
||||
'editing' => 'update',
|
||||
'building' => 'build',
|
||||
'viewing' => 'show',
|
||||
'creation' => 'create',
|
||||
'editing' => 'update',
|
||||
'building' => 'build',
|
||||
'customization' => 'customize',
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -399,6 +399,13 @@ class BackendMenuBuilder extends MenuBuilder
|
|||
))->setLabel($this->translate(sprintf('sylius.backend.menu.%s.channels', $section)));
|
||||
}
|
||||
|
||||
if ($this->rbacAuthorizationChecker->isGranted('sylius.metadata_container.index')) {
|
||||
$child->addChild('metadata', array(
|
||||
'route' => 'sylius_backend_metadata_container_index',
|
||||
'labelAttributes' => array('icon' => 'glyphicon glyphicon-file'),
|
||||
))->setLabel($this->translate(sprintf('sylius.backend.menu.%s.metadata', $section)));
|
||||
}
|
||||
|
||||
if ($this->rbacAuthorizationChecker->isGranted('sylius.locale.index')) {
|
||||
$child->addChild('locales', array(
|
||||
'route' => 'sylius_backend_locale_index',
|
||||
|
|
|
|||
|
|
@ -174,3 +174,7 @@ sylius_backend_content:
|
|||
sylius_backend_report:
|
||||
resource: @SyliusWebBundle/Resources/config/routing/backend/report.yml
|
||||
prefix: /reports
|
||||
|
||||
sylius_backend_metadata_container:
|
||||
resource: @SyliusWebBundle/Resources/config/routing/backend/metadata_container.yml
|
||||
prefix: /metadatas
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
# This file is part of the Sylius package.
|
||||
# (c) Paweł Jędrzejewski
|
||||
|
||||
sylius_backend_metadata_container_index:
|
||||
path: /
|
||||
methods: [GET]
|
||||
defaults:
|
||||
_controller: sylius.controller.metadata_container:indexAction
|
||||
_sylius:
|
||||
template: SyliusWebBundle:Backend/Metadata:index.html.twig
|
||||
sortable: true
|
||||
paginate: 50
|
||||
sorting:
|
||||
id: asc
|
||||
|
||||
sylius_backend_metadata_container_customize:
|
||||
path: /customize/{id}
|
||||
methods: [GET, POST, PUT]
|
||||
defaults:
|
||||
_controller: sylius.controller.metadata_container:customizeAction
|
||||
_sylius:
|
||||
factory:
|
||||
method: createIdentifiedBy
|
||||
arguments: [$id]
|
||||
template: SyliusWebBundle:Backend/Metadata:customize.html.twig
|
||||
redirect: sylius_backend_metadata_container_show
|
||||
|
||||
sylius_backend_metadata_container_delete:
|
||||
path: /{id}
|
||||
methods: [DELETE]
|
||||
defaults:
|
||||
_controller: sylius.controller.metadata_container:deleteAction
|
||||
_sylius:
|
||||
template: SyliusWebBundle:Backend/Misc:delete.html.twig
|
||||
redirect: sylius_backend_metadata_container_index
|
||||
|
||||
sylius_backend_metadata_container_show:
|
||||
path: /{id}
|
||||
methods: [GET]
|
||||
defaults:
|
||||
_controller: sylius.controller.metadata_container:showAction
|
||||
_sylius:
|
||||
template: SyliusWebBundle:Backend/Metadata:show.html.twig
|
||||
|
|
@ -207,6 +207,8 @@ sylius:
|
|||
index: Menus
|
||||
menu_node:
|
||||
index: Menu nodes
|
||||
metadata:
|
||||
index: Metadata
|
||||
new: New
|
||||
option:
|
||||
index: Options
|
||||
|
|
@ -556,6 +558,21 @@ sylius:
|
|||
frontend_description: Sylius is modern ecommerce solution for PHP, based on the Symfony2 framework
|
||||
frontend_keywords: Sylius, ecommerce, symfony2, shop, cart, webshop
|
||||
frontend_title: Sylius, modern ecommerce for Symfony2
|
||||
metadata:
|
||||
customize_header: Customizing metadata
|
||||
show_header: Show metadata
|
||||
id: ID
|
||||
customize: Customize metadata
|
||||
manage: Manage metadata
|
||||
content: Content
|
||||
index_metadata: Metadata
|
||||
default_page:
|
||||
group_customize: Customize default metadata
|
||||
product:
|
||||
single_customize: Customize metadata
|
||||
group_customize: Customize products metadata
|
||||
product_variant:
|
||||
single_customize: Customize metadata
|
||||
move_down: Move down
|
||||
move_up: Move up
|
||||
na: N/A
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
{% form_theme form 'SyliusWebBundle:Backend:forms.html.twig' %}
|
||||
|
||||
{{ form_errors(form) }}
|
||||
|
||||
<fieldset id="metadata-form">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{{ form_row(form.id) }}
|
||||
<hr/>
|
||||
{{ form_row(form.metadata.title) }}
|
||||
{{ form_row(form.metadata.description) }}
|
||||
{{ form_row(form.metadata.keywords) }}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{{ form_row(form.metadata.twitter) }}
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<hr>
|
||||
{{ form_widget(form._token) }}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
{% extends 'SyliusWebBundle:Backend:layout.html.twig' %}
|
||||
|
||||
{% from 'SyliusResourceBundle:Macros:actions.html.twig' import update %}
|
||||
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
<script type="text/javascript" src="{{ asset('bundles/syliusmetadata/js/dynamic-form.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block topbar %}
|
||||
<ol class="breadcrumb">
|
||||
<li>{{ 'sylius.breadcrumb.configuration'|trans }}</li>
|
||||
<li><a href="{{ path('sylius_backend_metadata_container_index') }}">{{ 'sylius.breadcrumb.metadata.index'|trans }}</a></li>
|
||||
<li><a href="{{ path('sylius_backend_metadata_container_show', {'id': metadata_container.id}) }}">{{ metadata_container.id }}</a></li>
|
||||
<li>{{ 'sylius.breadcrumb.edit'|trans }}</li>
|
||||
</ol>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<h1><i class="glyphicon glyphicon-pencil"></i> {{ 'sylius.metadata.customize_header'|trans|raw }} {{ metadata_container.id }}</h1>
|
||||
</div>
|
||||
|
||||
{{ form_errors(form) }}
|
||||
|
||||
<form action="{{ path('sylius_backend_metadata_container_customize', {'id': metadata_container.id }) }}" method="post" class="form-horizontal" novalidate>
|
||||
{% include 'SyliusWebBundle:Backend/Metadata:_form.html.twig' %}
|
||||
{{ update() }}
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
{% extends 'SyliusWebBundle:Backend:layout.html.twig' %}
|
||||
|
||||
{% import 'SyliusResourceBundle:Macros:buttons.html.twig' as buttons %}
|
||||
{% from 'SyliusWebBundle:Backend/Macros:misc.html.twig' import pagination %}
|
||||
{% from 'SyliusWebBundle:Backend/Metadata:macros.html.twig' import list %}
|
||||
|
||||
{% block topbar %}
|
||||
<ol class="breadcrumb">
|
||||
<li>{{ 'sylius.breadcrumb.configuration'|trans }}</li>
|
||||
<li>{{ 'sylius.breadcrumb.metadata.index'|trans }}</li>
|
||||
</ol>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<div class="actions-menu">
|
||||
<a href="{{ path('sylius_backend_metadata_container_customize', { 'id': 'DefaultPage' }) }}" class="btn btn-default">
|
||||
<i class="glyphicon glyphicon-file"></i><span>{{ 'sylius.metadata.default_page.group_customize'|trans }}</span>
|
||||
</a>
|
||||
</div>
|
||||
<h1><i class="glyphicon glyphicon-flag"></i> {{ 'sylius.metadata.index_header'|trans|raw }}</h1>
|
||||
</div>
|
||||
|
||||
{{ pagination(metadata_containers) }}
|
||||
{{ list(metadata_containers) }}
|
||||
{{ pagination(metadata_containers) }}
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
{% macro list(metadatas) %}
|
||||
|
||||
{% import 'SyliusResourceBundle:Macros:buttons.html.twig' as buttons %}
|
||||
{% import 'SyliusWebBundle:Backend/Macros:alerts.html.twig' as alerts %}
|
||||
|
||||
{% if metadatas|length > 0 %}
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ sylius_resource_sort('id', 'sylius.metadata.id'|trans) }}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for metadata in metadatas %}
|
||||
<tr>
|
||||
<td><a href="{{ path('sylius_backend_metadata_container_show', { 'id': metadata_container.id }) }}">{{ metadata_container.id }}</a></td>
|
||||
<td>
|
||||
<div class="pull-right">
|
||||
{{ buttons.edit(path('sylius_backend_metadata_container_customize', { 'id': metadata_container.id })) }}
|
||||
{{ buttons.delete(path('sylius_backend_metadata_container_delete', { 'id': metadata_container.id })) }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
{{ alerts.info('sylius.metadata.no_results'|trans) }}
|
||||
{% endif %}
|
||||
|
||||
{% endmacro %}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
{% extends 'SyliusWebBundle:Backend:layout.html.twig' %}
|
||||
|
||||
{% import 'SyliusResourceBundle:Macros:buttons.html.twig' as buttons %}
|
||||
|
||||
{% macro dataAsList(data) %}
|
||||
{% if data is iterable and data|length > 0 %}
|
||||
<ul>
|
||||
{% for key, element in data %}
|
||||
<li>
|
||||
{% if key is not sameas(loop.index0) %}<b>{{ key|humanize }}:</b> {% endif %}{{ _self.dataAsList(element) }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elseif data is not empty %}
|
||||
{{ data }}
|
||||
{% else %}
|
||||
<small><i>empty</i></small>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block topbar %}
|
||||
<ol class="breadcrumb">
|
||||
<li>{{ 'sylius.breadcrumb.configuration'|trans }}</li>
|
||||
<li><a href="{{ path('sylius_backend_metadata_container_index') }}">{{ 'sylius.breadcrumb.metadata.index'|trans }}</a></li>
|
||||
<li>{{ metadata_container.id }}</li>
|
||||
</ol>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<div class="actions-menu">
|
||||
{{ buttons.manage(path('sylius_backend_metadata_container_index'), 'sylius.metadata.manage'|trans) }}
|
||||
{{ buttons.edit(path('sylius_backend_metadata_container_customize', { 'id': metadata_container.id })) }}
|
||||
{{ buttons.delete(path('sylius_backend_metadata_container_delete', { 'id': metadata_container.id }), null, false, false) }}
|
||||
</div>
|
||||
<h1><i class="glyphicon glyphicon-flag"></i> {{ 'sylius.metadata.show_header'|trans|raw }}</h1>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'sylius.metadata.id'|trans }}</th>
|
||||
<th>{{ 'sylius.metadata.content'|trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ metadata_container.id }}</td>
|
||||
<td>{{ _self.dataAsList(metadata_container.metadata.toArray()) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
|
@ -15,6 +15,9 @@
|
|||
<div class="page-header">
|
||||
<div class="actions-menu">
|
||||
{{ buttons.create(path('sylius_backend_product_create'), 'sylius.product.create'|trans) }}
|
||||
<a href="{{ path('sylius_backend_metadata_container_customize', { 'id': constant('Sylius\\Component\\Core\\Model\\ProductInterface::METADATA_CLASS_IDENTIFIER') }) }}" class="btn btn-default">
|
||||
<i class="glyphicon glyphicon-file"></i><span>{{ 'sylius.metadata.product.group_customize'|trans }}</span>
|
||||
</a>
|
||||
{{ buttons.manage(path('sylius_backend_product_option_index'), 'sylius.product_option.manage'|trans) }}
|
||||
{{ buttons.manage(path('sylius_backend_product_attribute_index'), 'sylius.product_attribute.manage'|trans) }}
|
||||
{% if app.request.query.get('deleted') %}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,9 @@
|
|||
{{ product.updatedAt|date('Y/m/d') }}
|
||||
</td>
|
||||
<td class="center-text">
|
||||
<a href="{{ path('sylius_backend_metadata_container_customize', { 'id': product.metadataIdentifier }) }}" class="btn btn-default">
|
||||
<i class="glyphicon glyphicon-file"></i><span>{{ 'sylius.metadata.product.single_customize'|trans }}</span>
|
||||
</a>
|
||||
{% if product.deleted %}
|
||||
{{ buttons.patch(path('sylius_backend_product_delete_restore', {'id': product.id}), 'sylius.restore'|trans, null, 'btn btn-primary') }}
|
||||
{% else %}
|
||||
|
|
|
|||
|
|
@ -23,12 +23,15 @@
|
|||
{{ buttons.enable(path('sylius_backend_product_enable', {'id': product.id})) }}
|
||||
{% endif %}
|
||||
{% if not product.deleted %}
|
||||
{{ buttons.edit(path('sylius_backend_product_update', {'id': product.id})) }}
|
||||
{{ buttons.delete(path('sylius_backend_product_delete', {'id': product.id}), null, false, true) }}
|
||||
<a href="{{ path(product) }}" class="btn btn-info">
|
||||
<i class="glyphicon glyphicon-shopping-cart"></i>
|
||||
{{ 'sylius.product.show_in_store'|trans }}
|
||||
</a>
|
||||
<a href="{{ path('sylius_backend_metadata_container_customize', { 'id': product.metadataIdentifier }) }}" class="btn btn-default">
|
||||
<i class="glyphicon glyphicon-file"></i><span>{{ 'sylius.metadata.product.single_customize'|trans }}</span>
|
||||
</a>
|
||||
{{ buttons.edit(path('sylius_backend_product_update', {'id': product.id})) }}
|
||||
{{ buttons.delete(path('sylius_backend_product_delete', {'id': product.id}), null, false, true) }}
|
||||
<a href="{{ path(product) }}" class="btn btn-info">
|
||||
<i class="glyphicon glyphicon-shopping-cart"></i>
|
||||
{{ 'sylius.product.show_in_store'|trans }}
|
||||
</a>
|
||||
{% else %}
|
||||
{{ buttons.patch(path('sylius_backend_product_delete_restore', {'id': product.id}), 'sylius.restore'|trans, null, 'btn btn-primary') }}
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -50,8 +50,11 @@
|
|||
<td>
|
||||
<div class="pull-right">
|
||||
{% if not variant.deleted %}
|
||||
{{ buttons.edit(path('sylius_backend_product_variant_update', {'productId': product.id, 'id': variant.id})) }}
|
||||
{{ buttons.delete(path('sylius_backend_product_variant_delete', {'productId': product.id, 'id': variant.id})) }}
|
||||
<a href="{{ path('sylius_backend_metadata_container_customize', { 'id': variant.metadataIdentifier }) }}" class="btn btn-default">
|
||||
<i class="glyphicon glyphicon-file"></i><span>{{ 'sylius.metadata.product_variant.single_customize'|trans }}</span>
|
||||
</a>
|
||||
{{ buttons.edit(path('sylius_backend_product_variant_update', {'productId': product.id, 'id': variant.id})) }}
|
||||
{{ buttons.delete(path('sylius_backend_product_variant_delete', {'productId': product.id, 'id': variant.id})) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,14 @@
|
|||
{% set form = sylius_cart_form({'product': product}) %}
|
||||
{% from 'SyliusWebBundle:Frontend/Product:macros.html.twig' import sylius_display_price %}
|
||||
|
||||
{% block head %}
|
||||
{{ sylius_metadata_render(product, null, { 'defaults': {
|
||||
'title': settings.title|default('sylius.meta.frontend_title'|trans),
|
||||
'description': settings.meta_description|default('sylius.meta.frontend_description'|trans),
|
||||
'keywords': settings.meta_description|default('sylius.meta.frontend_keywords'|trans)
|
||||
} })|raw }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
|
|
|
|||
|
|
@ -2,14 +2,16 @@
|
|||
{% set settings = sylius_settings_all('sylius_general') %}
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
{% block title %}
|
||||
{{ settings.title|default('sylius.meta.frontend_title'|trans) }}
|
||||
{% endblock %}
|
||||
</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="description" content="{{ settings.meta_description|default('sylius.meta.frontend_description'|trans) }}">
|
||||
<meta name="keywords" content="{{ settings.meta_keywords|default('sylius.meta.frontend_keywords'|trans) }}">
|
||||
{% block head %}
|
||||
<title>
|
||||
{% block title %}
|
||||
{{ settings.title|default('sylius.meta.frontend_title'|trans) }}
|
||||
{% endblock %}
|
||||
</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="description" content="{{ settings.meta_description|default('sylius.meta.frontend_description'|trans) }}">
|
||||
<meta name="keywords" content="{{ settings.meta_keywords|default('sylius.meta.frontend_keywords'|trans) }}">
|
||||
{% endblock %}
|
||||
|
||||
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700|Open+Sans:300italic,400,300,700&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
<?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\Component\Core\Metadata\HierarchyProvider;
|
||||
|
||||
use Sylius\Component\Core\Model\ArchetypeInterface;
|
||||
use Sylius\Component\Core\Model\ProductInterface;
|
||||
use Sylius\Component\Metadata\HierarchyProvider\MetadataHierarchyProviderInterface;
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class ProductHierarchyProvider implements MetadataHierarchyProviderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param ProductInterface|MetadataSubjectInterface $product
|
||||
*/
|
||||
public function getHierarchyByMetadataSubject(MetadataSubjectInterface $product)
|
||||
{
|
||||
$hierarchy = [
|
||||
$product->getMetadataIdentifier(),
|
||||
];
|
||||
|
||||
/** @var ArchetypeInterface $productArchetype */
|
||||
$productArchetype = $product->getArchetype();
|
||||
if (null !== $productArchetype) {
|
||||
$hierarchy[] = $productArchetype->getMetadataIdentifier();
|
||||
}
|
||||
|
||||
$hierarchy[] = $product->getMetadataClassIdentifier();
|
||||
$hierarchy[] = 'DefaultPage';
|
||||
|
||||
return $hierarchy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports(MetadataSubjectInterface $metadataSubject)
|
||||
{
|
||||
return $metadataSubject instanceof ProductInterface;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?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\Component\Core\Metadata\HierarchyProvider;
|
||||
|
||||
use Sylius\Component\Core\Model\ArchetypeInterface;
|
||||
use Sylius\Component\Core\Model\ProductInterface;
|
||||
use Sylius\Component\Core\Model\ProductVariantInterface;
|
||||
use Sylius\Component\Metadata\HierarchyProvider\MetadataHierarchyProviderInterface;
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class ProductVariantHierarchyProvider implements MetadataHierarchyProviderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHierarchyByMetadataSubject(MetadataSubjectInterface $metadataSubject)
|
||||
{
|
||||
/** @var ProductVariantInterface $productVariant */
|
||||
$productVariant = $metadataSubject;
|
||||
|
||||
/** @var ProductInterface $product */
|
||||
$product = $productVariant->getProduct();
|
||||
|
||||
$hierarchy = [
|
||||
$productVariant->getMetadataIdentifier(),
|
||||
$product->getMetadataIdentifier(),
|
||||
];
|
||||
|
||||
/** @var ArchetypeInterface $productArchetype */
|
||||
$productArchetype = $product->getArchetype();
|
||||
if (null !== $productArchetype) {
|
||||
$hierarchy[] = $productArchetype->getMetadataIdentifier();
|
||||
}
|
||||
|
||||
$hierarchy[] = $product->getMetadataClassIdentifier();
|
||||
|
||||
$hierarchy[] = 'DefaultPage';
|
||||
|
||||
return $hierarchy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports(MetadataSubjectInterface $metadataSubject)
|
||||
{
|
||||
return $metadataSubject instanceof ProductVariantInterface;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Sylius\Component\Core\Metadata\Provider;
|
||||
|
||||
use Sylius\Component\Metadata\HierarchyProvider\MetadataHierarchyProviderInterface;
|
||||
use Sylius\Component\Metadata\Model\Custom\PageMetadata;
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
use Sylius\Component\Metadata\Provider\MetadataProviderInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class MetadataProvider implements MetadataProviderInterface
|
||||
{
|
||||
/**
|
||||
* @var MetadataProviderInterface
|
||||
*/
|
||||
private $metadataProvider;
|
||||
|
||||
/**
|
||||
* @var MetadataHierarchyProviderInterface
|
||||
*/
|
||||
private $metadataHierarchyProvider;
|
||||
|
||||
/**
|
||||
* @param MetadataProviderInterface $metadataProvider
|
||||
* @param MetadataHierarchyProviderInterface $metadataHierarchyProvider
|
||||
*/
|
||||
public function __construct(MetadataProviderInterface $metadataProvider, MetadataHierarchyProviderInterface $metadataHierarchyProvider)
|
||||
{
|
||||
$this->metadataProvider = $metadataProvider;
|
||||
$this->metadataHierarchyProvider = $metadataHierarchyProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function findMetadataBySubject(MetadataSubjectInterface $metadataSubject)
|
||||
{
|
||||
$metadata = $this->metadataProvider->findMetadataBySubject($metadataSubject);
|
||||
if (null !== $metadata) {
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
$hierarchy = $this->metadataHierarchyProvider->getHierarchyByMetadataSubject($metadataSubject);
|
||||
if ('DefaultPage' === end($hierarchy)) {
|
||||
return new PageMetadata();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
45
src/Sylius/Component/Core/Model/Archetype.php
Normal file
45
src/Sylius/Component/Core/Model/Archetype.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?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\Component\Core\Model;
|
||||
|
||||
use Sylius\Component\Product\Model\Archetype as BaseArchetype;
|
||||
use Sylius\Component\Product\Model\ArchetypeTranslation;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class Archetype extends BaseArchetype implements ArchetypeInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadataClassIdentifier()
|
||||
{
|
||||
return 'Archetype';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadataIdentifier()
|
||||
{
|
||||
return $this->getMetadataClassIdentifier() . '-' . $this->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getTranslationClass()
|
||||
{
|
||||
return ArchetypeTranslation::class;
|
||||
}
|
||||
}
|
||||
22
src/Sylius/Component/Core/Model/ArchetypeInterface.php
Normal file
22
src/Sylius/Component/Core/Model/ArchetypeInterface.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?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\Component\Core\Model;
|
||||
|
||||
use Sylius\Component\Product\Model\ArchetypeInterface as BaseArchetypeInterface;
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface ArchetypeInterface extends BaseArchetypeInterface, MetadataSubjectInterface
|
||||
{
|
||||
}
|
||||
|
|
@ -87,6 +87,22 @@ class Product extends BaseProduct implements ProductInterface
|
|||
$this->variantSelectionMethod = self::VARIANT_SELECTION_CHOICE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadataClassIdentifier()
|
||||
{
|
||||
return self::METADATA_CLASS_IDENTIFIER;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadataIdentifier()
|
||||
{
|
||||
return $this->getMetadataClassIdentifier() . '-' . $this->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use Doctrine\Common\Collections\Collection;
|
|||
use Sylius\Component\Addressing\Model\ZoneInterface;
|
||||
use Sylius\Component\Channel\Model\ChannelsAwareInterface;
|
||||
use Sylius\Component\Product\Model\ProductInterface as BaseProductInterface;
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
use Sylius\Component\Shipping\Model\ShippingCategoryInterface;
|
||||
use Sylius\Component\Taxation\Model\TaxableInterface;
|
||||
use Sylius\Component\Taxation\Model\TaxCategoryInterface;
|
||||
|
|
@ -28,7 +29,8 @@ interface ProductInterface extends
|
|||
BaseProductInterface,
|
||||
TaxableInterface,
|
||||
TaxonsAwareInterface,
|
||||
ChannelsAwareInterface
|
||||
ChannelsAwareInterface,
|
||||
MetadataSubjectInterface
|
||||
{
|
||||
/*
|
||||
* Variant selection methods.
|
||||
|
|
@ -41,6 +43,8 @@ interface ProductInterface extends
|
|||
const VARIANT_SELECTION_CHOICE = 'choice';
|
||||
const VARIANT_SELECTION_MATCH = 'match';
|
||||
|
||||
const METADATA_CLASS_IDENTIFIER = 'Product';
|
||||
|
||||
/**
|
||||
* Get product SKU.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -147,6 +147,22 @@ class ProductVariant extends BaseVariant implements ProductVariantInterface
|
|||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadataClassIdentifier()
|
||||
{
|
||||
return self::METADATA_CLASS_IDENTIFIER;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadataIdentifier()
|
||||
{
|
||||
return $this->getMetadataClassIdentifier() . '-' . $this->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use Doctrine\Common\Collections\Collection;
|
|||
use Sylius\Component\Inventory\Model\StockableInterface;
|
||||
use Sylius\Component\Pricing\Model\PriceableInterface;
|
||||
use Sylius\Component\Product\Model\VariantInterface as BaseVariantInterface;
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
use Sylius\Component\Shipping\Model\ShippableInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -26,8 +27,11 @@ interface ProductVariantInterface extends
|
|||
BaseVariantInterface,
|
||||
ShippableInterface,
|
||||
StockableInterface,
|
||||
PriceableInterface
|
||||
PriceableInterface,
|
||||
MetadataSubjectInterface
|
||||
{
|
||||
const METADATA_CLASS_IDENTIFIER = 'ProductVariant';
|
||||
|
||||
/**
|
||||
* Get images.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
<?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 spec\Sylius\Component\Core\Metadata\HierarchyProvider;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Component\Core\Metadata\HierarchyProvider\ProductHierarchyProvider;
|
||||
use Sylius\Component\Core\Model\ArchetypeInterface;
|
||||
use Sylius\Component\Core\Model\ProductInterface;
|
||||
use Sylius\Component\Metadata\HierarchyProvider\MetadataHierarchyProviderInterface;
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
|
||||
/**
|
||||
* @mixin ProductHierarchyProvider
|
||||
*
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class ProductHierarchyProviderSpec extends ObjectBehavior
|
||||
{
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Component\Core\Metadata\HierarchyProvider\ProductHierarchyProvider');
|
||||
}
|
||||
|
||||
function it_implements_Sylius_Metadata_Hierarchy_Provider_interface()
|
||||
{
|
||||
$this->shouldImplement(MetadataHierarchyProviderInterface::class);
|
||||
}
|
||||
|
||||
function it_supports_Sylius_Core_Product(
|
||||
ProductInterface $coreProduct,
|
||||
MetadataSubjectInterface $metadataSubject
|
||||
) {
|
||||
$this->supports($coreProduct)->shouldReturn(true);
|
||||
$this->supports($metadataSubject)->shouldReturn(false);
|
||||
}
|
||||
|
||||
function it_generates_correct_hierarchy_when_product_has_archetype(
|
||||
ProductInterface $product,
|
||||
ArchetypeInterface $archetype
|
||||
) {
|
||||
$product->getMetadataIdentifier()->shouldBeCalled()->willReturn('Product-42');
|
||||
$product->getMetadataClassIdentifier()->shouldBeCalled()->willReturn('Product');
|
||||
|
||||
$archetype->getMetadataIdentifier()->shouldBeCalled()->willReturn('Archetype-42');
|
||||
|
||||
$product->getArchetype()->shouldBeCalled()->willReturn($archetype);
|
||||
|
||||
$this->getHierarchyByMetadataSubject($product)->shouldReturn([
|
||||
'Product-42',
|
||||
'Archetype-42',
|
||||
'Product',
|
||||
'DefaultPage',
|
||||
]);
|
||||
}
|
||||
|
||||
function it_generates_correct_hierarchy_when_product_does_not_have_archetype(
|
||||
ProductInterface $product
|
||||
) {
|
||||
$product->getMetadataIdentifier()->shouldBeCalled()->willReturn('Product-42');
|
||||
$product->getMetadataClassIdentifier()->shouldBeCalled()->willReturn('Product');
|
||||
|
||||
$product->getArchetype()->shouldBeCalled()->willReturn(null);
|
||||
|
||||
$this->getHierarchyByMetadataSubject($product)->shouldReturn([
|
||||
'Product-42',
|
||||
'Product',
|
||||
'DefaultPage',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<?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 spec\Sylius\Component\Core\Metadata\HierarchyProvider;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Component\Core\Model\ArchetypeInterface;
|
||||
use Sylius\Component\Core\Model\ProductInterface;
|
||||
use Sylius\Component\Core\Model\ProductVariantInterface;
|
||||
use Sylius\Component\Metadata\HierarchyProvider\MetadataHierarchyProviderInterface;
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
|
||||
/**
|
||||
* @mixin \Sylius\Component\Core\Metadata\HierarchyProvider\ProductVariantHierarchyProvider
|
||||
*
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class ProductVariantHierarchyProviderSpec extends ObjectBehavior
|
||||
{
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Component\Core\Metadata\HierarchyProvider\ProductVariantHierarchyProvider');
|
||||
}
|
||||
|
||||
function it_implements_Sylius_Metadata_Hierarchy_Provider_interface()
|
||||
{
|
||||
$this->shouldImplement(MetadataHierarchyProviderInterface::class);
|
||||
}
|
||||
|
||||
function it_supports_Sylius_Core_ProductVariant(
|
||||
ProductVariantInterface $coreProductVariant,
|
||||
MetadataSubjectInterface $metadataSubject
|
||||
) {
|
||||
$this->supports($coreProductVariant)->shouldReturn(true);
|
||||
$this->supports($metadataSubject)->shouldReturn(false);
|
||||
}
|
||||
|
||||
function it_generates_correct_hierarchy_when_product_variant_has_archetype(
|
||||
ProductVariantInterface $productVariant,
|
||||
ProductInterface $product,
|
||||
ArchetypeInterface $archetype
|
||||
) {
|
||||
$productVariant->getMetadataIdentifier()->shouldBeCalled()->willReturn('ProductVariant-42');
|
||||
|
||||
$product->getMetadataIdentifier()->shouldBeCalled()->willReturn('Product-42');
|
||||
$product->getMetadataClassIdentifier()->shouldBeCalled()->willReturn('Product');
|
||||
|
||||
$archetype->getMetadataIdentifier()->shouldBeCalled()->willReturn('Archetype-42');
|
||||
|
||||
$productVariant->getProduct()->shouldBeCalled()->willReturn($product);
|
||||
|
||||
$product->getArchetype()->shouldBeCalled()->willReturn($archetype);
|
||||
|
||||
$this->getHierarchyByMetadataSubject($productVariant)->shouldReturn([
|
||||
'ProductVariant-42',
|
||||
'Product-42',
|
||||
'Archetype-42',
|
||||
'Product',
|
||||
'DefaultPage',
|
||||
]);
|
||||
}
|
||||
|
||||
function it_generates_correct_hierarchy_when_product_variant_does_not_have_archetype(
|
||||
ProductVariantInterface $productVariant,
|
||||
ProductInterface $product
|
||||
) {
|
||||
$productVariant->getMetadataIdentifier()->shouldBeCalled()->willReturn('ProductVariant-42');
|
||||
|
||||
$product->getMetadataIdentifier()->shouldBeCalled()->willReturn('Product-42');
|
||||
$product->getMetadataClassIdentifier()->shouldBeCalled()->willReturn('Product');
|
||||
|
||||
$productVariant->getProduct()->shouldBeCalled()->willReturn($product);
|
||||
|
||||
$product->getArchetype()->shouldBeCalled()->willReturn(null);
|
||||
|
||||
$this->getHierarchyByMetadataSubject($productVariant)->shouldReturn([
|
||||
'ProductVariant-42',
|
||||
'Product-42',
|
||||
'Product',
|
||||
'DefaultPage',
|
||||
]);
|
||||
}
|
||||
}
|
||||
37
src/Sylius/Component/Core/spec/Model/ArchetypeSpec.php
Normal file
37
src/Sylius/Component/Core/spec/Model/ArchetypeSpec.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?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 spec\Sylius\Component\Core\Model;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
/**
|
||||
* @mixin \Sylius\Component\Core\Model\Archetype
|
||||
*
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class ArchetypeSpec extends ObjectBehavior
|
||||
{
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType('Sylius\Component\Core\Model\Archetype');
|
||||
}
|
||||
|
||||
function it_implements_Sylius_Core_Archetype_interface()
|
||||
{
|
||||
$this->shouldImplement('Sylius\Component\Core\Model\ArchetypeInterface');
|
||||
}
|
||||
|
||||
function it_has_metadata_class_identifier()
|
||||
{
|
||||
$this->getMetadataClassIdentifier()->shouldReturn('Archetype');
|
||||
}
|
||||
}
|
||||
|
|
@ -53,6 +53,11 @@ class ProductSpec extends ObjectBehavior
|
|||
$this->shouldHaveType(SyliusProduct::class);
|
||||
}
|
||||
|
||||
function it_has_metadata_class_identifier()
|
||||
{
|
||||
$this->getMetadataClassIdentifier()->shouldReturn('Product');
|
||||
}
|
||||
|
||||
function it_initializes_taxon_collection_by_default()
|
||||
{
|
||||
$this->getTaxons()->shouldHaveType(Collection::class);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ class ProductVariantSpec extends ObjectBehavior
|
|||
$this->shouldHaveType('Sylius\Component\Product\Model\Variant');
|
||||
}
|
||||
|
||||
function it_has_metadata_class_identifier()
|
||||
{
|
||||
$this->getMetadataClassIdentifier()->shouldReturn('ProductVariant');
|
||||
}
|
||||
|
||||
function it_should_not_have_price_by_default()
|
||||
{
|
||||
$this->getPrice()->shouldReturn(null);
|
||||
|
|
|
|||
7
src/Sylius/Component/Metadata/.gitignore
vendored
Normal file
7
src/Sylius/Component/Metadata/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
vendor/
|
||||
bin/
|
||||
|
||||
composer.phar
|
||||
composer.lock
|
||||
|
||||
phpspec.yml
|
||||
15
src/Sylius/Component/Metadata/.travis.yml
Normal file
15
src/Sylius/Component/Metadata/.travis.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
language: php
|
||||
|
||||
sudo: false
|
||||
|
||||
php:
|
||||
- 7.0
|
||||
- 5.6
|
||||
- 5.5
|
||||
|
||||
before_script:
|
||||
- phpenc config-rm xdebug.ini || true
|
||||
- composer install --no-interaction --prefer-source
|
||||
|
||||
script:
|
||||
- vendor/bin/phpspec run -f pretty --verbose
|
||||
56
src/Sylius/Component/Metadata/Accessor/MetadataAccessor.php
Normal file
56
src/Sylius/Component/Metadata/Accessor/MetadataAccessor.php
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?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\Component\Metadata\Accessor;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
use Sylius\Component\Metadata\Provider\MetadataProviderInterface;
|
||||
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
final class MetadataAccessor implements MetadataAccessorInterface
|
||||
{
|
||||
/**
|
||||
* @var MetadataProviderInterface
|
||||
*/
|
||||
private $metadataProvider;
|
||||
|
||||
/**
|
||||
* @var PropertyAccessorInterface
|
||||
*/
|
||||
private $propertyAccessor;
|
||||
|
||||
/**
|
||||
* @param MetadataProviderInterface $metadataProvider
|
||||
* @param PropertyAccessorInterface $propertyAccessor
|
||||
*/
|
||||
public function __construct(MetadataProviderInterface $metadataProvider, PropertyAccessorInterface $propertyAccessor)
|
||||
{
|
||||
$this->metadataProvider = $metadataProvider;
|
||||
$this->propertyAccessor = $propertyAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProperty(MetadataSubjectInterface $metadataSubject, $propertyPath = null)
|
||||
{
|
||||
$metadata = $this->metadataProvider->findMetadataBySubject($metadataSubject);
|
||||
|
||||
if (null === $propertyPath) {
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
return $this->propertyAccessor->getValue($metadata, $propertyPath);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?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\Component\Metadata\Accessor;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface MetadataAccessorInterface
|
||||
{
|
||||
/**
|
||||
* @param MetadataSubjectInterface $metadataSubject
|
||||
* @param string|null $propertyPath
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProperty(MetadataSubjectInterface $metadataSubject, $propertyPath = null);
|
||||
}
|
||||
35
src/Sylius/Component/Metadata/Compiler/MetadataCompiler.php
Normal file
35
src/Sylius/Component/Metadata/Compiler/MetadataCompiler.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?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\Component\Metadata\Compiler;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
final class MetadataCompiler implements MetadataCompilerInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile(MetadataInterface $metadata, array $parents = [])
|
||||
{
|
||||
$compiledMetadata = clone $metadata;
|
||||
|
||||
/** @var MetadataInterface[] $parents */
|
||||
foreach ($parents as $parent) {
|
||||
$compiledMetadata->merge($parent);
|
||||
}
|
||||
|
||||
return $compiledMetadata;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?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\Component\Metadata\Compiler;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface MetadataCompilerInterface
|
||||
{
|
||||
/**
|
||||
* @param MetadataInterface $metadata
|
||||
* @param MetadataInterface[] $parents
|
||||
*
|
||||
* @return MetadataInterface
|
||||
*/
|
||||
public function compile(MetadataInterface $metadata, array $parents = []);
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Sylius\Component\Metadata\Factory;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataContainerInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
final class MetadataContainerFactory implements MetadataContainerFactoryInterface, FactoryInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $metadataContainerClass;
|
||||
|
||||
/**
|
||||
* @param string $metadataContainerClass
|
||||
*/
|
||||
public function __construct($metadataContainerClass)
|
||||
{
|
||||
$this->metadataContainerClass = $metadataContainerClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return MetadataContainerInterface
|
||||
*/
|
||||
public function createNew()
|
||||
{
|
||||
return new $this->metadataContainerClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createIdentifiedBy($id)
|
||||
{
|
||||
$metadataContainer = $this->createNew();
|
||||
$metadataContainer->setId($id);
|
||||
|
||||
return $metadataContainer;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Sylius\Component\Metadata\Factory;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataContainerInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface MetadataContainerFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @return MetadataContainerInterface
|
||||
*/
|
||||
public function createIdentifiedBy($id);
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?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\Component\Metadata\HierarchyProvider;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
final class CompositeMetadataHierarchyProvider implements MetadataHierarchyProviderInterface
|
||||
{
|
||||
/**
|
||||
* @var MetadataHierarchyProviderInterface[]
|
||||
*/
|
||||
private $providers;
|
||||
|
||||
/**
|
||||
* @param MetadataHierarchyProviderInterface[] $providers
|
||||
*/
|
||||
public function __construct(array $providers = [])
|
||||
{
|
||||
$this->assertProvidersHaveCorrectType($providers);
|
||||
|
||||
$this->providers = $providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHierarchyByMetadataSubject(MetadataSubjectInterface $metadataSubject)
|
||||
{
|
||||
foreach ($this->providers as $provider) {
|
||||
if ($provider->supports($metadataSubject)) {
|
||||
return $provider->getHierarchyByMetadataSubject($metadataSubject);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
$metadataSubject->getMetadataIdentifier(),
|
||||
$metadataSubject->getMetadataClassIdentifier(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports(MetadataSubjectInterface $metadataSubject)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MetadataHierarchyProviderInterface[] $providers
|
||||
*/
|
||||
private function assertProvidersHaveCorrectType(array $providers)
|
||||
{
|
||||
foreach ($providers as $provider) {
|
||||
if ($provider instanceof MetadataHierarchyProviderInterface) {
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Metadata hierarchy provider should have type "%s"',
|
||||
MetadataHierarchyProviderInterface::class
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?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\Component\Metadata\HierarchyProvider;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataSubjectInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface MetadataHierarchyProviderInterface
|
||||
{
|
||||
/**
|
||||
* Returns identifiers in order from the most specific to the least specific.
|
||||
*
|
||||
* @param MetadataSubjectInterface $metadataSubject
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getHierarchyByMetadataSubject(MetadataSubjectInterface $metadataSubject);
|
||||
|
||||
/**
|
||||
* @param MetadataSubjectInterface $metadataSubject
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function supports(MetadataSubjectInterface $metadataSubject);
|
||||
}
|
||||
19
src/Sylius/Component/Metadata/LICENSE
Normal file
19
src/Sylius/Component/Metadata/LICENSE
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2011-2016 Paweł Jędrzejewski
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
78
src/Sylius/Component/Metadata/Model/AbstractMetadata.php
Normal file
78
src/Sylius/Component/Metadata/Model/AbstractMetadata.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?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\Component\Metadata\Model;
|
||||
|
||||
/**
|
||||
* Base metadata class with reusable merging ability.
|
||||
*
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
abstract class AbstractMetadata implements MetadataInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function merge(MetadataInterface $metadata)
|
||||
{
|
||||
if (!$metadata instanceof $this || !$this instanceof $metadata) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf(
|
||||
'You can only merge instances of the same classes. Tried to merge "%s" with "%s".',
|
||||
get_class($this),
|
||||
get_class($metadata)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$inheritedVariables = get_object_vars($metadata);
|
||||
foreach ($inheritedVariables as $inheritedKey => $inheritedValue) {
|
||||
if ($this->{$inheritedKey} instanceof MetadataInterface) {
|
||||
$this->{$inheritedKey}->merge($inheritedValue);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null !== $this->{$inheritedKey}) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->{$inheritedKey} = $inheritedValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return array_map(
|
||||
function ($value) {
|
||||
if ($value instanceof MetadataInterface) {
|
||||
$value = $value->toArray();
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
get_object_vars($this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function forAll(callable $callable)
|
||||
{
|
||||
foreach (get_object_vars($this) as $key => $value) {
|
||||
$this->$key = $callable($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
126
src/Sylius/Component/Metadata/Model/Custom/PageMetadata.php
Normal file
126
src/Sylius/Component/Metadata/Model/Custom/PageMetadata.php
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<?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\Component\Metadata\Model\Custom;
|
||||
|
||||
use Sylius\Component\Metadata\Model\AbstractMetadata;
|
||||
use Sylius\Component\Metadata\Model\Twitter\CardInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class PageMetadata extends AbstractMetadata implements PageMetadataInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $title;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $keywords = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $charset = 'UTF-8';
|
||||
|
||||
/**
|
||||
* @var CardInterface
|
||||
*/
|
||||
protected $twitter;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getKeywords()
|
||||
{
|
||||
return $this->keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setKeywords(array $keywords)
|
||||
{
|
||||
$this->keywords = $keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCharset()
|
||||
{
|
||||
return $this->charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setCharset($charset)
|
||||
{
|
||||
$this->charset = $charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTwitter()
|
||||
{
|
||||
return $this->twitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setTwitter(CardInterface $twitter = null)
|
||||
{
|
||||
$this->twitter = $twitter;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?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\Component\Metadata\Model\Custom;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataInterface;
|
||||
use Sylius\Component\Metadata\Model\Twitter\CardInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface PageMetadataInterface extends MetadataInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle();
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription();
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description);
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getKeywords();
|
||||
|
||||
/**
|
||||
* @param string[] $keywords
|
||||
*/
|
||||
public function setKeywords(array $keywords);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCharset();
|
||||
|
||||
/**
|
||||
* @param string $charset
|
||||
*/
|
||||
public function setCharset($charset);
|
||||
|
||||
/**
|
||||
* @return CardInterface|null
|
||||
*/
|
||||
public function getTwitter();
|
||||
|
||||
/**
|
||||
* @param CardInterface|null $card
|
||||
*/
|
||||
public function setTwitter(CardInterface $card = null);
|
||||
}
|
||||
60
src/Sylius/Component/Metadata/Model/MetadataContainer.php
Normal file
60
src/Sylius/Component/Metadata/Model/MetadataContainer.php
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?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\Component\Metadata\Model;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class MetadataContainer implements MetadataContainerInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @var MetadataInterface
|
||||
*/
|
||||
protected $metadata;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadata()
|
||||
{
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMetadata(MetadataInterface $metadata)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?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\Component\Metadata\Model;
|
||||
|
||||
use Sylius\Component\Resource\Model\ResourceInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface MetadataContainerInterface extends ResourceInterface
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId();
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
public function setId($id);
|
||||
|
||||
/**
|
||||
* @return MetadataInterface
|
||||
*/
|
||||
public function getMetadata();
|
||||
|
||||
/**
|
||||
* @param MetadataInterface $metadata
|
||||
*/
|
||||
public function setMetadata(MetadataInterface $metadata);
|
||||
}
|
||||
33
src/Sylius/Component/Metadata/Model/MetadataInterface.php
Normal file
33
src/Sylius/Component/Metadata/Model/MetadataInterface.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?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\Component\Metadata\Model;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface MetadataInterface
|
||||
{
|
||||
/**
|
||||
* @param MetadataInterface $metadata
|
||||
*/
|
||||
public function merge(MetadataInterface $metadata);
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray();
|
||||
|
||||
/**
|
||||
* @param callable $callable
|
||||
*/
|
||||
public function forAll(callable $callable);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?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\Component\Metadata\Model;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface MetadataSubjectInterface
|
||||
{
|
||||
/**
|
||||
* Metadata class identifier is usually a class name (not FQCN), eg. "MetadataSubject".
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMetadataClassIdentifier();
|
||||
|
||||
/**
|
||||
* Metadata identifier is usually a class name (not FQCN) and ID joined by dash, eg. "MetadataSubject-42".
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMetadataIdentifier();
|
||||
}
|
||||
75
src/Sylius/Component/Metadata/Model/Twitter/AbstractCard.php
Normal file
75
src/Sylius/Component/Metadata/Model/Twitter/AbstractCard.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?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\Component\Metadata\Model\Twitter;
|
||||
|
||||
use Sylius\Component\Metadata\Model\AbstractMetadata;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
abstract class AbstractCard extends AbstractMetadata implements CardInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $site;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $siteId;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSite()
|
||||
{
|
||||
return $this->site;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSite($site)
|
||||
{
|
||||
$this->site = $site;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSiteId()
|
||||
{
|
||||
return $this->siteId;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSiteId($siteId)
|
||||
{
|
||||
$this->siteId = $siteId;
|
||||
}
|
||||
}
|
||||
235
src/Sylius/Component/Metadata/Model/Twitter/AppCard.php
Normal file
235
src/Sylius/Component/Metadata/Model/Twitter/AppCard.php
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
<?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\Component\Metadata\Model\Twitter;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class AppCard extends AbstractCard implements AppCardInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $type = 'app';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appNameIphone;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appIdIphone;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appUrlIphone;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appNameIpad;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appIdIpad;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appUrlIpad;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appNameGooglePlay;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appIdGooglePlay;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $appUrlGooglePlay;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAppNameIphone()
|
||||
{
|
||||
return $this->appNameIphone;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAppNameIphone($appNameIphone)
|
||||
{
|
||||
$this->appNameIphone = $appNameIphone;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAppIdIphone()
|
||||
{
|
||||
return $this->appIdIphone;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAppIdIphone($appIdIphone)
|
||||
{
|
||||
$this->appIdIphone = $appIdIphone;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAppUrlIphone()
|
||||
{
|
||||
return $this->appUrlIphone;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAppUrlIphone($appUrlIphone)
|
||||
{
|
||||
$this->appUrlIphone = $appUrlIphone;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAppNameIpad()
|
||||
{
|
||||
return $this->appNameIpad;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAppNameIpad($appNameIpad)
|
||||
{
|
||||
$this->appNameIpad = $appNameIpad;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAppIdIpad()
|
||||
{
|
||||
return $this->appIdIpad;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAppIdIpad($appIdIpad)
|
||||
{
|
||||
$this->appIdIpad = $appIdIpad;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAppUrlIpad()
|
||||
{
|
||||
return $this->appUrlIpad;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAppUrlIpad($appUrlIpad)
|
||||
{
|
||||
$this->appUrlIpad = $appUrlIpad;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAppNameGooglePlay()
|
||||
{
|
||||
return $this->appNameGooglePlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAppNameGooglePlay($appNameGooglePlay)
|
||||
{
|
||||
$this->appNameGooglePlay = $appNameGooglePlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAppIdGooglePlay()
|
||||
{
|
||||
return $this->appIdGooglePlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAppIdGooglePlay($appIdGooglePlay)
|
||||
{
|
||||
$this->appIdGooglePlay = $appIdGooglePlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAppUrlGooglePlay()
|
||||
{
|
||||
return $this->appUrlGooglePlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAppUrlGooglePlay($appUrlGooglePlay)
|
||||
{
|
||||
$this->appUrlGooglePlay = $appUrlGooglePlay;
|
||||
}
|
||||
}
|
||||
160
src/Sylius/Component/Metadata/Model/Twitter/AppCardInterface.php
Normal file
160
src/Sylius/Component/Metadata/Model/Twitter/AppCardInterface.php
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<?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\Component\Metadata\Model\Twitter;
|
||||
|
||||
/**
|
||||
* @see https://dev.twitter.com/cards/types/app
|
||||
*
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface AppCardInterface extends CardInterface
|
||||
{
|
||||
/**
|
||||
* The twitter:description property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription();
|
||||
|
||||
/**
|
||||
* The twitter:description property.
|
||||
*
|
||||
* @param string $description
|
||||
*/
|
||||
public function setDescription($description);
|
||||
|
||||
/**
|
||||
* The twitter:app:name:iphone property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAppNameIphone();
|
||||
|
||||
/**
|
||||
* The twitter:app:name:iphone property.
|
||||
*
|
||||
* @param string $appNameIphone
|
||||
*/
|
||||
public function setAppNameIphone($appNameIphone);
|
||||
|
||||
/**
|
||||
* The twitter:app:id:iphone property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAppIdIphone();
|
||||
|
||||
/**
|
||||
* The twitter:app:id:iphone property.
|
||||
*
|
||||
* @param string $appIdIphone
|
||||
*/
|
||||
public function setAppIdIphone($appIdIphone);
|
||||
|
||||
/**
|
||||
* The twitter:app:url:iphone property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAppUrlIphone();
|
||||
|
||||
/**
|
||||
* The twitter:app:url:iphone property.
|
||||
*
|
||||
* @param string $appUrlIphone
|
||||
*/
|
||||
public function setAppUrlIphone($appUrlIphone);
|
||||
|
||||
/**
|
||||
* The twitter:app:name:ipad property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAppNameIpad();
|
||||
|
||||
/**
|
||||
* The twitter:app:name:ipad property.
|
||||
*
|
||||
* @param string $appNameIpad
|
||||
*/
|
||||
public function setAppNameIpad($appNameIpad);
|
||||
|
||||
/**
|
||||
* The twitter:app:id:ipad property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAppIdIpad();
|
||||
|
||||
/**
|
||||
* The twitter:app:id:ipad property.
|
||||
*
|
||||
* @param string $appIdIpad
|
||||
*/
|
||||
public function setAppIdIpad($appIdIpad);
|
||||
|
||||
/**
|
||||
* The twitter:app:url:ipad property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAppUrlIpad();
|
||||
|
||||
/**
|
||||
* The twitter:app:url:ipad property.
|
||||
*
|
||||
* @param string $appUrlIpad
|
||||
*/
|
||||
public function setAppUrlIpad($appUrlIpad);
|
||||
|
||||
/**
|
||||
* The twitter:app:name:googleplay property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAppNameGooglePlay();
|
||||
|
||||
/**
|
||||
* The twitter:app:name:googleplay property.
|
||||
*
|
||||
* @param string $appNameGooglePlay
|
||||
*/
|
||||
public function setAppNameGooglePlay($appNameGooglePlay);
|
||||
|
||||
/**
|
||||
* The twitter:app:id:googleplay property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAppIdGooglePlay();
|
||||
|
||||
/**
|
||||
* The twitter:app:id:googleplay property.
|
||||
*
|
||||
* @param string $appIdGooglePlay
|
||||
*/
|
||||
public function setAppIdGooglePlay($appIdGooglePlay);
|
||||
|
||||
/**
|
||||
* The twitter:app:url:googleplay property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAppUrlGooglePlay();
|
||||
|
||||
/**
|
||||
* The twitter:app:url:googleplay property.
|
||||
*
|
||||
* @param string $appUrlGooglePlay
|
||||
*/
|
||||
public function setAppUrlGooglePlay($appUrlGooglePlay);
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?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\Component\Metadata\Model\Twitter;
|
||||
|
||||
use Sylius\Component\Metadata\Model\MetadataInterface;
|
||||
|
||||
/**
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
interface CardInterface extends MetadataInterface
|
||||
{
|
||||
/**
|
||||
* The twitter:card property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType();
|
||||
|
||||
/**
|
||||
* The twitter:site property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSite();
|
||||
|
||||
/**
|
||||
* The twitter:site property.
|
||||
*
|
||||
* @param string $site
|
||||
*/
|
||||
public function setSite($site);
|
||||
|
||||
/**
|
||||
* The twitter:site:id property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSiteId();
|
||||
|
||||
/**
|
||||
* The twitter:site:id property.
|
||||
*
|
||||
* @param string $siteId
|
||||
*/
|
||||
public function setSiteId($siteId);
|
||||
}
|
||||
193
src/Sylius/Component/Metadata/Model/Twitter/PlayerCard.php
Normal file
193
src/Sylius/Component/Metadata/Model/Twitter/PlayerCard.php
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
<?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\Component\Metadata\Model\Twitter;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @author Kamil Kokot <kamil.kokot@lakion.com>
|
||||
*/
|
||||
class PlayerCard extends AbstractCard implements PlayerCardInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $type = 'player';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $title;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $image;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $player;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $playerWidth;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $playerHeight;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $playerStream;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $playerStreamContentType;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getImage()
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setImage($image)
|
||||
{
|
||||
$this->image = $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPlayer()
|
||||
{
|
||||
return $this->player;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setPlayer($player)
|
||||
{
|
||||
$this->player = $player;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPlayerWidth()
|
||||
{
|
||||
return $this->playerWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPlayerWidth($playerWidth)
|
||||
{
|
||||
$this->playerWidth = $playerWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPlayerHeight()
|
||||
{
|
||||
return $this->playerHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPlayerHeight($playerHeight)
|
||||
{
|
||||
$this->playerHeight = $playerHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPlayerStream()
|
||||
{
|
||||
return $this->playerStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPlayerStream($playerStream)
|
||||
{
|
||||
$this->playerStream = $playerStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPlayerStreamContentType()
|
||||
{
|
||||
return $this->playerStreamContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPlayerStreamContentType($playerStreamContentType)
|
||||
{
|
||||
$this->playerStreamContentType = $playerStreamContentType;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue