Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to enabled some routes for admin through configuration in BO #37

Merged
merged 1 commit into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading