Problem/Motivation
Since 1.2.2, the module registers a "Clone" local task (commerce_quick_node_clone.node.quick_clone) on entity.commerce_product.canonical, with access controlled by a custom access callback:
commerce_quick_node_clone.node.quick_clone: path: '/clone/{node}/edit' defaults: _controller: '\Drupal\commerce_quick_node_clone\Controller\QuickNodeCloneNodeController::cloneNode' _title: 'Clone product' requirements: _custom_access: '\Drupal\commerce_quick_node_clone\Controller\QuickNodeCloneNodeAccess::cloneNode' options: _admin_route: TRUE parameters: node: type: entity:commerce_product
QuickNodeCloneNodeAccess::cloneNode(AccountInterface $account, $node) has no default value for $node. When Drupal's local task plugin manager (\Drupal\Core\Menu\LocalTaskManager) evaluates access for this local task plugin outside of an actual product route context — e.g. any code that calls getLocalTasks() / getTasksBuild() for the current route while browsing a route that has no node route parameter at all — ArgumentsResolver cannot resolve the $node argument and throws:
RuntimeException: Callable "Drupal\commerce_quick_node_clone\Controller\QuickNodeCloneNodeAccess::cloneNode" requires a value for the "$node" argument. in Drupal\Component\Utility\ArgumentsResolver->handleUnresolvedArgument() (line 149 of core/lib/Drupal/Component/Utility/ArgumentsResolver.php).This is the same failure mode already fixed upstream in the sibling module Quick Node Clone, see #3431222: RuntimeException: Callable QuickNodeCloneNodeAccess::cloneNode requires a value for the "$node" argument, where the accepted resolution was to give $node a default value of NULL. That fix was never carried over to this module.
Steps to reproduce
- Enable Commerce Quick Node Clone 1.2.2+ together with Commerce Product.
- As an authenticated user with permission to see the admin toolbar, trigger a build of the current route's local tasks through the local task plugin manager (
\Drupal::service('plugin.manager.menu.local_task')->getLocalTasks($route_name, 0)) while browsing any route other thanentity.commerce_product.canonical— for example from custom code that lists "current page" local tasks in a toolbar/admin menu. - The page returns a 500 with the RuntimeException above instead of simply omitting the "Clone" tab.
Proposed resolution
Give $node a default value of NULL in QuickNodeCloneNodeAccess::cloneNode(). The method body already handles a non-ProductInterface, non-scalar value correctly by falling through to AccessResult::forbidden(), so no other logic changes are required. Patch attached; a merge request with the same change is also linked once opened.
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | 3619289-commerce_quick_node_clone-cloneNode_default_node_argument.patch | 495 bytes | abarrio |
Issue fork commerce_quick_node_clone-3619289
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
abarrioCreated mr to fix the problem on cloneNode signature.
Detected on version 1.22 but same change is valid for version 2.0.x.
Pused a patch too to be used on a project.
Comment #4
abarrioComment #7
jesus_md commentedConfirmed and tested. Reproduced on 1.2.2: resolving the Clone tab access callback without a
noderoute parameter throwsRuntimeException: Callable "...QuickNodeCloneNodeAccess::cloneNode" requires a value for the "$node" argument.With theNULLdefault it just returns forbidden and the tab is left out, same fix as #3431222: RuntimeException: Callable QuickNodeCloneNodeAccess::cloneNode requires a value for the "$node" argument in Quick Node Clone.Merged into 1.2.x and ported to 2.0.x, which had the same signature. It will be in the next 1.2.x and 2.0.x releases.
Thanks abarrio. Marking as fixed.
Comment #8
jesus_md commented