Loading .cspell-project-words.txt +1 −0 Changes for .cspell-project-words.txt: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ produit Produits quickedit Sentier skus SLRL subelement templatecache Loading commerce.routing.yml +2 −0 Changes for commerce.routing.yml: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ commerce.inbox_message.read: _controller: '\Drupal\commerce\Controller\DashboardController::readInboxMessage' requirements: _permission: 'access commerce administration pages' _csrf_token: 'TRUE' commerce.inbox_message.dismiss: path: '/admin/commerce/inbox-message/{message_id}/dismiss' Loading @@ -44,3 +45,4 @@ commerce.inbox_message.dismiss: _controller: '\Drupal\commerce\Controller\DashboardController::dismissInboxMessage' requirements: _permission: 'access commerce administration pages' _csrf_token: 'TRUE' js/commerce.inbox.js +1 −3 Changes for js/commerce.inbox.js: 1 added line, 3 removed lines. Original line number Diff line number Diff line Loading @@ -10,9 +10,7 @@ message.classList.add('opened'); if (message.classList.contains('unread')) { Drupal.ajax({ url: Drupal.url( `admin/commerce/inbox-message/${message.dataset.messageId}/read` ), url: message.dataset.readUrl, }).execute(); } }); Loading modules/cart/src/EventSubscriber/QueryAccessSubscriber.php +6 −0 Changes for modules/cart/src/EventSubscriber/QueryAccessSubscriber.php: 6 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -52,6 +52,12 @@ class QueryAccessSubscriber implements EventSubscriberInterface { if ($account->isAnonymous()) { $completed_cart_ids = $this->cartSession->getCartIds(CartSessionInterface::COMPLETED); $cart_ids = array_merge($cart_ids, $completed_cart_ids); // Anonymous customers are identified by the cart IDs in their session, // and all of them share the same user ID. $conditions->addCacheContexts(['session']); } else { $conditions->addCacheContexts(['cart']); } if (!empty($cart_ids)) { Loading modules/cart/src/Hook/CommerceCartHooks.php +44 −2 Changes for modules/cart/src/Hook/CommerceCartHooks.php: 44 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\Routing\AdminContext; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AnonymousUserSession; use Drupal\Core\StringTranslation\StringTranslationTrait; Loading Loading @@ -47,6 +48,8 @@ class CommerceCartHooks { * The cart session. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager * The entity type manager. * @param \Drupal\Core\Routing\AdminContext $adminContext * The admin context. */ public function __construct( #[Autowire(service: 'commerce_cart.cron')] Loading @@ -57,6 +60,7 @@ class CommerceCartHooks { protected readonly OrderAssignmentInterface $orderAssignment, protected readonly CartSessionInterface $cartSession, protected readonly EntityTypeManagerInterface $entityTypeManager, protected readonly AdminContext $adminContext, ) {} /** Loading Loading @@ -111,7 +115,21 @@ class CommerceCartHooks { #[Hook('commerce_order_item_access')] public function commerceOrderItemAccess(OrderItemInterface $order_item, string $operation, AccountInterface $account): AccessResultInterface { $order = $order_item->getOrder(); return $order ? $this->orderAccess($order, $operation, $account) : AccessResult::neutral(); if (!$order) { return AccessResult::neutral(); } // The order is locked while the customer is on the payment step, and is // no longer refreshed. Changing its items then (e.g. the quantity or the // purchased entity) would leave the price, and the payment, out of date. if ($operation === 'update' && $order->isLocked()) { return AccessResult::neutral()->addCacheableDependency($order); } // Customers can't change locked order items (e.g. added by a promotion), // matching the cart form. if ($operation === 'update' && $order_item->isLocked()) { return AccessResult::neutral()->addCacheableDependency($order_item); } return $this->orderAccess($order, $operation, $account); } /** Loading @@ -119,6 +137,10 @@ class CommerceCartHooks { */ #[Hook('entity_type_build')] public function entityTypeBuild(array &$entity_types): void { // Only administrators can change whether an order is a cart. $restricted_fields = $entity_types['commerce_order']->get('restricted_fields') ?? []; $entity_types['commerce_order']->set('restricted_fields', array_merge($restricted_fields, ['cart'])); if ($this->moduleHandler->moduleExists('commerce_product')) { $entity_types['commerce_order_item']->setFormClass('add_to_cart', AddToCartForm::class); } Loading Loading @@ -328,6 +350,12 @@ class CommerceCartHooks { if ($operation !== 'view' && $operation !== 'update') { return AccessResult::neutral(); } // Customers can update their carts while shopping, but this must never // grant access to the admin pages (e.g. the order edit form), not even to // a customer who has access to the admin pages for other reasons. if ($operation === 'update' && $this->adminContext->isAdminRoute()) { return AccessResult::neutral()->addCacheContexts(['route.name']); } if ($account->isAuthenticated()) { $customer_check = $account->id() == $order->getCustomerId(); Loading @@ -340,14 +368,28 @@ class CommerceCartHooks { } $access_result = AccessResult::allowedIf($customer_check); if ($order->getState()->getId() === 'draft') { // Customers can only access draft orders that are carts. Other draft // orders (e.g. created by staff, or recurring orders) belong to the // merchant until they are placed. $access_result = $access_result->andIf(AccessResult::allowedIf((bool) $order->get('cart')->value)); } if ($operation === 'update') { $access_result = $access_result->andIf( AccessResult::allowedIf($order->getState()->getId() === 'draft'), ); // The update access depends on the route not being an admin route. $access_result->addCacheContexts(['route.name']); } return $access_result $access_result ->addCacheableDependency($order) ->cachePerUser(); if ($account->isAnonymous()) { // Anonymous customers are identified by the cart IDs in their session, // and all of them share the same user ID. $access_result->addCacheContexts(['session']); } return $access_result; } /** Loading Loading
.cspell-project-words.txt +1 −0 Changes for .cspell-project-words.txt: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ produit Produits quickedit Sentier skus SLRL subelement templatecache Loading
commerce.routing.yml +2 −0 Changes for commerce.routing.yml: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ commerce.inbox_message.read: _controller: '\Drupal\commerce\Controller\DashboardController::readInboxMessage' requirements: _permission: 'access commerce administration pages' _csrf_token: 'TRUE' commerce.inbox_message.dismiss: path: '/admin/commerce/inbox-message/{message_id}/dismiss' Loading @@ -44,3 +45,4 @@ commerce.inbox_message.dismiss: _controller: '\Drupal\commerce\Controller\DashboardController::dismissInboxMessage' requirements: _permission: 'access commerce administration pages' _csrf_token: 'TRUE'
js/commerce.inbox.js +1 −3 Changes for js/commerce.inbox.js: 1 added line, 3 removed lines. Original line number Diff line number Diff line Loading @@ -10,9 +10,7 @@ message.classList.add('opened'); if (message.classList.contains('unread')) { Drupal.ajax({ url: Drupal.url( `admin/commerce/inbox-message/${message.dataset.messageId}/read` ), url: message.dataset.readUrl, }).execute(); } }); Loading
modules/cart/src/EventSubscriber/QueryAccessSubscriber.php +6 −0 Changes for modules/cart/src/EventSubscriber/QueryAccessSubscriber.php: 6 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -52,6 +52,12 @@ class QueryAccessSubscriber implements EventSubscriberInterface { if ($account->isAnonymous()) { $completed_cart_ids = $this->cartSession->getCartIds(CartSessionInterface::COMPLETED); $cart_ids = array_merge($cart_ids, $completed_cart_ids); // Anonymous customers are identified by the cart IDs in their session, // and all of them share the same user ID. $conditions->addCacheContexts(['session']); } else { $conditions->addCacheContexts(['cart']); } if (!empty($cart_ids)) { Loading
modules/cart/src/Hook/CommerceCartHooks.php +44 −2 Changes for modules/cart/src/Hook/CommerceCartHooks.php: 44 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\Routing\AdminContext; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AnonymousUserSession; use Drupal\Core\StringTranslation\StringTranslationTrait; Loading Loading @@ -47,6 +48,8 @@ class CommerceCartHooks { * The cart session. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager * The entity type manager. * @param \Drupal\Core\Routing\AdminContext $adminContext * The admin context. */ public function __construct( #[Autowire(service: 'commerce_cart.cron')] Loading @@ -57,6 +60,7 @@ class CommerceCartHooks { protected readonly OrderAssignmentInterface $orderAssignment, protected readonly CartSessionInterface $cartSession, protected readonly EntityTypeManagerInterface $entityTypeManager, protected readonly AdminContext $adminContext, ) {} /** Loading Loading @@ -111,7 +115,21 @@ class CommerceCartHooks { #[Hook('commerce_order_item_access')] public function commerceOrderItemAccess(OrderItemInterface $order_item, string $operation, AccountInterface $account): AccessResultInterface { $order = $order_item->getOrder(); return $order ? $this->orderAccess($order, $operation, $account) : AccessResult::neutral(); if (!$order) { return AccessResult::neutral(); } // The order is locked while the customer is on the payment step, and is // no longer refreshed. Changing its items then (e.g. the quantity or the // purchased entity) would leave the price, and the payment, out of date. if ($operation === 'update' && $order->isLocked()) { return AccessResult::neutral()->addCacheableDependency($order); } // Customers can't change locked order items (e.g. added by a promotion), // matching the cart form. if ($operation === 'update' && $order_item->isLocked()) { return AccessResult::neutral()->addCacheableDependency($order_item); } return $this->orderAccess($order, $operation, $account); } /** Loading @@ -119,6 +137,10 @@ class CommerceCartHooks { */ #[Hook('entity_type_build')] public function entityTypeBuild(array &$entity_types): void { // Only administrators can change whether an order is a cart. $restricted_fields = $entity_types['commerce_order']->get('restricted_fields') ?? []; $entity_types['commerce_order']->set('restricted_fields', array_merge($restricted_fields, ['cart'])); if ($this->moduleHandler->moduleExists('commerce_product')) { $entity_types['commerce_order_item']->setFormClass('add_to_cart', AddToCartForm::class); } Loading Loading @@ -328,6 +350,12 @@ class CommerceCartHooks { if ($operation !== 'view' && $operation !== 'update') { return AccessResult::neutral(); } // Customers can update their carts while shopping, but this must never // grant access to the admin pages (e.g. the order edit form), not even to // a customer who has access to the admin pages for other reasons. if ($operation === 'update' && $this->adminContext->isAdminRoute()) { return AccessResult::neutral()->addCacheContexts(['route.name']); } if ($account->isAuthenticated()) { $customer_check = $account->id() == $order->getCustomerId(); Loading @@ -340,14 +368,28 @@ class CommerceCartHooks { } $access_result = AccessResult::allowedIf($customer_check); if ($order->getState()->getId() === 'draft') { // Customers can only access draft orders that are carts. Other draft // orders (e.g. created by staff, or recurring orders) belong to the // merchant until they are placed. $access_result = $access_result->andIf(AccessResult::allowedIf((bool) $order->get('cart')->value)); } if ($operation === 'update') { $access_result = $access_result->andIf( AccessResult::allowedIf($order->getState()->getId() === 'draft'), ); // The update access depends on the route not being an admin route. $access_result->addCacheContexts(['route.name']); } return $access_result $access_result ->addCacheableDependency($order) ->cachePerUser(); if ($account->isAnonymous()) { // Anonymous customers are identified by the cart IDs in their session, // and all of them share the same user ID. $access_result->addCacheContexts(['session']); } return $access_result; } /** Loading