first commit
This commit is contained in:
41
plugins/content/loadmodule/loadmodule.xml
Normal file
41
plugins/content/loadmodule/loadmodule.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="content" method="upgrade">
|
||||
<name>plg_content_loadmodule</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2005-11</creationDate>
|
||||
<copyright>(C) 2005 Open Source Matters, Inc.</copyright>
|
||||
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
|
||||
<authorEmail>admin@joomla.org</authorEmail>
|
||||
<authorUrl>www.joomla.org</authorUrl>
|
||||
<version>3.0.0</version>
|
||||
<description>PLG_LOADMODULE_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Plugin\Content\LoadModule</namespace>
|
||||
<files>
|
||||
<folder plugin="loadmodule">services</folder>
|
||||
<folder>src</folder>
|
||||
</files>
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/plg_content_loadmodule.ini</language>
|
||||
<language tag="en-GB">language/en-GB/plg_content_loadmodule.sys.ini</language>
|
||||
</languages>
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field
|
||||
name="style"
|
||||
type="list"
|
||||
label="PLG_LOADMODULE_FIELD_STYLE_LABEL"
|
||||
default="none"
|
||||
validate="options"
|
||||
>
|
||||
<option value="none">PLG_LOADMODULE_FIELD_VALUE_RAW</option>
|
||||
<option value="html5">PLG_LOADMODULE_FIELD_VALUE_DIVS</option>
|
||||
<option value="table">PLG_LOADMODULE_FIELD_VALUE_TABLE</option>
|
||||
<!-- @TODO: The following styles don't exist in default installation and can be removed in Joomla 5 -->
|
||||
<option value="horz">PLG_LOADMODULE_FIELD_VALUE_HORIZONTAL</option>
|
||||
<option value="rounded">PLG_LOADMODULE_FIELD_VALUE_MULTIPLEDIVS</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
46
plugins/content/loadmodule/services/provider.php
Normal file
46
plugins/content/loadmodule/services/provider.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Plugin
|
||||
* @subpackage Content.loadmodule
|
||||
*
|
||||
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Extension\PluginInterface;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Joomla\Plugin\Content\LoadModule\Extension\LoadModule;
|
||||
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->set(
|
||||
PluginInterface::class,
|
||||
function (Container $container) {
|
||||
$plugin = new LoadModule(
|
||||
$container->get(DispatcherInterface::class),
|
||||
(array) PluginHelper::getPlugin('content', 'loadmodule')
|
||||
);
|
||||
$plugin->setApplication(Factory::getApplication());
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
250
plugins/content/loadmodule/src/Extension/LoadModule.php
Normal file
250
plugins/content/loadmodule/src/Extension/LoadModule.php
Normal file
@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Plugin
|
||||
* @subpackage Content.loadmodule
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Plugin\Content\LoadModule\Extension;
|
||||
|
||||
use Joomla\CMS\Helper\ModuleHelper;
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Plugin to enable loading modules into content (e.g. articles)
|
||||
* This uses the {loadmodule} syntax
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
final class LoadModule extends CMSPlugin
|
||||
{
|
||||
protected static $modules = [];
|
||||
|
||||
protected static $mods = [];
|
||||
|
||||
/**
|
||||
* Plugin that loads module positions within content
|
||||
*
|
||||
* @param string $context The context of the content being passed to the plugin.
|
||||
* @param object &$article The article object. Note $article->text is also available
|
||||
* @param mixed &$params The article params
|
||||
* @param integer $page The 'page' number
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function onContentPrepare($context, &$article, &$params, $page = 0)
|
||||
{
|
||||
// Only execute if $article is an object and has a text property
|
||||
if (!\is_object($article) || !property_exists($article, 'text') || \is_null($article->text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$defaultStyle = $this->params->get('style', 'none');
|
||||
|
||||
// Fallback xhtml (used in Joomla 3) to html5
|
||||
if ($defaultStyle === 'xhtml') {
|
||||
$defaultStyle = 'html5';
|
||||
}
|
||||
|
||||
// Expression to search for (positions)
|
||||
$regex = '/{loadposition\s(.*?)}/i';
|
||||
|
||||
// Expression to search for(modules)
|
||||
$regexmod = '/{loadmodule\s(.*?)}/i';
|
||||
|
||||
// Expression to search for(id)
|
||||
$regexmodid = '/{loadmoduleid\s([1-9][0-9]*)}/i';
|
||||
|
||||
// Remove macros and don't run this plugin when the content is being indexed
|
||||
if ($context === 'com_finder.indexer') {
|
||||
if (str_contains($article->text, 'loadposition')) {
|
||||
$article->text = preg_replace($regex, '', $article->text);
|
||||
}
|
||||
|
||||
if (str_contains($article->text, 'loadmoduleid')) {
|
||||
$article->text = preg_replace($regexmodid, '', $article->text);
|
||||
}
|
||||
|
||||
if (str_contains($article->text, 'loadmodule')) {
|
||||
$article->text = preg_replace($regexmod, '', $article->text);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (str_contains($article->text, '{loadposition ')) {
|
||||
// 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);
|
||||
|
||||
// No matches, skip this
|
||||
if ($matches) {
|
||||
foreach ($matches as $match) {
|
||||
$matcheslist = explode(',', $match[1]);
|
||||
|
||||
// We may not have a module style so fall back to the plugin default.
|
||||
if (!\array_key_exists(1, $matcheslist)) {
|
||||
$matcheslist[1] = $defaultStyle;
|
||||
}
|
||||
|
||||
$position = trim($matcheslist[0]);
|
||||
$style = trim($matcheslist[1]);
|
||||
|
||||
$output = $this->load($position, $style);
|
||||
|
||||
// We should replace only first occurrence in order to allow positions with the same name to regenerate their content:
|
||||
if (($start = strpos($article->text, $match[0])) !== false) {
|
||||
$article->text = substr_replace($article->text, $output, $start, \strlen($match[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (str_contains($article->text, '{loadmodule ')) {
|
||||
// Find all instances of plugin and put in $matchesmod for loadmodule
|
||||
preg_match_all($regexmod, $article->text, $matchesmod, PREG_SET_ORDER);
|
||||
|
||||
// If no matches, skip this
|
||||
if ($matchesmod) {
|
||||
foreach ($matchesmod as $matchmod) {
|
||||
$matchesmodlist = explode(',', $matchmod[1]);
|
||||
|
||||
// First parameter is the module, will be prefixed with mod_ later
|
||||
$module = trim($matchesmodlist[0]);
|
||||
|
||||
// Second parameter is the title
|
||||
$title = '';
|
||||
|
||||
if (\array_key_exists(1, $matchesmodlist)) {
|
||||
$title = htmlspecialchars_decode(trim($matchesmodlist[1]));
|
||||
}
|
||||
|
||||
// Third parameter is the module style, (fallback is the plugin default set earlier).
|
||||
$stylemod = $defaultStyle;
|
||||
|
||||
if (\array_key_exists(2, $matchesmodlist)) {
|
||||
$stylemod = trim($matchesmodlist[2]);
|
||||
}
|
||||
|
||||
$output = $this->loadModule($module, $title, $stylemod);
|
||||
|
||||
// We should replace only first occurrence in order to allow positions with the same name to regenerate their content:
|
||||
if (($start = strpos($article->text, $matchmod[0])) !== false) {
|
||||
$article->text = substr_replace($article->text, $output, $start, \strlen($matchmod[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (str_contains($article->text, '{loadmoduleid ')) {
|
||||
// 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:
|
||||
if (($start = strpos($article->text, $match[0])) !== false) {
|
||||
$article->text = substr_replace($article->text, $output, $start, \strlen($match[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and renders the module
|
||||
*
|
||||
* @param string $position The position assigned to the module
|
||||
* @param string $style The style assigned to the module
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
private function load($position, $style = 'none')
|
||||
{
|
||||
$document = $this->getApplication()->getDocument();
|
||||
$renderer = $document->loadRenderer('module');
|
||||
$modules = ModuleHelper::getModules($position);
|
||||
$params = ['style' => $style];
|
||||
ob_start();
|
||||
|
||||
foreach ($modules as $module) {
|
||||
echo $renderer->render($module, $params);
|
||||
}
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is always going to get the first instance of the module type unless
|
||||
* there is a title.
|
||||
*
|
||||
* @param string $module The module title
|
||||
* @param string $title The title of the module
|
||||
* @param string $style The style of the module
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
private function loadModule($module, $title, $style = 'none')
|
||||
{
|
||||
$document = $this->getApplication()->getDocument();
|
||||
$renderer = $document->loadRenderer('module');
|
||||
$mod = ModuleHelper::getModule($module, $title);
|
||||
|
||||
// If the module without the mod_ isn't found, try it with mod_.
|
||||
// This allows people to enter it either way in the content
|
||||
if (!isset($mod)) {
|
||||
$name = 'mod_' . $module;
|
||||
$mod = ModuleHelper::getModule($name, $title);
|
||||
}
|
||||
|
||||
$params = ['style' => $style];
|
||||
ob_start();
|
||||
|
||||
if ($mod->id) {
|
||||
echo $renderer->render($mod, $params);
|
||||
}
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and renders the module
|
||||
*
|
||||
* @param string $id The id of the module
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 3.9.0
|
||||
*/
|
||||
private function loadID($id)
|
||||
{
|
||||
$document = $this->getApplication()->getDocument();
|
||||
$renderer = $document->loadRenderer('module');
|
||||
$modules = ModuleHelper::getModuleById($id);
|
||||
$params = ['style' => 'none'];
|
||||
ob_start();
|
||||
|
||||
if ($modules->id > 0) {
|
||||
echo $renderer->render($modules, $params);
|
||||
}
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user