Skip to content

Commit

Permalink
feat(AdminRoutes): Allow to enabled some routes for admin through con…
Browse files Browse the repository at this point in the history
…figuration in BO
  • Loading branch information
Etienne Gutbub authored and maximehuran committed Aug 30, 2024
1 parent ea9dc54 commit 0f3fd31
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 13 deletions.
16 changes: 16 additions & 0 deletions src/Form/Type/Settings/NoCommerceType.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace MonsieurBiz\SyliusNoCommercePlugin\Form\Type\Settings;

use MonsieurBiz\SyliusNoCommercePlugin\Firewall\RegistryInterface;
use MonsieurBiz\SyliusNoCommercePlugin\Provider\FeaturesProvider;
use MonsieurBiz\SyliusSettingsPlugin\Form\AbstractSettingsType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
Expand Down Expand Up @@ -60,5 +61,20 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'multiple' => true,
'choices' => $choices,
]);
$this->addWithDefaultCheckbox($builder, 're_enabled_admin_routes', ChoiceType::class, [
'label' => 'monsieurbiz.nocommerce.ui.form.field.re_enabled_admin_routes.label',
'required' => false,
'multiple' => true,
'choices' => [
'sylius.ui.countries' => FeaturesProvider::COUNTRIES_KEY,
'sylius.ui.currencies' => FeaturesProvider::CURRENCIES_KEY,
'sylius.ui.inventory' => FeaturesProvider::INVENTORY_KEY,
'sylius.ui.payment' => FeaturesProvider::PAYMENT_KEY,
'sylius.menu.admin.main.catalog.header' => FeaturesProvider::CATALOG_KEY,
'sylius.ui.shipping' => FeaturesProvider::SHIPPING_KEY,
'sylius.ui.tax' => FeaturesProvider::TAX_KEY,
'sylius.ui.zones' => FeaturesProvider::ZONES_KEY,
],
]);
}
}
2 changes: 1 addition & 1 deletion src/Kernel/SyliusNoCommerceKernelTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public function loadRoutes(LoaderInterface $loader): RouteCollection
foreach ($collection as $name => $route) {
foreach ($routesToRemove as $routeToRemove) {
if (false !== strpos($name, $routeToRemove)) {
$route->setCondition('not context.checkNoCommerce()');
$route->setCondition('not context.checkNoCommerce(params)');
}
}
}
Expand Down
64 changes: 55 additions & 9 deletions src/Menu/AdminMenuListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public function __invoke(MenuBuilderEvent $event): void
}

$menu->removeChild('sales');
$menu->removeChild('catalog');

$this->handleCatalogMenu($menu);
$menu->removeChild('marketing');

