diff --git a/app/code/Magento/Csp/Model/BlockCache.php b/app/code/Magento/Csp/Model/BlockCache.php
index f0469c3251379..fac0beec51c07 100644
--- a/app/code/Magento/Csp/Model/BlockCache.php
+++ b/app/code/Magento/Csp/Model/BlockCache.php
@@ -111,7 +111,7 @@ public function save($data, $identifier, $tags = [], $lifeTime = null)
];
}
}
- $data = $this->serializer->serialize(['policies' => $policiesData, 'html' => $data]);
+ $data = $this->serializer->serialize(['policies' => $policiesData, 'html' => (string)$data]);
}
return $this->cache->save($data, $identifier, $tags, $lifeTime);
diff --git a/app/code/Magento/Csp/Model/Collector/CompositeMerger.php b/app/code/Magento/Csp/Model/Collector/CompositeMerger.php
new file mode 100644
index 0000000000000..16430f1ff8aa9
--- /dev/null
+++ b/app/code/Magento/Csp/Model/Collector/CompositeMerger.php
@@ -0,0 +1,57 @@
+mergers = $mergers;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function merge(PolicyInterface $policy1, PolicyInterface $policy2): PolicyInterface
+ {
+ foreach ($this->mergers as $merger) {
+ if ($merger->canMerge($policy1, $policy2)) {
+ return $merger->merge($policy1, $policy2);
+ }
+ }
+
+ throw new \RuntimeException('Cannot merge 2 policies of ' .get_class($policy1));
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function canMerge(PolicyInterface $policy1, PolicyInterface $policy2): bool
+ {
+ foreach ($this->mergers as $merger) {
+ if ($merger->canMerge($policy1, $policy2)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/app/code/Magento/Csp/Model/Collector/DynamicCollector.php b/app/code/Magento/Csp/Model/Collector/DynamicCollector.php
index 6478e9622f910..743f77c93f3d8 100644
--- a/app/code/Magento/Csp/Model/Collector/DynamicCollector.php
+++ b/app/code/Magento/Csp/Model/Collector/DynamicCollector.php
@@ -20,6 +20,19 @@ class DynamicCollector implements PolicyCollectorInterface
*/
private $added = [];
+ /**
+ * @var MergerInterface
+ */
+ private $merger;
+
+ /**
+ * @param MergerInterface $merger
+ */
+ public function __construct(MergerInterface $merger)
+ {
+ $this->merger = $merger;
+ }
+
/**
* Add a policy for current page.
*
@@ -28,7 +41,15 @@ class DynamicCollector implements PolicyCollectorInterface
*/
public function add(PolicyInterface $policy): void
{
- $this->added[] = $policy;
+ if (array_key_exists($policy->getId(), $this->added)) {
+ if ($this->merger->canMerge($this->added[$policy->getId()], $policy)) {
+ $this->added[$policy->getId()] = $this->merger->merge($this->added[$policy->getId()], $policy);
+ } else {
+ throw new \RuntimeException('Cannot merge a policy of ' .get_class($policy));
+ }
+ } else {
+ $this->added[$policy->getId()] = $policy;
+ }
}
/**
@@ -36,6 +57,6 @@ public function add(PolicyInterface $policy): void
*/
public function collect(array $defaultPolicies = []): array
{
- return array_merge($defaultPolicies, $this->added);
+ return array_merge($defaultPolicies, array_values($this->added));
}
}
diff --git a/app/code/Magento/Csp/etc/di.xml b/app/code/Magento/Csp/etc/di.xml
index 7b1129a0e1a41..238392fe1c8d1 100644
--- a/app/code/Magento/Csp/etc/di.xml
+++ b/app/code/Magento/Csp/etc/di.xml
@@ -15,6 +15,17 @@
+
+
+
+
+ - Magento\Csp\Model\Collector\FetchPolicyMerger
+ - Magento\Csp\Model\Collector\FlagPolicyMerger
+ - Magento\Csp\Model\Collector\PluginTypesPolicyMerger
+ - Magento\Csp\Model\Collector\SandboxPolicyMerger
+
+
+
@@ -24,10 +35,7 @@
- Magento\Csp\Model\Collector\DynamicCollector\Proxy
- - Magento\Csp\Model\Collector\FetchPolicyMerger
- - Magento\Csp\Model\Collector\FlagPolicyMerger
- - Magento\Csp\Model\Collector\PluginTypesPolicyMerger
- - Magento\Csp\Model\Collector\SandboxPolicyMerger
+ - Magento\Csp\Model\Collector\MergerInterface
@@ -93,6 +101,7 @@
configured_block_cache
+ Magento\Framework\Serialize\Serializer\Serialize