diff --git a/administrator/components/com_modules/views/modules/tmpl/modal.php b/administrator/components/com_modules/views/modules/tmpl/modal.php index dd602403bb041..b59602d0f3d04 100644 --- a/administrator/components/com_modules/views/modules/tmpl/modal.php +++ b/administrator/components/com_modules/views/modules/tmpl/modal.php @@ -89,7 +89,7 @@ - + escape($item->title); ?> diff --git a/libraries/src/Helper/ModuleHelper.php b/libraries/src/Helper/ModuleHelper.php index 7dbb32f163282..bf8e071829450 100644 --- a/libraries/src/Helper/ModuleHelper.php +++ b/libraries/src/Helper/ModuleHelper.php @@ -644,4 +644,43 @@ public static function isAdminMultilang() return $enabled; } + + /** + * Get module by id + * + * @param string $id The id of the module + * + * @return \stdClass The Module object + * + * @since __DEPLOY_VERSION__ + */ + public static function &getModuleById($id) + { + $modules =& static::load(); + + $total = count($modules); + + for ($i = 0; $i < $total; $i++) + { + // Match the id of the module + if ($modules[$i]->id === $id) + { + // Found it + return $modules[$i]; + } + } + + // If we didn't find it, create a dummy object + $result = new \stdClass; + $result->id = 0; + $result->title = ''; + $result->module = ''; + $result->position = ''; + $result->content = ''; + $result->showtitle = 0; + $result->control = ''; + $result->params = ''; + + return $result; + } } diff --git a/media/com_modules/js/admin-modules-modal.js b/media/com_modules/js/admin-modules-modal.js index e2d1303536a43..83f9e9444ee09 100644 --- a/media/com_modules/js/admin-modules-modal.js +++ b/media/com_modules/js/admin-modules-modal.js @@ -10,19 +10,18 @@ document.addEventListener('DOMContentLoaded', function() { var modulesLinks = document.querySelectorAll('.js-module-insert'), i, positionsLinks = document.querySelectorAll('.js-position-insert'); - /** Assign listener for click event (for single module insertion) **/ + /** Assign listener for click event (for single module id insertion) **/ for (i= 0; modulesLinks.length > i; i++) { modulesLinks[i].addEventListener('click', function(event) { event.preventDefault(); - var type = event.target.getAttribute('data-module'), - name = event.target.getAttribute('data-title'), + var modid = event.target.getAttribute('data-module'), editor = event.target.getAttribute('data-editor'); /** Use the API, if editor supports it **/ if (window.parent.Joomla && window.parent.Joomla.editors && window.parent.Joomla.editors.instances && window.parent.Joomla.editors.instances.hasOwnProperty(editor)) { - window.parent.Joomla.editors.instances[editor].replaceSelection("{loadmodule " + type + "," + name + "}") + window.parent.Joomla.editors.instances[editor].replaceSelection("{loadmoduleid " + modid + "}") } else { - window.parent.jInsertEditorText("{loadmodule " + type + "," + name + "}", editor); + window.parent.jInsertEditorText("{loadmoduleid " + modid + "}", editor); } window.parent.jModalClose(); @@ -46,4 +45,5 @@ document.addEventListener('DOMContentLoaded', function() { window.parent.jModalClose(); }); } + }); diff --git a/media/com_modules/js/admin-modules-modal.min.js b/media/com_modules/js/admin-modules-modal.min.js index 965dadb96f996..8396f641de5c2 100644 --- a/media/com_modules/js/admin-modules-modal.min.js +++ b/media/com_modules/js/admin-modules-modal.min.js @@ -1 +1 @@ -document.addEventListener("DOMContentLoaded",function(){"use strict";var b,a=document.querySelectorAll(".js-module-insert"),c=document.querySelectorAll(".js-position-insert");for(b=0;a.length>b;b++)a[b].addEventListener("click",function(a){a.preventDefault();var b=a.target.getAttribute("data-module"),c=a.target.getAttribute("data-title"),d=a.target.getAttribute("data-editor");window.parent.Joomla&&window.parent.Joomla.editors&&window.parent.Joomla.editors.instances&&window.parent.Joomla.editors.instances.hasOwnProperty(d)?window.parent.Joomla.editors.instances[d].replaceSelection("{loadmodule "+b+","+c+"}"):window.parent.jInsertEditorText("{loadmodule "+b+","+c+"}",d),window.parent.jModalClose()});for(b=0;c.length>b;b++)c[b].addEventListener("click",function(a){a.preventDefault();var b=a.target.getAttribute("data-position"),c=a.target.getAttribute("data-editor");window.Joomla&&window.Joomla.editors&&Joomla.editors.instances&&Joomla.editors.instances.hasOwnProperty(c)?Joomla.editors.instances[c].replaceSelection("{loadposition "+b+"}"):window.parent.jInsertEditorText("{loadposition "+b+"}",c),window.parent.jModalClose()})}); \ No newline at end of file +document.addEventListener('DOMContentLoaded',function(){'use strict';var b,a=document.querySelectorAll('.js-module-insert'),c=document.querySelectorAll('.js-position-insert');for(b=0;a.length>b;b++)a[b].addEventListener('click',function(d){d.preventDefault();var e=d.target.getAttribute('data-module'),f=d.target.getAttribute('data-editor');window.parent.Joomla&&window.parent.Joomla.editors&&window.parent.Joomla.editors.instances&&window.parent.Joomla.editors.instances.hasOwnProperty(f)?window.parent.Joomla.editors.instances[f].replaceSelection('{loadmoduleid '+e+'}'):window.parent.jInsertEditorText('{loadmoduleid '+e+'}',f),window.parent.jModalClose()});for(b=0;c.length>b;b++)c[b].addEventListener('click',function(d){d.preventDefault();var e=d.target.getAttribute('data-position'),f=d.target.getAttribute('data-editor');window.Joomla&&window.Joomla.editors&&Joomla.editors.instances&&Joomla.editors.instances.hasOwnProperty(f)?Joomla.editors.instances[f].replaceSelection('{loadposition '+e+'}'):window.parent.jInsertEditorText('{loadposition '+e+'}',f),window.parent.jModalClose()})}); diff --git a/plugins/content/loadmodule/loadmodule.php b/plugins/content/loadmodule/loadmodule.php index 7f4505dbc5af6..5d900f7edd95e 100644 --- a/plugins/content/loadmodule/loadmodule.php +++ b/plugins/content/loadmodule/loadmodule.php @@ -55,6 +55,9 @@ public function onContentPrepare($context, &$article, &$params, $page = 0) $regexmod = '/{loadmodule\s(.*?)}/i'; $stylemod = $this->params->def('style', 'none'); + // Expression to search for(id) + $regexmodid = '/{loadmoduleid\s([1-9][0-9]*)}/i'; + // Find all instances of plugin and put in $matches for loadposition // $matches[0] is full pattern match, $matches[1] is the position preg_match_all($regex, $article->text, $matches, PREG_SET_ORDER); @@ -117,6 +120,23 @@ public function onContentPrepare($context, &$article, &$params, $page = 0) $stylemod = $this->params->def('style', 'none'); } } + + // Find all instances of plugin and put in $matchesmodid for loadmoduleid + preg_match_all($regexmodid, $article->text, $matchesmodid, PREG_SET_ORDER); + + // If no matches, skip this + if ($matchesmodid) + { + foreach ($matchesmodid as $match) + { + $id = trim($match[1]); + $output = $this->_loadid($id); + + // We should replace only first occurrence in order to allow positions with the same name to regenerate their content: + $article->text = preg_replace("|$match[0]|", addcslashes($output, '\\$'), $article->text, 1); + $style = $this->params->def('style', 'none'); + } + } } /** @@ -187,4 +207,32 @@ protected function _loadmod($module, $title, $style = 'none') return self::$mods[$module]; } + + /** + * Loads and renders the module + * + * @param string $id The id of the module + * + * @return mixed + * + * @since __DEPLOY_VERSION__ + */ + protected function _loadid($id) + { + self::$modules[$id] = ''; + $document = JFactory::getDocument(); + $renderer = $document->loadRenderer('module'); + $modules = JModuleHelper::getModuleById($id); + $params = array('style' => 'none'); + ob_start(); + + if ($modules->id > 0) + { + echo $renderer->render($modules, $params); + } + + self::$modules[$id] = ob_get_clean(); + + return self::$modules[$id]; + } }