mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 09:02:12 +00:00
Merge pull request #6657 from Zales0123/edit-taxons-slug
[Taxon] Edit taxon slug
This commit is contained in:
commit
6a6aa6c36b
49 changed files with 571 additions and 177 deletions
38
app/migrations/Version20161107154554.php
Normal file
38
app/migrations/Version20161107154554.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Sylius\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
class Version20161107154554 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('DROP INDEX permalink_uidx ON sylius_taxon_translation');
|
||||
$this->addSql('ALTER TABLE sylius_taxon_translation DROP permalink');
|
||||
$this->addSql('CREATE UNIQUE INDEX slug_uidx ON sylius_taxon_translation (locale, slug)');
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 INDEX slug_uidx ON sylius_taxon_translation');
|
||||
$this->addSql('ALTER TABLE sylius_taxon_translation ADD permalink VARCHAR(255) NOT NULL COLLATE utf8_unicode_ci');
|
||||
$this->addSql('CREATE UNIQUE INDEX permalink_uidx ON sylius_taxon_translation (locale, permalink)');
|
||||
}
|
||||
}
|
||||
|
|
@ -13,16 +13,17 @@ Feature: Adding a new taxon
|
|||
Given I want to create a new taxon
|
||||
When I specify its code as "t-shirts"
|
||||
And I name it "T-Shirts" in "English (United States)"
|
||||
And I set its slug to "t-shirts"
|
||||
And I add it
|
||||
Then I should be notified that it has been successfully created
|
||||
And the "T-Shirts" taxon should appear in the registry
|
||||
|
||||
@ui
|
||||
Scenario: Adding a new taxon with permalink and description
|
||||
Scenario: Adding a new taxon with slug and description
|
||||
Given I want to create a new taxon
|
||||
When I specify its code as "category"
|
||||
And I name it "Category" in "English (United States)"
|
||||
And I specify its permalink as "category" in "English (United States)"
|
||||
And I set its slug to "category"
|
||||
And I describe it as "Main taxonomy for products." in "English (United States)"
|
||||
And I add it
|
||||
Then I should be notified that it has been successfully created
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ Feature: Adding a new taxon for parent
|
|||
Given I want to create a new taxon for "Category"
|
||||
And I specify its code as "guns"
|
||||
And I name it "Guns" in "English (United States)"
|
||||
And I set its slug to "guns"
|
||||
And I add it
|
||||
Then I should be notified that it has been successfully created
|
||||
And the "Guns" taxon should appear in the registry
|
||||
|
|
|
|||
|
|
@ -26,22 +26,12 @@ Feature: Editing a taxon
|
|||
Then I should be notified that it has been successfully edited
|
||||
And this taxon description should be "Main taxonomy for stickers"
|
||||
|
||||
@ui
|
||||
Scenario: Changing permalink
|
||||
Given I want to modify the "T-Shirts" taxon
|
||||
When I rename it to "Stickers" in "English (United States)"
|
||||
And I change its description to "Main taxonomy for stickers" in "English (United States)"
|
||||
And I change its permalink to "stickers" in "English (United States)"
|
||||
And I save my changes
|
||||
Then I should be notified that it has been successfully edited
|
||||
And this taxon permalink should be "stickers"
|
||||
|
||||
@ui
|
||||
Scenario: Changing parent taxon
|
||||
Given I want to modify the "T-Shirts" taxon
|
||||
When I rename it to "Stickers" in "English (United States)"
|
||||
And I change its description to "Main taxonomy for stickers" in "English (United States)"
|
||||
And I change its permalink to "stickers" in "English (United States)"
|
||||
And I set its slug to "stickers"
|
||||
And I change its parent taxon to "Accessories"
|
||||
And I save my changes
|
||||
Then I should be notified that it has been successfully edited
|
||||
|
|
|
|||
80
features/taxonomy/managing_taxons/editing_taxon_slug.feature
Normal file
80
features/taxonomy/managing_taxons/editing_taxon_slug.feature
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
@managing_taxons
|
||||
Feature: Editing taxon's slug
|
||||
In order to In order to manage access path to taxon page
|
||||
As an Administrator
|
||||
I want to be able to edit taxon's slug
|
||||
|
||||
Background:
|
||||
Given the store is available in "English (United States)"
|
||||
And I am logged in as an administrator
|
||||
|
||||
@ui @javascript
|
||||
Scenario: Creating a root taxon with an autogenerated slug
|
||||
Given I want to create a new taxon
|
||||
When I specify its code as "MEDIEVAL_WEAPONS"
|
||||
And I name it "Medieval weapons" in "English (United States)"
|
||||
And I add it
|
||||
Then this taxon slug should be "medieval-weapons"
|
||||
|
||||
@ui
|
||||
Scenario: Creating a root taxon with a custom slug
|
||||
Given I want to create a new taxon
|
||||
When I specify its code as "MEDIEVAL_WEAPONS"
|
||||
And I name it "Medieval weapons" in "English (United States)"
|
||||
And I set its slug to "mw"
|
||||
And I add it
|
||||
Then this taxon slug should be "mw"
|
||||
|
||||
@ui @javascript
|
||||
Scenario: Creating a taxon with an autogenerated slug for parent
|
||||
Given the store has "Medieval weapons" taxonomy
|
||||
And I want to create a new taxon for "Medieval weapons"
|
||||
When I specify its code as "SIEGE_ENGINES"
|
||||
And I name it "Siege engines" in "English (United States)"
|
||||
And I add it
|
||||
Then this taxon slug should be "medieval-weapons/siege-engines"
|
||||
|
||||
@ui
|
||||
Scenario: Creating a taxon with a custom slug for parent
|
||||
Given the store has "Medieval weapons" taxonomy
|
||||
And I want to create a new taxon for "Medieval weapons"
|
||||
When I specify its code as "SIEGE_ENGINES"
|
||||
And I name it "Siege engines" in "English (United States)"
|
||||
And I set its slug to "medieval-weapons/siege"
|
||||
And I add it
|
||||
Then this taxon slug should be "medieval-weapons/siege"
|
||||
|
||||
@ui
|
||||
Scenario: Seeing disabled slug field when editing a taxon
|
||||
Given the store has "Medieval weapons" taxonomy
|
||||
When I want to modify the "Medieval weapons" taxon
|
||||
Then the slug field should not be editable
|
||||
|
||||
@ui @javascript
|
||||
Scenario: Prevent from editing a slug while changing a taxon name
|
||||
Given the store has "Medieval weapons" taxonomy
|
||||
When I want to modify the "Medieval weapons" taxon
|
||||
And I rename it to "Renaissance weapons" in "English (United States)"
|
||||
And I save my changes
|
||||
Then the slug of the "Renaissance weapons" taxon should still be "medieval-weapons"
|
||||
|
||||
@ui @javascript
|
||||
Scenario: Automatically changing a taxon's slug while editing a taxon's name
|
||||
Given the store has "Medieval weapons" taxonomy
|
||||
When I want to modify the "Medieval weapons" taxon
|
||||
And I enable slug modification
|
||||
And I rename it to "Renaissance weapons" in "English (United States)"
|
||||
And I save my changes
|
||||
Then the slug of the "Renaissance weapons" taxon should be "renaissance-weapons"
|
||||
|
||||
@ui @javascript
|
||||
Scenario: Manually changing a taxon's slug while editing a taxon's name
|
||||
Given the store has "Medieval weapons" taxonomy
|
||||
When I want to modify the "Medieval weapons" taxon
|
||||
And I enable slug modification
|
||||
And I rename it to "Renaissance weapons" in "English (United States)"
|
||||
And I set its slug to "renaissance"
|
||||
And I save my changes
|
||||
Then the slug of the "Renaissance weapons" taxon should be "renaissance"
|
||||
|
||||
|
||||
|
|
@ -20,6 +20,7 @@ use Sylius\Component\Core\Model\TaxonInterface;
|
|||
use Sylius\Component\Core\Uploader\ImageUploaderInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
use Sylius\Component\Taxonomy\Generator\TaxonSlugGeneratorInterface;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
/**
|
||||
|
|
@ -52,6 +53,11 @@ final class TaxonomyContext implements Context
|
|||
*/
|
||||
private $imageUploader;
|
||||
|
||||
/**
|
||||
* @var TaxonSlugGeneratorInterface
|
||||
*/
|
||||
private $taxonSlugGenerator;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
|
@ -63,6 +69,7 @@ final class TaxonomyContext implements Context
|
|||
* @param FactoryInterface $taxonImageFactory
|
||||
* @param ObjectManager $objectManager
|
||||
* @param ImageUploaderInterface $imageUploader
|
||||
* @param TaxonSlugGeneratorInterface $taxonSlugGenerator
|
||||
* @param array $minkParameters
|
||||
*/
|
||||
public function __construct(
|
||||
|
|
@ -71,6 +78,7 @@ final class TaxonomyContext implements Context
|
|||
FactoryInterface $taxonImageFactory,
|
||||
ObjectManager $objectManager,
|
||||
ImageUploaderInterface $imageUploader,
|
||||
TaxonSlugGeneratorInterface $taxonSlugGenerator,
|
||||
array $minkParameters
|
||||
) {
|
||||
$this->taxonRepository = $taxonRepository;
|
||||
|
|
@ -78,6 +86,7 @@ final class TaxonomyContext implements Context
|
|||
$this->taxonImageFactory = $taxonImageFactory;
|
||||
$this->objectManager = $objectManager;
|
||||
$this->imageUploader = $imageUploader;
|
||||
$this->taxonSlugGenerator = $taxonSlugGenerator;
|
||||
$this->minkParameters = $minkParameters;
|
||||
}
|
||||
|
||||
|
|
@ -133,6 +142,7 @@ final class TaxonomyContext implements Context
|
|||
$taxon = $this->taxonFactory->createNew();
|
||||
$taxon->setName($name);
|
||||
$taxon->setCode(StringInflector::nameToCode($name));
|
||||
$taxon->setSlug($this->taxonSlugGenerator->generate($name));
|
||||
|
||||
return $taxon;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ use Sylius\Behat\Page\Admin\Taxon\CreatePageInterface;
|
|||
use Sylius\Behat\Page\Admin\Taxon\UpdatePageInterface;
|
||||
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
|
||||
use Sylius\Behat\Service\SharedStorageInterface;
|
||||
use Sylius\Component\Core\Model\Taxon;
|
||||
use Sylius\Component\Core\Model\TaxonInterface;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
|
|
@ -122,6 +123,40 @@ final class ManagingTaxonsContext implements Context
|
|||
$this->updatePage->nameIt($name, $language);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I set its slug to :slug
|
||||
*/
|
||||
public function iSetItsSlugTo($slug)
|
||||
{
|
||||
/** @var CreatePageInterface|UpdatePageInterface $currentPage */
|
||||
$currentPage = $this->currentPageResolver->getCurrentPageWithForm([
|
||||
$this->createPage,
|
||||
$this->createForParentPage,
|
||||
$this->updatePage,
|
||||
]);
|
||||
|
||||
$currentPage->specifySlug($slug);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then the slug field should not be editable
|
||||
*/
|
||||
public function theSlugFieldShouldNotBeEditable()
|
||||
{
|
||||
Assert::true(
|
||||
$this->updatePage->isSlugReadOnly(),
|
||||
'Slug should be immutable, but it does not.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I enable slug modification
|
||||
*/
|
||||
public function iEnableSlugModification()
|
||||
{
|
||||
$this->updatePage->enableSlugModification();
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I change its description to :description in :language
|
||||
*/
|
||||
|
|
@ -130,22 +165,6 @@ final class ManagingTaxonsContext implements Context
|
|||
$this->updatePage->describeItAs($description, $language);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I specify its permalink as :permalink in :language
|
||||
*/
|
||||
public function iSpecifyItsPermalinkAs($permalink, $language)
|
||||
{
|
||||
$this->createPage->specifyPermalink($permalink, $language);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I change its permalink to :permalink in :language
|
||||
*/
|
||||
public function iChangeItsPermalinkToIn($permalink, $language)
|
||||
{
|
||||
$this->updatePage->specifyPermalink($permalink, $language);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When I describe it as :description in :language
|
||||
*/
|
||||
|
|
@ -263,6 +282,19 @@ final class ManagingTaxonsContext implements Context
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^the slug of the ("[^"]+" taxon) should(?:| still) be "([^"]+)"$/
|
||||
*/
|
||||
public function productSlugShouldBe(TaxonInterface $taxon, $slug)
|
||||
{
|
||||
$this->updatePage->open(['id' => $taxon->getId()]);
|
||||
|
||||
Assert::true(
|
||||
$this->updatePage->hasResourceValues(['slug' => $slug]),
|
||||
sprintf('Taxon\'s slug should be %s.', $slug)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^this taxon should (belongs to "[^"]+")$/
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ final class ProductContext implements Context
|
|||
*/
|
||||
public function iCheckListOfProductsForTaxon(TaxonInterface $taxon)
|
||||
{
|
||||
$this->taxonShowPage->open(['permalink' => $taxon->getPermalink()]);
|
||||
$this->taxonShowPage->open(['slug' => $taxon->getSlug()]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -295,7 +295,7 @@ final class ProductContext implements Context
|
|||
{
|
||||
$sorting = ['createdAt' => 'oldest' === $sortDirection ? 'asc' : 'desc'];
|
||||
|
||||
$this->taxonShowPage->open(['permalink' => $taxon->getPermalink(), 'sorting' => $sorting]);
|
||||
$this->taxonShowPage->open(['slug' => $taxon->getSlug(), 'sorting' => $sorting]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -106,14 +106,16 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
|
|||
public function nameIt($name, $languageCode)
|
||||
{
|
||||
$this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_name', $languageCode), $name);
|
||||
|
||||
$this->waitForSlugGenerationIfNecessary();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function specifyPermalink($permalink, $languageCode)
|
||||
public function specifySlug($slug)
|
||||
{
|
||||
$this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_permalink', $languageCode), $permalink);
|
||||
$this->getDocument()->fillField('Slug', $slug);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -210,7 +212,7 @@ JS;
|
|||
'images' => '#sylius_taxon_images',
|
||||
'name' => '#sylius_taxon_translations_en_US_name',
|
||||
'parent' => '#sylius_taxon_parent',
|
||||
'permalink' => '#sylius_taxon_translations_en_US_permalink',
|
||||
'slug' => '#sylius_taxon_translations_en_US_slug',
|
||||
'tree' => '.ui.list',
|
||||
]);
|
||||
}
|
||||
|
|
@ -275,4 +277,13 @@ JS;
|
|||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
private function waitForSlugGenerationIfNecessary()
|
||||
{
|
||||
if ($this->getDriver() instanceof Selenium2Driver) {
|
||||
$this->getDocument()->waitFor(1000, function () {
|
||||
return '' !== $this->getElement('slug')->getValue();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,10 +71,9 @@ interface CreatePageInterface extends BaseCreatePageInterface
|
|||
public function specifyCode($code);
|
||||
|
||||
/**
|
||||
* @param string $permalink
|
||||
* @param string $languageCode
|
||||
* @param string $slug
|
||||
*/
|
||||
public function specifyPermalink($permalink, $languageCode);
|
||||
public function specifySlug($slug);
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Sylius\Behat\Page\Admin\Taxon;
|
||||
|
||||
use Behat\Mink\Driver\Selenium2Driver;
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Behat\Mink\Exception\ElementNotFoundException;
|
||||
use Sylius\Behat\Behaviour\ChecksCodeImmutability;
|
||||
|
|
@ -47,14 +48,16 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
|
|||
public function nameIt($name, $languageCode)
|
||||
{
|
||||
$this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_name', $languageCode), $name);
|
||||
|
||||
$this->waitForSlugGenerationIfNecessary();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function specifyPermalink($permalink, $languageCode)
|
||||
public function specifySlug($slug)
|
||||
{
|
||||
$this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_permalink', $languageCode), $permalink);
|
||||
$this->getDocument()->fillField('Slug', $slug);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -93,6 +96,14 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
|
|||
return false === stripos($pageText, '404 Not Found');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSlugReadOnly()
|
||||
{
|
||||
return 'readonly' === $this->getElement('slug')->getAttribute('readonly');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
@ -108,6 +119,11 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
|
|||
$imageElement->clickLink('Delete');
|
||||
}
|
||||
|
||||
public function enableSlugModification()
|
||||
{
|
||||
$this->getElement('toggle_taxon_slug_modification_button')->press();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
@ -194,7 +210,8 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
|
|||
'images' => '#sylius_taxon_images',
|
||||
'name' => '#sylius_taxon_translations_en_US_name',
|
||||
'parent' => '#sylius_taxon_parent',
|
||||
'permalink' => '#sylius_taxon_translations_en_US_permalink',
|
||||
'slug' => '#sylius_taxon_translations_en_US_slug',
|
||||
'toggle_taxon_slug_modification_button' => '#toggle-taxon-slug-modification',
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -246,4 +263,21 @@ class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
|
|||
|
||||
return $inputCode->getParent()->getParent()->getParent();
|
||||
}
|
||||
|
||||
private function waitForSlugGenerationIfNecessary()
|
||||
{
|
||||
if (!$this->getDriver() instanceof Selenium2Driver) {
|
||||
return;
|
||||
}
|
||||
|
||||
$slugElement = $this->getElement('slug');
|
||||
if ($slugElement->hasAttribute('readonly')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$value = $slugElement->getValue();
|
||||
$this->getDocument()->waitFor(1000, function () use ($slugElement, $value) {
|
||||
return $value !== $slugElement->getValue();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,10 +43,9 @@ interface UpdatePageInterface extends BaseUpdatePageInterface
|
|||
public function nameIt($name, $languageCode);
|
||||
|
||||
/**
|
||||
* @param string $permalink
|
||||
* @param string $languageCode
|
||||
* @param string $slug
|
||||
*/
|
||||
public function specifyPermalink($permalink, $languageCode);
|
||||
public function specifySlug($slug);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
|
|
@ -66,6 +65,11 @@ interface UpdatePageInterface extends BaseUpdatePageInterface
|
|||
*/
|
||||
public function isImageWithCodeDisplayed($code);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSlugReadOnly();
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
*/
|
||||
|
|
@ -73,6 +77,8 @@ interface UpdatePageInterface extends BaseUpdatePageInterface
|
|||
|
||||
public function removeFirstImage();
|
||||
|
||||
public function enableSlugModification();
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@
|
|||
<argument type="service" id="__symfony__.sylius.factory.taxon_image" />
|
||||
<argument type="service" id="__symfony__.doctrine.orm.entity_manager" />
|
||||
<argument type="service" id="__symfony__.sylius.image_uploader" />
|
||||
<argument type="service" id="__symfony__.sylius.generator.taxon_slug" />
|
||||
<argument>%__behat__.mink.parameters%</argument>
|
||||
<tag name="fob.context_service" />
|
||||
</service>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
sylius_admin_api_taxon:
|
||||
resource: "@SyliusAdminBundle/Resources/config/routing/api/taxon.yml"
|
||||
prefix: /taxons
|
||||
|
||||
sylius_admin_api_product:
|
||||
resource: "@SyliusAdminBundle/Resources/config/routing/api/product.yml"
|
||||
prefix: /products
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
sylius_admin_api_generate_taxon_slug:
|
||||
path: /generate-slug/
|
||||
methods: [GET]
|
||||
defaults:
|
||||
_controller: sylius.controller.taxon_slug:generateAction
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
$(document).ready(function() {
|
||||
var timeout;
|
||||
|
||||
$('[name*="sylius_taxon[translations]"][name*="[name]"]').on('input', function() {
|
||||
clearTimeout(timeout);
|
||||
$element = $(this);
|
||||
|
||||
timeout = setTimeout(function() {
|
||||
updateSlug($element);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
$('#toggle-taxon-slug-modification').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggleSlugModification($(this), $(this).siblings('input'));
|
||||
});
|
||||
});
|
||||
|
||||
function updateSlug($element) {
|
||||
$slugInput = $element.parents('.content').find('[name*="[slug]"]');
|
||||
$loadableParent = $slugInput.parents('.field.loadable');
|
||||
|
||||
if ('readonly' == $slugInput.attr('readonly')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$loadableParent.addClass('loading');
|
||||
|
||||
if ('' != $slugInput.attr('data-parent') && undefined != $slugInput.attr('data-parent')) {
|
||||
$data = { name: $element.val(), parentId: $slugInput.attr('data-parent') };
|
||||
} else if ($('#sylius_taxon_parent').length > 0 && $('#sylius_taxon_parent').is(':visible') && '' != $('#sylius_taxon_parent').val()) {
|
||||
$data = { name: $element.val(), parentId: $('#sylius_taxon_parent').val() };
|
||||
} else {
|
||||
$data = { name: $element.val() };
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: $slugInput.attr('data-url'),
|
||||
data: $data,
|
||||
dataType: "json",
|
||||
accept: "application/json",
|
||||
success: function(data) {
|
||||
$slugInput.val(data.slug);
|
||||
if ($slugInput.parents('.field').hasClass('error')) {
|
||||
$slugInput.parents('.field').removeClass('error');
|
||||
$slugInput.parents('.field').find('.sylius-validation-error').remove();
|
||||
}
|
||||
$loadableParent.removeClass('loading');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function toggleSlugModification($button, $slugInput) {
|
||||
if ($slugInput.attr('readonly')) {
|
||||
$slugInput.removeAttr('readonly');
|
||||
$button.html('<i class="unlock icon"></i>');
|
||||
} else {
|
||||
$slugInput.attr('readonly', 'readonly');
|
||||
$button.html('<i class="lock icon"></i>');
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
<div class="ui action input">
|
||||
{{ form_widget(slugField, {'attr': {'readonly': 'readonly', 'data-url': path('sylius_admin_api_generate_product_slug')}}) }}
|
||||
<span id="toggle-slug-modification" class="ui icon button">
|
||||
<i class="lock icon"></i>
|
||||
<i class="unlock icon"></i>
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
</div>
|
||||
<div class="content{% if 0 == loop.index0 %} active{% endif %}">
|
||||
{{ form_row(translationForm.name) }}
|
||||
{{ form_row(translationForm.permalink) }}
|
||||
{% include '@SyliusAdmin/Taxon/_slugField.html.twig' with { 'slugField': translationForm.slug } %}
|
||||
{{ form_row(translationForm.description) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
<div class="{% if slugField.vars.required %}required {% endif %}field{% if slugField.vars.errors|length > 0 %} error{% endif %} ui loadable form">
|
||||
{{ form_label(slugField) }}
|
||||
{% if taxon.slug == null %}
|
||||
{{ form_widget(slugField, {'attr': {'data-url': path('sylius_admin_api_generate_taxon_slug'), 'data-parent': app.request.attributes.get('id')}}) }}
|
||||
{% else %}
|
||||
<div class="ui action input">
|
||||
{{ form_widget(slugField, {'attr': {'readonly': 'readonly', 'data-url': path('sylius_admin_api_generate_taxon_slug')}}) }}
|
||||
<span id="toggle-taxon-slug-modification" class="ui icon button">
|
||||
<i class="lock icon"></i>
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ form_errors(slugField) }}
|
||||
</div>
|
||||
|
|
@ -17,6 +17,7 @@ use Sylius\Component\Core\Model\TaxonInterface;
|
|||
use Sylius\Component\Locale\Model\LocaleInterface;
|
||||
use Sylius\Component\Resource\Factory\FactoryInterface;
|
||||
use Sylius\Component\Resource\Repository\RepositoryInterface;
|
||||
use Sylius\Component\Taxonomy\Generator\TaxonSlugGeneratorInterface;
|
||||
use Sylius\Component\Taxonomy\Repository\TaxonRepositoryInterface;
|
||||
use Symfony\Component\OptionsResolver\Options;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
|
@ -46,6 +47,11 @@ final class TaxonExampleFactory implements ExampleFactoryInterface
|
|||
*/
|
||||
private $faker;
|
||||
|
||||
/**
|
||||
* @var TaxonSlugGeneratorInterface
|
||||
*/
|
||||
private $taxonSlugGenerator;
|
||||
|
||||
/**
|
||||
* @var OptionsResolver
|
||||
*/
|
||||
|
|
@ -56,16 +62,19 @@ final class TaxonExampleFactory implements ExampleFactoryInterface
|
|||
* @param TaxonRepositoryInterface $taxonRepository
|
||||
* @param ObjectManager $taxonManager
|
||||
* @param RepositoryInterface $localeRepository
|
||||
* @param TaxonSlugGeneratorInterface $taxonSlugGenerator
|
||||
*/
|
||||
public function __construct(
|
||||
FactoryInterface $taxonFactory,
|
||||
TaxonRepositoryInterface $taxonRepository,
|
||||
ObjectManager $taxonManager,
|
||||
RepositoryInterface $localeRepository
|
||||
RepositoryInterface $localeRepository,
|
||||
TaxonSlugGeneratorInterface $taxonSlugGenerator
|
||||
) {
|
||||
$this->taxonFactory = $taxonFactory;
|
||||
$this->taxonRepository = $taxonRepository;
|
||||
$this->localeRepository = $localeRepository;
|
||||
$this->taxonSlugGenerator = $taxonSlugGenerator;
|
||||
|
||||
$this->faker = \Faker\Factory::create();
|
||||
$this->optionsResolver =
|
||||
|
|
@ -106,6 +115,7 @@ final class TaxonExampleFactory implements ExampleFactoryInterface
|
|||
|
||||
$taxon->setName($options['name']);
|
||||
$taxon->setDescription($options['description']);
|
||||
$taxon->setSlug($this->taxonSlugGenerator->generate($options['name']));
|
||||
}
|
||||
|
||||
foreach ($options['children'] as $childOptions) {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@
|
|||
<argument type="service" id="sylius.repository.taxon" />
|
||||
<argument type="service" id="sylius.manager.taxon" />
|
||||
<argument type="service" id="sylius.repository.locale" />
|
||||
<argument type="service" id="sylius.generator.taxon_slug" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.fixture.example_factory.product" class="Sylius\Bundle\CoreBundle\Fixture\Factory\ProductExampleFactory">
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
# (c) Paweł Jędrzejewski
|
||||
|
||||
sylius_shop_taxon_show:
|
||||
path: /taxons/{permalink}
|
||||
path: /taxons/{slug}
|
||||
methods: [GET]
|
||||
defaults:
|
||||
_controller: sylius.controller.taxon:showAction
|
||||
_sylius:
|
||||
template: SyliusShopBundle:Taxon:show.html.twig
|
||||
repository:
|
||||
method: findOneByPermalink
|
||||
arguments: [$permalink]
|
||||
method: findOneBySlug
|
||||
arguments: [$slug]
|
||||
requirements:
|
||||
permalink: .+
|
||||
slug: .+
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
{{ sylius_grid_render_filter(products, filter) }}
|
||||
{% endfor %}
|
||||
<button type="submit" class="ui primary icon labeled button"><i class="search icon"></i> {{ 'sylius.ui.search'|trans }}</button>
|
||||
<a href="{{ path('sylius_shop_taxon_show', { 'permalink': app.request.query.get('permalink') }) }}" class="ui negative icon labeled button">
|
||||
<a href="{{ path('sylius_shop_taxon_show', { 'slug': app.request.query.get('slug') }) }}" class="ui negative icon labeled button">
|
||||
<i class="cancel icon"></i> {{ 'sylius.ui.clear'|trans }}
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{% set definition = resources.definition %}
|
||||
|
||||
{% set oldest_first_path = path('sylius_shop_taxon_show', {'sorting': {'createdAt': 'asc'}, 'permalink': resources.parameters.get('permalink')}) %}
|
||||
{% set newest_first_path = path('sylius_shop_taxon_show', {'sorting': {'createdAt': 'desc'}, 'permalink': resources.parameters.get('permalink')}) %}
|
||||
{% set oldest_first_path = path('sylius_shop_taxon_show', {'sorting': {'createdAt': 'asc'}, 'slug': resources.parameters.get('slug')}) %}
|
||||
{% set newest_first_path = path('sylius_shop_taxon_show', {'sorting': {'createdAt': 'desc'}, 'slug': resources.parameters.get('slug')}) %}
|
||||
|
||||
{% if app.request.query.get('sorting') is empty or app.request.basePath == newest_first_path %}
|
||||
{% set current_sorting_label = 'sylius.ui.newest_first'|trans|lower %}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
{% set parents = taxon.parents|reverse %}
|
||||
|
||||
{% for parent in parents %}
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'permalink': parent.permalink}) }}" class="section">{{ parent.name }}</a>
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'slug': parent.slug}) }}" class="section">{{ parent.name }}</a>
|
||||
<div class="divider"> / </div>
|
||||
{% endfor %}
|
||||
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'permalink': taxon.permalink}) }}" class="section">{{ taxon.name }}</a>
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'slug': taxon.slug}) }}" class="section">{{ taxon.name }}</a>
|
||||
<div class="divider"> / </div>
|
||||
{% endif %}
|
||||
<div class="section">{{ product.name }}</div>
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
{% set parents = taxon.parents|reverse %}
|
||||
|
||||
{% for parent in parents %}
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'permalink': parent.permalink}) }}" class="section">{{ parent.name }}</a>
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'slug': parent.slug}) }}" class="section">{{ parent.name }}</a>
|
||||
<div class="divider"> / </div>
|
||||
{% endfor %}
|
||||
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'permalink': taxon.permalink}) }}" class="section">{{ taxon.name }}</a>
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'slug': taxon.slug}) }}" class="section">{{ taxon.name }}</a>
|
||||
<div class="divider"> / </div>
|
||||
{% endif %}
|
||||
<div class="active section">{{ product.name }}</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<a href="{{ path('sylius_shop_homepage') }}" class="section">{{ 'sylius.ui.home'|trans }}</a>
|
||||
<div class="divider"> / </div>
|
||||
{% for parent in parents %}
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'permalink': parent.permalink}) }}" class="section">{{ parent.name }}</a>
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'slug': parent.slug}) }}" class="section">{{ parent.name }}</a>
|
||||
<div class="divider"> / </div>
|
||||
{% endfor %}
|
||||
<div class="active section">{{ taxon.name }}</div>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<div class="ui fluid vertical menu">
|
||||
<div class="header item">{{ taxon.name }}</div>
|
||||
{% if taxon.parent is not empty %}
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'permalink': taxon.parent.permalink}) }}" class="item">
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'slug': taxon.parent.slug}) }}" class="item">
|
||||
<i class="up arrow icon"></i> {{ 'sylius.ui.go_level_up'|trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% for child in taxon.children %}
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'permalink': child.permalink}) }}" class="item">{{ child.name }}</a>
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'slug': child.slug}) }}" class="item">{{ child.name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'permalink': taxon.permalink}) }}" class="item">{{ taxon.name }}</a>
|
||||
<a href="{{ path('sylius_shop_taxon_show', {'slug': taxon.slug}) }}" class="item">{{ taxon.name }}</a>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
{
|
||||
'code': taxon.code,
|
||||
'template': '@SyliusShop/Product/Grid/_default.html.twig',
|
||||
'permalink': app.request.attributes.get('permalink'),
|
||||
'slug': app.request.attributes.get('slug'),
|
||||
'sorting': app.request.query.get('sorting'),
|
||||
'criteria': app.request.query.get('criteria')
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -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\TaxonomyBundle\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
|
||||
*/
|
||||
class TaxonSlugController extends Controller
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function generateAction(Request $request)
|
||||
{
|
||||
$name = $request->query->get('name');
|
||||
$parentId = $request->query->get('parentId');
|
||||
|
||||
return new JsonResponse([
|
||||
'slug' => $this->get('sylius.generator.taxon_slug')->generate($name, $parentId),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -93,13 +93,13 @@ class TaxonRepository extends EntityRepository implements TaxonRepositoryInterfa
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function findOneByPermalink($permalink)
|
||||
public function findOneBySlug($slug)
|
||||
{
|
||||
return $this->createQueryBuilder('o')
|
||||
->addSelect('translation')
|
||||
->leftJoin('o.translations', 'translation')
|
||||
->where('translation.permalink = :permalink')
|
||||
->setParameter('permalink', $permalink)
|
||||
->where('translation.slug = :slug')
|
||||
->setParameter('slug', $slug)
|
||||
->orderBy('o.position')
|
||||
->getQuery()
|
||||
->getOneOrNullResult()
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@ class TaxonTranslationType extends AbstractResourceType
|
|||
->add('name', 'text', [
|
||||
'label' => 'sylius.form.taxon.name',
|
||||
])
|
||||
->add('permalink', 'text', [
|
||||
'required' => false,
|
||||
'label' => 'sylius.form.taxon.permalink',
|
||||
->add('slug', 'text', [
|
||||
'label' => 'sylius.form.taxon.slug',
|
||||
])
|
||||
->add('description', 'textarea', [
|
||||
'required' => false,
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@
|
|||
<field name="slug" column="slug" type="string" unique="true">
|
||||
<gedmo:slug fields="name" unique="true" />
|
||||
</field>
|
||||
<field name="permalink" column="permalink" type="string" unique="true">
|
||||
<gedmo:slug fields="name" unique="true" />
|
||||
</field>
|
||||
<field name="description" column="description" type="string" />
|
||||
<field name="left" column="tree_left" type="int">
|
||||
<gedmo:tree-left />
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
-->
|
||||
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-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">
|
||||
|
|
@ -22,24 +21,10 @@
|
|||
<generator strategy="AUTO" />
|
||||
</id>
|
||||
<field name="name" column="name" type="string" />
|
||||
<field name="slug" column="slug" type="string" unique="false">
|
||||
<gedmo:slug fields="name" unique="false" />
|
||||
</field>
|
||||
<field name="permalink" column="permalink" type="string" unique="false">
|
||||
<gedmo:slug fields="name" unique="false" >
|
||||
<gedmo:handler class="Sylius\Bundle\ResourceBundle\GedmoHandler\TranslationSlugHandler">
|
||||
<gedmo:handler-option name="relationField" value="translatable"/>
|
||||
<gedmo:handler-option name="relationParentRelationField" value="parent"/>
|
||||
<gedmo:handler-option name="parentFieldMethod" value="getPermalink"/>
|
||||
<gedmo:handler-option name="locale" value="locale"/>
|
||||
<gedmo:handler-option name="translate" value="translate"/>
|
||||
<gedmo:handler-option name="separator" value="/"/>
|
||||
</gedmo:handler>
|
||||
</gedmo:slug>
|
||||
</field>
|
||||
<field name="slug" column="slug" type="string" unique="false" />
|
||||
<field name="description" column="description" type="text" nullable="true" />
|
||||
<unique-constraints>
|
||||
<unique-constraint columns="locale,permalink" name="permalink_uidx" />
|
||||
<unique-constraint columns="locale,slug" name="slug_uidx" />
|
||||
</unique-constraints>
|
||||
</mapped-superclass>
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,12 @@
|
|||
|
||||
<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">
|
||||
<services>
|
||||
<service id="sylius.controller.taxon_slug" class="Sylius\Bundle\TaxonomyBundle\Controller\TaxonSlugController">
|
||||
<call method="setContainer">
|
||||
<argument type="service" id="service_container" />
|
||||
</call>
|
||||
</service>
|
||||
|
||||
<service id="sylius.form.type.taxon_choice" class="Sylius\Bundle\TaxonomyBundle\Form\Type\TaxonChoiceType">
|
||||
<argument type="service" id="sylius.repository.taxon" />
|
||||
<tag name="form.type" alias="sylius_taxon_choice" />
|
||||
|
|
@ -27,5 +33,9 @@
|
|||
decorates="sylius.factory.taxon" public="false">
|
||||
<argument type="service" id="sylius.factory.taxon.decorated.inner" />
|
||||
</service>
|
||||
|
||||
<service id="sylius.generator.taxon_slug" class="Sylius\Component\Taxonomy\Generator\TaxonSlugGenerator">
|
||||
<argument type="service" id="sylius.repository.taxon" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@
|
|||
</property>
|
||||
<constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
|
||||
<option name="fields">
|
||||
<value>locale</value>
|
||||
<value>permalink</value>
|
||||
<value>locale</value>
|
||||
<value>slug</value>
|
||||
</option>
|
||||
<option name="message">sylius.permalink.unique</option>
|
||||
<option name="message">sylius.slug.unique</option>
|
||||
<option name="groups">sylius</option>
|
||||
</constraint>
|
||||
</class>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ sylius:
|
|||
description: Description
|
||||
name: Name
|
||||
parent: Parent
|
||||
permalink: Permalink
|
||||
slug: Slug
|
||||
taxonomy:
|
||||
name: Name
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ final class TaxonTranslationTypeSpec extends ObjectBehavior
|
|||
;
|
||||
|
||||
$builder
|
||||
->add('permalink', 'text', Argument::any())
|
||||
->add('slug', 'text', Argument::any())
|
||||
->shouldBeCalled()
|
||||
->willReturn($builder)
|
||||
;
|
||||
|
|
|
|||
|
|
@ -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\Taxonomy\Generator;
|
||||
|
||||
use Behat\Transliterator\Transliterator;
|
||||
use Sylius\Component\Taxonomy\Model\TaxonInterface;
|
||||
use Sylius\Component\Taxonomy\Repository\TaxonRepositoryInterface;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
/**
|
||||
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
|
||||
*/
|
||||
final class TaxonSlugGenerator implements TaxonSlugGeneratorInterface
|
||||
{
|
||||
const SLUG_SEPARATOR = '/';
|
||||
|
||||
/**
|
||||
* @var TaxonRepositoryInterface
|
||||
*/
|
||||
private $taxonRepository;
|
||||
|
||||
/**
|
||||
* @param TaxonRepositoryInterface $taxonRepository
|
||||
*/
|
||||
public function __construct(TaxonRepositoryInterface $taxonRepository)
|
||||
{
|
||||
$this->taxonRepository = $taxonRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate($name, $parentId = null)
|
||||
{
|
||||
$taxonSlug = Transliterator::transliterate($name);
|
||||
if (null === $parentId) {
|
||||
return $taxonSlug;
|
||||
}
|
||||
|
||||
/** @var TaxonInterface $parent */
|
||||
$parent = $this->taxonRepository->find($parentId);
|
||||
Assert::notNull($parent, sprintf('There is no parent taxon with id %d.', $parentId));
|
||||
|
||||
return $parent->getSlug().self::SLUG_SEPARATOR.$taxonSlug;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?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\Taxonomy\Generator;
|
||||
|
||||
/**
|
||||
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
|
||||
*/
|
||||
interface TaxonSlugGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
* @param int|null $parentId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate($name, $parentId = null);
|
||||
}
|
||||
|
|
@ -236,34 +236,6 @@ class Taxon implements TaxonInterface
|
|||
$this->translate()->setSlug($slug);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPermalink()
|
||||
{
|
||||
$permalink = $this->translate()->getPermalink();
|
||||
|
||||
if (null !== $permalink) {
|
||||
return $permalink;
|
||||
}
|
||||
|
||||
if (null === $this->parent) {
|
||||
return $this->getSlug();
|
||||
}
|
||||
|
||||
$this->setPermalink($permalink = $this->parent->getPermalink().'/'.$this->getSlug());
|
||||
|
||||
return $permalink;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPermalink($permalink)
|
||||
{
|
||||
$this->translate()->setPermalink($permalink);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,11 +33,6 @@ class TaxonTranslation extends AbstractTranslation implements TaxonTranslationIn
|
|||
*/
|
||||
protected $slug;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $permalink;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -91,22 +86,6 @@ class TaxonTranslation extends AbstractTranslation implements TaxonTranslationIn
|
|||
$this->slug = $slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPermalink()
|
||||
{
|
||||
return $this->permalink;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPermalink($permalink)
|
||||
{
|
||||
$this->permalink = $permalink;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -29,16 +29,6 @@ interface TaxonTranslationInterface extends SlugAwareInterface, ResourceInterfac
|
|||
*/
|
||||
public function setName($name);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPermalink();
|
||||
|
||||
/**
|
||||
* @param string $permalink
|
||||
*/
|
||||
public function setPermalink($permalink);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ interface TaxonRepositoryInterface extends RepositoryInterface
|
|||
public function findNodesTreeSorted();
|
||||
|
||||
/**
|
||||
* @param string $permalink
|
||||
* @param string $slug
|
||||
*
|
||||
* @return TaxonInterface|null
|
||||
*/
|
||||
public function findOneByPermalink($permalink);
|
||||
public function findOneBySlug($slug);
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@
|
|||
"require": {
|
||||
"php": "^5.6|^7.0",
|
||||
|
||||
"sylius/resource": "^1.0"
|
||||
"behat/transliterator": "^1.1",
|
||||
"sylius/resource": "^1.0",
|
||||
"webmozart/assert": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^3.1"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
<?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\Taxonomy\Generator;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Component\Taxonomy\Generator\TaxonSlugGenerator;
|
||||
use Sylius\Component\Taxonomy\Generator\TaxonSlugGeneratorInterface;
|
||||
use Sylius\Component\Taxonomy\Model\TaxonInterface;
|
||||
use Sylius\Component\Taxonomy\Repository\TaxonRepositoryInterface;
|
||||
|
||||
/**
|
||||
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
|
||||
*/
|
||||
final class TaxonSlugGeneratorSpec extends ObjectBehavior
|
||||
{
|
||||
function let(TaxonRepositoryInterface $taxonRepository)
|
||||
{
|
||||
$this->beConstructedWith($taxonRepository);
|
||||
}
|
||||
|
||||
function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType(TaxonSlugGenerator::class);
|
||||
}
|
||||
|
||||
function it_implements_taxon_slug_generator_interface()
|
||||
{
|
||||
$this->shouldImplement(TaxonSlugGeneratorInterface::class);
|
||||
}
|
||||
|
||||
function it_generates_slug_based_on_new_taxon_name_and_parent_taxon_slug(
|
||||
TaxonInterface $parent,
|
||||
TaxonRepositoryInterface $taxonRepository
|
||||
) {
|
||||
$taxonRepository->find(1)->willReturn($parent);
|
||||
$parent->getSlug()->willReturn('board-games');
|
||||
|
||||
$this->generate('Battle games', 1)->shouldReturn('board-games/battle-games');;
|
||||
}
|
||||
|
||||
function it_generates_slug_based_on_new_taxon_name_if_this_taxon_has_no_parent()
|
||||
{
|
||||
$this->generate('Board games')->shouldReturn('board-games');;
|
||||
}
|
||||
|
||||
function it_throws_exception_if_parent_taxon_with_given_id_does_not_exist(
|
||||
TaxonRepositoryInterface $taxonRepository
|
||||
) {
|
||||
$taxonRepository->find(1)->willReturn(null);
|
||||
|
||||
$this
|
||||
->shouldThrow(new \InvalidArgumentException('There is no parent taxon with id 1.'))
|
||||
->during('generate', ['Battle games', 1])
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -147,17 +147,6 @@ final class TaxonSpec extends ObjectBehavior
|
|||
$this->getSlug()->shouldReturn('t-shirts');
|
||||
}
|
||||
|
||||
function it_has_no_permalink_by_default()
|
||||
{
|
||||
$this->getPermalink()->shouldReturn(null);
|
||||
}
|
||||
|
||||
function its_permalink_is_mutable()
|
||||
{
|
||||
$this->setPermalink('woman-clothing');
|
||||
$this->getPermalink()->shouldReturn('woman-clothing');
|
||||
}
|
||||
|
||||
function it_initializes_child_taxon_collection_by_default()
|
||||
{
|
||||
$this->getChildren()->shouldHaveType(Collection::class);
|
||||
|
|
|
|||
|
|
@ -73,15 +73,4 @@ final class TaxonTranslationSpec extends ObjectBehavior
|
|||
$this->setSlug('t-shirts');
|
||||
$this->getSlug()->shouldReturn('t-shirts');
|
||||
}
|
||||
|
||||
function it_has_no_permalink_by_default()
|
||||
{
|
||||
$this->getPermalink()->shouldReturn(null);
|
||||
}
|
||||
|
||||
function its_permalink_is_mutable()
|
||||
{
|
||||
$this->setPermalink('woman-clothing');
|
||||
$this->getPermalink()->shouldReturn('woman-clothing');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue