Hi JoomShaper team,
I'd like to report a bug in SP Page Builder Pro 6.10.0, with a proposed fix.
Environment: Joomla 6.2.0, SP Page Builder Pro 6.10.0, PHP 8.3, MariaDB 10.5 (also reproduced on MySQL 8.0)
Problem
When an article built with SP Page Builder is copied with Save as Copy, the copy sometimes gets the layout of an SP Page Builder module instead of the article's own layout. This happens whenever a mod_sppagebuilder module exists whose module ID equals the original article's ID.
Steps to reproduce
- Have an SP Page Builder module with ID N and an article with ID N that is built with SP Page Builder. For example, module 130 "Blog Hero" and article 130.
- Open article N in the backend and click Save as Copy.
- Open the copy in the SP Page Builder editor. It contains the module's layout, not the article's.
Cause
In plugins/content/sppagebuilder/sppagebuilder.php, onContentAfterSave() (line 143) loads the source layout with only view_id = N:
$query->select('*')->from($db->quoteName('#__sppagebuilder'))->where($db->quoteName('view_id') . '=' . (int)$sppagebuilder_article_id);
Article and module layouts share the view_id numbers in #__sppagebuilder, so loadObject() can return the mod_sppagebuilder row. The same unfiltered lookup is used in two other places. They work today only because of row order:
onExtensionAfterSave()in the same file (line 87, module Save as Copy)onTableAfterLoad()inplugins/system/sppagebuilder/sppagebuilder.php(line 2533, module Duplicate)
Proposed fix
Filter on extension / extension_view. We tested this locally: article copies get the right layout, and module Save as Copy and Duplicate still work.
--- a/plugins/content/sppagebuilder/sppagebuilder.php
+++ b/plugins/content/sppagebuilder/sppagebuilder.php
@@ -87 +87,4 @@ public function onExtensionAfterSave($context, $module_data)
- $query->select('*')->from($db->quoteName('#__sppagebuilder'))->where($db->quoteName('view_id') . '=' . (int)$sppagebuilder_module_id);
+ $query->select('*')->from($db->quoteName('#__sppagebuilder'))->where($db->quoteName('view_id') . '=' . (int)$sppagebuilder_module_id)
+ ->where($db->quoteName('extension') . ' = ' . $db->quote('mod_sppagebuilder'))
+ ->where($db->quoteName('extension_view') . ' = ' . $db->quote('module'));
@@ -143 +146,4 @@ public function onContentAfterSave($context, $article, $isNew)
- $query->select('*')->from($db->quoteName('#__sppagebuilder'))->where($db->quoteName('view_id') . '=' . (int)$sppagebuilder_article_id);
+ $query->select('*')->from($db->quoteName('#__sppagebuilder'))->where($db->quoteName('view_id') . '=' . (int)$sppagebuilder_article_id)
+ ->where($db->quoteName('extension') . ' = ' . $db->quote('com_content'))
+ ->where($db->quoteName('extension_view') . ' = ' . $db->quote('article'));
--- a/plugins/system/sppagebuilder/sppagebuilder.php
+++ b/plugins/system/sppagebuilder/sppagebuilder.php
@@ -2533 +2533,4 @@ public function onTableAfterLoad(AfterLoadEvent $event)
- $query->select('*')->from($db->quoteName('#__sppagebuilder'))->where($db->quoteName('view_id') . '=' . (int)$id);
+ $query->select('*')->from($db->quoteName('#__sppagebuilder'))->where($db->quoteName('view_id') . '=' . (int)$id)
+ ->where($db->quoteName('extension') . ' = ' . $db->quote('mod_sppagebuilder'))
+ ->where($db->quoteName('extension_view') . ' = ' . $db->quote('module'));
Side note (separate issue)
Module Save as Copy inserts two identical #__sppagebuilder rows for the new module. SppagebuilderHelper::onAfterSavingModule() always inserts and never updates, and it appears to be called twice during the save. This also happens with the unmodified 6.10.0 plugin.
Could you please include a fix in the next release? We have patched our site in the meantime, but the patch will be lost on the next update.
Thank you!