Skip to content

Commit

Permalink
Merge pull request #36 from maximehuran/feature/slug-selector
Browse files Browse the repository at this point in the history
Add slug selector in modal to simplify URL field completion
  • Loading branch information
maximehuran authored Apr 10, 2024
2 parents be873bf + f4e034a commit cbeb767
Show file tree
Hide file tree
Showing 36 changed files with 744 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ test.container: ## Lint the symfony container
${CONSOLE} lint:container

test.yaml: ## Lint the symfony Yaml files
${CONSOLE} lint:yaml ../../recipes ../../src/Resources/config
${CONSOLE} lint:yaml ../../recipes ../../src/Resources/config --parse-tags

test.schema: ## Validate MySQL Schema
${CONSOLE} doctrine:schema:validate
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ Then create the config file in `config/packages/monsieurbiz_sylius_menu_plugin.y
```yaml
imports:
- { resource: "@MonsieurBizSyliusMenuPlugin/Resources/config/config.yaml" }

twig:
form_themes: ['@MonsieurBizSyliusMenuPlugin/Admin/Browser/Form/_theme.html.twig']
```
Finally import the routes in `config/routes/monsieurbiz_sylius_menu_plugin.yaml`:

Expand All @@ -49,6 +52,15 @@ bin/console doctrine:migrations:migrate

If you want to customize your menu, like adding an image, do so by overriding the MenuItem entity (more info about [overriding entities in the Sylius documentation](https://docs.sylius.com/en/1.9/customization/model.html)).

## Add URL Provider

The URLs selector allows you to select a URL from a list of URLs.
It provides URLs for :
- Taxons
- Products

You can add your customer Provider by creating a class which implements the `MonsieurBiz\SyliusMenuPlugin\Provider\UrlProviderInterface` .interface.

## Menu example

### Admin form index
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"require": "^4.4"
},
"branch-alias": {
"dev-master": "1.0-dev"
"dev-master": "1.3-dev"
}
},
"config": {
Expand Down
3 changes: 3 additions & 0 deletions dist/config/packages/monsieurbiz_sylius_menu_plugin.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
imports:
- { resource: "@MonsieurBizSyliusMenuPlugin/Resources/config/config.yaml" }

twig:
form_themes: ['@MonsieurBizSyliusMenuPlugin/Admin/Browser/Form/_theme.html.twig']
Empty file removed recipes/.gitignore
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
imports:
- { resource: "@MonsieurBizSyliusMenuPlugin/Resources/config/config.yaml" }

twig:
form_themes: ['@MonsieurBizSyliusMenuPlugin/Admin/Browser/Form/_theme.html.twig']
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
monsieurbiz_menu_admin_menu:
resource: "@MonsieurBizSyliusMenuPlugin/Resources/config/routes/admin.yaml"
prefix: /%sylius_admin.path_name%
10 changes: 10 additions & 0 deletions recipes/1.3-dev/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"bundles": {
"MonsieurBiz\\SyliusMenuPlugin\\MonsieurBizSyliusMenuPlugin": [
"all"
]
},
"copy-from-recipe": {
"config/": "%CONFIG_DIR%/"
}
}
66 changes: 66 additions & 0 deletions src/Controller/BrowserController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

/*
* This file is part of Monsieur Biz' Menu plugin for Sylius.
*
* (c) Monsieur Biz <[email protected]>
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace MonsieurBiz\SyliusMenuPlugin\Controller;

use MonsieurBiz\SyliusMenuPlugin\Provider\BrowsableObjectProviderInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

final class BrowserController extends AbstractController
{
public function __construct(
private BrowsableObjectProviderInterface $browsableObjectProvider
) {
}

public function listAction(
Request $request,
): ?Response {
$inputName = (string) $request->query->get('inputName', '');
$inputValue = (string) $request->query->get('inputValue', '');
$locale = (string) $request->query->get('locale', '');

return $this->render('@MonsieurBizSyliusMenuPlugin/Admin/Browser/_modal.html.twig', [
'urlProviders' => $this->browsableObjectProvider->getUrlProviders(),
'inputName' => $inputName,
'inputValue' => $inputValue,
'locale' => $locale,
]);
}

public function listItemsAction(
Request $request,
): ?Response {
$providerCode = (string) $request->query->get('providerCode', '');
$inputName = (string) $request->query->get('inputName', '');
$inputValue = (string) $request->query->get('inputValue', '');
$locale = (string) $request->query->get('locale', '');
$search = (string) $request->query->get('search', '');

$urlProvider = $this->browsableObjectProvider->findProviderByCode($providerCode);
if (null === $urlProvider) {
return new JsonResponse(['error' => 'URL Provider not found'], 404);
}

return $this->render('@MonsieurBizSyliusMenuPlugin/Admin/Browser/_modal.html.twig', [
'urlProvider' => $urlProvider,
'inputName' => $inputName,
'inputValue' => $inputValue,
'locale' => $locale,
'search' => $search,
]);
}
}
2 changes: 2 additions & 0 deletions src/DependencyInjection/MonsieurBizSyliusMenuExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace MonsieurBiz\SyliusMenuPlugin\DependencyInjection;

use MonsieurBiz\SyliusMenuPlugin\Provider\UrlProviderInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
Expand All @@ -28,6 +29,7 @@ public function load(array $config, ContainerBuilder $container): void
{
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yaml');
$container->registerForAutoconfiguration(UrlProviderInterface::class)->addTag('monsieurbiz_menu.url_provider');
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Form/Type/MenuItemTranslationType.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
->add('label', TextType::class, [
'label' => 'monsieurbiz_menu.ui.label',
])
->add('url', TextType::class, [
->add('url', UrlType::class, [
'required' => false,
'label' => 'monsieurbiz_menu.ui.url',
])
Expand Down
24 changes: 24 additions & 0 deletions src/Form/Type/UrlType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

/*
* This file is part of Monsieur Biz' Menu plugin for Sylius.
*
* (c) Monsieur Biz <[email protected]>
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace MonsieurBiz\SyliusMenuPlugin\Form\Type;

use Symfony\Component\Form\Extension\Core\Type\TextType;

final class UrlType extends TextType
{
public function getBlockPrefix(): string
{
return 'monsieurbiz_sylius_menu_url';
}
}
85 changes: 85 additions & 0 deletions src/Provider/AbstractUrlProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

/*
* This file is part of Monsieur Biz' Menu plugin for Sylius.
*
* (c) Monsieur Biz <[email protected]>
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace MonsieurBiz\SyliusMenuPlugin\Provider;

use Symfony\Component\Routing\RouterInterface;

abstract class AbstractUrlProvider implements UrlProviderInterface
{
protected int $maxResults = 1000;

protected string $code;

protected string $icon = 'angle right';

protected int $priority = 0;

protected array $items = [];

public function __construct(
protected RouterInterface $router
) {
}

public function getIcon(): string
{
return $this->icon;
}

public function getCode(): string
{
return $this->code;
}

public function getPriority(): int
{
return $this->priority;
}

public function getMaxResults(): int
{
return $this->maxResults;
}

protected function addItem(string $name, string $path): void
{
$this->items[] = [
'name' => $name,
'value' => $path,
];
}

protected function sortItems(): void
{
usort($this->items, fn ($itemA, $itemB) => $itemA['name'] <=> $itemB['name']);
}

abstract protected function getResults(string $locale, string $search = ''): iterable;

abstract protected function addItemFromResult(object $result, string $locale): void;

public function getItems(string $locale, string $search = ''): array
{
$this->items = [];
$results = $this->getResults($locale, $search);

foreach ($results as $result) {
$this->addItemFromResult($result, $locale);
}

$this->sortItems();

return $this->items;
}
}
45 changes: 45 additions & 0 deletions src/Provider/BrowsableObjectProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/*
* This file is part of Monsieur Biz' Menu plugin for Sylius.
*
* (c) Monsieur Biz <[email protected]>
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace MonsieurBiz\SyliusMenuPlugin\Provider;

class BrowsableObjectProvider implements BrowsableObjectProviderInterface
{
public function __construct(private iterable $urlProviders)
{
}

public function getUrlProviders(): array
{
$urlProviders = [];
foreach ($this->urlProviders as $urlProvider) {
$urlProviders[$urlProvider->getCode()] = $urlProvider;
}

uasort($urlProviders, fn ($urlProviderA, $urlProviderB) => $urlProviderB->getPriority() <=> $urlProviderA->getPriority());

return $urlProviders;
}

public function findProviderByCode(string $code): ?UrlProviderInterface
{
/** @var UrlProviderInterface $urlProvider */
foreach ($this->getUrlProviders() as $urlProvider) {
if ($urlProvider->getCode() === $code) {
return $urlProvider;
}
}

return null;
}
}
21 changes: 21 additions & 0 deletions src/Provider/BrowsableObjectProviderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

/*
* This file is part of Monsieur Biz' Menu plugin for Sylius.
*
* (c) Monsieur Biz <[email protected]>
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace MonsieurBiz\SyliusMenuPlugin\Provider;

interface BrowsableObjectProviderInterface
{
public function getUrlProviders(): array;

public function findProviderByCode(string $code): ?UrlProviderInterface;
}
Loading

0 comments on commit cbeb767

Please sign in to comment.