1

Why is my plugin not getting called?

app/code/Company/Configurator/etc/module.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Company_Configurator" setup_version="0.1.0">
        <sequence>
            <module name="Magento_Quote"/>
            <module name="Magento_Csp"/>
        </sequence>
    </module>
</config>

app/code/Company/Configurator/etc/di.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Csp\Model\Policy\FetchPolicy">
        <plugin name="company_configurator_after_fetch_policy"
                type="Company\Configurator\Plugin\FetchPolicyPlugin" />
    </type>
</config>

app/code/Company/Configurator/Plugin/FetchPolicyPlugin.php:

<?php
namespace Company\Configurator\Plugin;

class FetchPolicyPlugin
{
    /**
     * @param \Magento\Csp\Model\Policy\FetchPolicy $subject
     * @param string[] $result
     * @return string[]
     */
    public function afterGetHostSources(\Magento\Csp\Model\Policy\FetchPolicy $subject, array $result): array
    {
        // Modify the $result array here, if needed
        // For example, add an additional host source
        $result[] = 'example.com';  // I have set a xdebug breakpoint here, but it is never hit.

        return $result;
    }
}

The original method is getting called, but not my plugin.

0

2 Answers 2

2

The Magento\Csp\Model\Policy\FetchPolicy class is instantiated using the new keyword and not by dependency injection.

new FetchPolicy()

Therefore, using a plugin or preference will not work.

To apply the change to this class, I suggest creating a custom composer patch and applying it via composer.

For instructions on how to create a custom composer patch, please refer to this topic: How to create a Magento 2 Patch?

For instructions on how to apply composer patches, please refer to this document: https://experienceleague.adobe.com/docs/commerce-operations/upgrade-guide/patches/apply.html?lang=en#composer

2
  • But what if I upgrade my magento 2 and it conflicts with my patch?
    – Black
    Commented Jul 25, 2023 at 7:30
  • 1
    Then you need to update the patch file content again :). This is the only preferred way to modify the Magento\Csp\Model\Policy\FetchPolicy class. However, don't worry about the magento upgrade, this class rarely gets the update, the last update was 3 years ago (Magento 2.4.2). You can check the git commits history at github.com/magento/magento2/commits/2.4-develop/app/code/…
    – Tu Van
    Commented Jul 25, 2023 at 7:59
1

Based on your code snippet, you're trying to plugin to the method getHostSources of the Magento\Csp\Model\Policy\FetchPolicy class.

However, this method is called within the merge method of the Magento\Csp\Model\Collector\FetchPolicyMerger class and is directly passed as an argument to the array_merge function.

In Magento, when methods are called this way, plugins (interceptors) might not be triggered because of how PHP resolves function arguments. This is a known limitation in the Magento 2 plugin system.

This means that the method getHostSources is being called and its results are used directly as arguments for the array_merge function. PHP will resolve these arguments before making the call to array_merge.

As a result, the plugin is not getting triggered because from a PHP perspective, it's not a direct method call, but rather the method's result is being used as a function argument.

A workaround to this problem would be to extend the Magento\Csp\Model\Collector\FetchPolicyMerger class and override the respective methods. Alternatively, if it fits your use case, you might consider creating a plugin for the merge method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.