if (!$this->config->areCustomersAllowed()) {
Expand All @@ -55,19 +56,64 @@ public function __invoke(MenuBuilderEvent $event): void

private function removeConfigurationChildren(ItemInterface $configuration): void
{
$configuration->removeChild('currencies');
$this->removeChildIfRoutesDisabled($configuration, 'currencies');

if (!$this->config->areZonesAllowed() && !$this->config->areCountriesAllowed()) {
$configuration->removeChild('countries');
$this->removeChildIfRoutesDisabled($configuration, 'countries');
}
if (!$this->config->areZonesAllowed()) {
$configuration->removeChild('zones');
$this->removeChildIfRoutesDisabled($configuration, 'zones');
}

$configuration->removeChild('exchange_rates');
$configuration->removeChild('payment_methods');
$configuration->removeChild('shipping_methods');
$configuration->removeChild('shipping_categories');
$configuration->removeChild('tax_categories');
$configuration->removeChild('tax_rates');
$this->removeChildIfRoutesDisabled($configuration, 'payment_methods');
$this->removeChildIfRoutesDisabled($configuration, 'shipping_methods');
$this->removeChildIfRoutesDisabled($configuration, 'shipping_categories');
$this->removeChildIfRoutesDisabled($configuration, 'tax_categories');
$this->removeChildIfRoutesDisabled($configuration, 'tax_rates');
}

/**
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
private function removeChildIfRoutesDisabled(ItemInterface $menu, string $menuName): void
{
$menuItem = $menu->getChild($menuName);
if (!$menuItem || null === $menuItem->getExtra('routes')) {
return;
}

foreach ($menuItem->getExtra('routes') as $route) {
if (!isset($route['route'])) {
continue;
}
// If one route does not match the forced enabled routes, we remove the menu item
if (!$this->featuresProvider->isRouteForcedEnabled(['_route' => $route['route']])) {
$menu->removeChild($menuName);
}
}
}

private function handleCatalogMenu(ItemInterface $menu): void
{
$catalogMenu = $menu->getChild('catalog');

if (null === $catalogMenu) {
return;
}

$this->removeChildIfRoutesDisabled($catalogMenu, 'taxons');
$this->removeChildIfRoutesDisabled($catalogMenu, 'products');
$this->removeChildIfRoutesDisabled($catalogMenu, 'inventory');
$this->removeChildIfRoutesDisabled($catalogMenu, 'attributes');
$this->removeChildIfRoutesDisabled($catalogMenu, 'options');
$this->removeChildIfRoutesDisabled($catalogMenu, 'association_types');

// We remove the catalog menu if it has no children
if ($catalogMenu->hasChildren()) {
return;
}

$menu->removeChild('catalog');
}
}
89 changes: 88 additions & 1 deletion src/Provider/FeaturesProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,60 @@

final class FeaturesProvider implements FeaturesProviderInterface
{
public const COUNTRIES_KEY = 'countries';

public const CURRENCIES_KEY = 'currencies';

public const INVENTORY_KEY = 'inventory';

public const PAYMENT_KEY = 'payment';

public const CATALOG_KEY = 'catalog';

public const SHIPPING_KEY = 'shipping';

public const TAX_KEY = 'tax';

public const ZONES_KEY = 'zones';

public const ADMIN_ROUTES_THAT_CAN_BE_RE_ENABLED = [
self::COUNTRIES_KEY => [
'sylius_admin_country',
'sylius_admin_ajax_render_province_form',
],
self::CURRENCIES_KEY => [
'sylius_admin_currency',
],
self::INVENTORY_KEY => [
'sylius_admin_inventory',
],
self::PAYMENT_KEY => [
'sylius_admin_payment_method',
],
self::CATALOG_KEY => [
'sylius_admin_get_attribute_types',
'sylius_admin_get_product_attributes',
'sylius_admin_render_attribute_forms',
'sylius_admin_product',
'sylius_admin_ajax_product',
'sylius_admin_partial_product',
'sylius_admin_ajax_generate_product_slug',
'sylius_admin_partial_taxon',
'sylius_admin_ajax_taxon',
'sylius_admin_taxon',
'sylius_admin_ajax_generate_taxon_slug',
],
self::SHIPPING_KEY => [
'sylius_admin_shipping',
],
self::TAX_KEY => [
'sylius_admin_tax_',
],
self::ZONES_KEY => [
'sylius_admin_zone',
],
];

private ChannelContextInterface $channelContext;

private SettingsInterface $nocommerceSettings;
Expand All @@ -38,7 +92,7 @@ public function isNoCommerceEnabledForChannel(?ChannelInterface $channel = null)
if (null === $channel) {
$channel = $this->channelContext->getChannel();
}
// In case we are getting a channel that does not exists yet we return null to have the channel set properly
// In case we are getting a channel that does not exist yet, we return null to have the channel set properly
if (null === $channel->getId()) {
return true;
}
Expand All @@ -48,4 +102,37 @@ public function isNoCommerceEnabledForChannel(?ChannelInterface $channel = null)

return (bool) $this->nocommerceSettings->getCurrentValue($channel, null, 'enabled');
}

/**
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function isRouteForcedEnabled(array $params = []): bool
{
if (!isset($params['_route'])) {
return false;
}

$route = $params['_route'];
$channel = $this->channelContext->getChannel();
/** @var ?array $reEnabledAdminRoutes */
$reEnabledAdminRoutes = $this->nocommerceSettings->getCurrentValue($channel, null, 're_enabled_admin_routes');

if (empty($reEnabledAdminRoutes)) {
return false;
}

// We are checking if we should re-enable the route
foreach ($reEnabledAdminRoutes as $reEnabledAdminSection) {
if (!isset(self::ADMIN_ROUTES_THAT_CAN_BE_RE_ENABLED[$reEnabledAdminSection])) {
continue;
}
foreach (self::ADMIN_ROUTES_THAT_CAN_BE_RE_ENABLED[$reEnabledAdminSection] as $reEnabledAdminRoute) {
if (false !== strpos($route, $reEnabledAdminRoute)) {
return true;
}
}
}

return false;
}
}
2 changes: 2 additions & 0 deletions src/Provider/FeaturesProviderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@
interface FeaturesProviderInterface
{
public function isNoCommerceEnabledForChannel(?ChannelInterface $channel = null): bool;

public function isRouteForcedEnabled(array $params = []): bool;
}
2 changes: 2 additions & 0 deletions src/Resources/translations/messages.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ monsieurbiz:
label: Firewalls to be disabled
enabled:
label: Enabled
re_enabled_admin_routes:
label: Admin routes to re-enable
2 changes: 2 additions & 0 deletions src/Resources/translations/messages.fr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ monsieurbiz:
label: Firewalls à désactiver
enabled:
label: Activer
re_enabled_admin_routes:
label: Routes à réactiver pour l'admin
4 changes: 2 additions & 2 deletions src/Routing/NoCommerceRequestContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ public function __construct(
$this->featuresProvider = $featuresProvider;
}

public function checkNoCommerce(): bool
public function checkNoCommerce(array $params = []): bool
{
return $this->featuresProvider->isNoCommerceEnabledForChannel();
return $this->featuresProvider->isNoCommerceEnabledForChannel() && !$this->featuresProvider->isRouteForcedEnabled($params);
}

/**
Expand Down

0 comments on commit 0f3fd31

Please sign in to comment.