first commit

This commit is contained in:
2025-06-17 11:53:18 +02:00
commit 9f0f7ba12b
8804 changed files with 1369176 additions and 0 deletions

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<access component="com_plugins">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" />
<action name="core.manage" title="JACTION_MANAGE" />
<action name="core.edit" title="JACTION_EDIT" />
<action name="core.edit.state" title="JACTION_EDITSTATE" />
</section>
</access>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<config>
<help key="Plugin:_Options"/>
<fieldset
name="permissions"
label="JCONFIG_PERMISSIONS_LABEL"
>
<field
name="rules"
type="rules"
label="JCONFIG_PERMISSIONS_LABEL"
filter="rules"
validate="rules"
component="com_plugins"
section="component"
/>
</fieldset>
</config>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<form addfieldprefix="Joomla\Component\Plugins\Administrator\Field">
<fields name="filter">
<field
name="search"
type="text"
inputmode="search"
label="COM_PLUGINS_FILTER_SEARCH_LABEL"
description="COM_PLUGINS_SEARCH_IN_TITLE"
hint="JSEARCH_FILTER"
/>
<field
name="enabled"
type="pluginstatus"
label="JSTATUS"
class="js-select-submit-on-change"
>
<option value="">JOPTION_SELECT_PUBLISHED</option>
</field>
<field
name="folder"
type="PluginType"
label="COM_PLUGINS_FOLDER_HEADING"
class="js-select-submit-on-change"
>
<option value="">COM_PLUGINS_OPTION_FOLDER</option>
</field>
<field
name="element"
type="PluginElement"
label="COM_PLUGINS_ELEMENT_HEADING"
class="js-select-submit-on-change"
>
<option value="">COM_PLUGINS_OPTION_ELEMENT</option>
</field>
<field
name="access"
type="accesslevel"
label="JGRID_HEADING_ACCESS"
class="js-select-submit-on-change"
>
<option value="">JOPTION_SELECT_ACCESS</option>
</field>
</fields>
<fields name="list">
<field
name="fullordering"
type="list"
label="JGLOBAL_SORT_BY"
class="js-select-submit-on-change"
default="folder ASC"
validate="options"
>
<option value="">JGLOBAL_SORT_BY</option>
<option value="ordering ASC">JGRID_HEADING_ORDERING_ASC</option>
<option value="ordering DESC">JGRID_HEADING_ORDERING_DESC</option>
<option value="enabled ASC">JSTATUS_ASC</option>
<option value="enabled DESC">JSTATUS_DESC</option>
<option value="name ASC">JGLOBAL_NAME_ASC</option>
<option value="name DESC">JGLOBAL_NAME_DESC</option>
<option value="folder ASC">COM_PLUGINS_HEADING_FOLDER_ASC</option>
<option value="folder DESC">COM_PLUGINS_HEADING_FOLDER_DESC</option>
<option value="element ASC">COM_PLUGINS_HEADING_ELEMENT_ASC</option>
<option value="element DESC">COM_PLUGINS_HEADING_ELEMENT_DESC</option>
<option value="access ASC">JGRID_HEADING_ACCESS_ASC</option>
<option value="access DESC">JGRID_HEADING_ACCESS_DESC</option>
<option value="extension_id ASC">JGRID_HEADING_ID_ASC</option>
<option value="extension_id DESC">JGRID_HEADING_ID_DESC</option>
</field>
<field
name="limit"
type="limitbox"
label="JGLOBAL_LIST_LIMIT"
default="25"
class="js-select-submit-on-change"
/>
</fields>
</form>

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<form addfieldprefix="Joomla\Component\Plugins\Administrator\Field">
<config>
<inlinehelp button="show"/>
</config>
<fieldset>
<field
name="extension_id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
default="0"
readonly="true"
class="readonly"
/>
<field
name="name"
type="hidden"
label="COM_PLUGINS_FIELD_NAME_LABEL"
/>
<field
name="enabled"
type="list"
label="JSTATUS"
class="form-select-color-state"
default="1"
validate="options"
>
<option value="1">JENABLED</option>
<option value="0">JDISABLED</option>
</field>
<field
name="access"
type="accesslevel"
label="JFIELD_ACCESS_LABEL"
filter="UINT"
validate="options"
/>
<field
name="ordering"
type="pluginordering"
label="JFIELD_ORDERING_LABEL"
/>
<field
name="folder"
type="text"
label="COM_PLUGINS_FIELD_FOLDER_LABEL"
class="readonly"
readonly="true"
/>
<field
name="element"
type="text"
label="COM_PLUGINS_FIELD_ELEMENT_LABEL"
class="readonly"
readonly="true"
/>
<field
name="note"
type="textarea"
label="JFIELD_NOTE_LABEL"
maxlength="255"
/>
</fieldset>
</form>

View File

@ -0,0 +1,27 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*
* @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
*/
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Plugins component helper.
*
* @since 1.6
*
* @deprecated 4.3 will be removed in 6.0
* Use \Joomla\Component\Plugins\Administrator\Helper\PluginsHelper instead
*/
class PluginsHelper extends \Joomla\Component\Plugins\Administrator\Helper\PluginsHelper
{
}

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="component" method="upgrade">
<name>com_plugins</name>
<author>Joomla! Project</author>
<creationDate>2006-04</creationDate>
<copyright>(C) 2006 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>4.0.0</version>
<description>COM_PLUGINS_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Component\Plugins</namespace>
<administration>
<files folder="admin">
<filename>access.xml</filename>
<filename>config.xml</filename>
<filename>plugins.xml</filename>
<folder>forms</folder>
<folder>helpers</folder>
<folder>services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages folder="admin">
<language tag="en-GB">language/en-GB/com_plugins.ini</language>
<language tag="en-GB">language/en-GB/com_plugins.sys.ini</language>
</languages>
</administration>
</extension>

View File

@ -0,0 +1,51 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2018 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\Dispatcher\ComponentDispatcherFactoryInterface;
use Joomla\CMS\Extension\ComponentInterface;
use Joomla\CMS\Extension\MVCComponent;
use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory;
use Joomla\CMS\Extension\Service\Provider\MVCFactory;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
/**
* The plugin service provider.
*
* @since 4.0.0
*/
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.0.0
*/
public function register(Container $container)
{
$container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Plugins'));
$container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Plugins'));
$container->set(
ComponentInterface::class,
function (Container $container) {
$component = new MVCComponent($container->get(ComponentDispatcherFactoryInterface::class));
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
return $component;
}
);
}
};

View File

@ -0,0 +1,67 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\Controller;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Plugins display controller.
*
* @since 1.5
*/
class DisplayController extends BaseController
{
/**
* The default view.
*
* @var string
* @since 1.6
*/
protected $default_view = 'plugins';
/**
* Method to display a view.
*
* @param boolean $cachable If true, the view output will be cached
* @param array $urlparams An array of safe URL parameters and their variable types.
* @see \Joomla\CMS\Filter\InputFilter::clean() for valid values.
*
* @return static|boolean This object to support chaining or false on failure.
*
* @since 1.5
*/
public function display($cachable = false, $urlparams = [])
{
$view = $this->input->get('view', 'plugins');
$layout = $this->input->get('layout', 'default');
$id = $this->input->getInt('extension_id');
// Check for edit form.
if ($view == 'plugin' && $layout == 'edit' && !$this->checkEditId('com_plugins.edit.plugin', $id)) {
// Somehow the person just went to the form - we don't allow that.
if (!\count($this->app->getMessageQueue())) {
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
}
$this->setRedirect(Route::_('index.php?option=com_plugins&view=plugins', false));
return false;
}
return parent::display($cachable, $urlparams);
}
}

View File

@ -0,0 +1,26 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\Controller;
use Joomla\CMS\MVC\Controller\FormController;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Plugin controller class.
*
* @since 1.6
*/
class PluginController extends FormController
{
}

View File

@ -0,0 +1,67 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\Controller;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\AdminController;
use Joomla\CMS\Response\JsonResponse;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Plugins list controller class.
*
* @since 1.6
*/
class PluginsController extends AdminController
{
/**
* Method to get a model object, loading it if required.
*
* @param string $name The model name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return object The model.
*
* @since 1.6
*/
public function getModel($name = 'Plugin', $prefix = 'Administrator', $config = ['ignore_request' => true])
{
return parent::getModel($name, $prefix, $config);
}
/**
* Method to get the number of activated plugins
*
* @return void
*
* @since 4.0.0
*/
public function getQuickiconContent()
{
$model = $this->getModel('Plugins');
$model->setState('filter.enabled', 1);
$amount = (int) $model->getTotal();
$result = [];
$result['amount'] = $amount;
$result['sronly'] = Text::plural('COM_PLUGINS_N_QUICKICON_SRONLY', $amount);
$result['name'] = Text::plural('COM_PLUGINS_N_QUICKICON', $amount);
echo new JsonResponse($result);
}
}

View File

@ -0,0 +1,48 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\Field;
use Joomla\CMS\Form\Field\ListField;
use Joomla\Component\Plugins\Administrator\Helper\PluginsHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Plugin Element field.
*
* @since 3.9.0
*/
class PluginElementField extends ListField
{
/**
* The form field type.
*
* @var string
* @since 3.9.0
*/
protected $type = 'PluginElement';
/**
* Method to get the field options.
*
* @return array The field option objects.
*
* @since 3.9.0
*/
public function getOptions()
{
$options = PluginsHelper::elementOptions();
return array_merge(parent::getOptions(), $options);
}
}

View File

@ -0,0 +1,48 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2015 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\Field;
use Joomla\CMS\Form\Field\ListField;
use Joomla\Component\Plugins\Administrator\Helper\PluginsHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Plugin Type field.
*
* @since 3.5
*/
class PluginTypeField extends ListField
{
/**
* The form field type.
*
* @var string
* @since 3.5
*/
protected $type = 'PluginType';
/**
* Method to get the field options.
*
* @return array The field option objects.
*
* @since 3.5
*/
public function getOptions()
{
$options = PluginsHelper::folderOptions();
return array_merge(parent::getOptions(), $options);
}
}

View File

@ -0,0 +1,73 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\Field;
use Joomla\CMS\Form\Field\OrderingField;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Supports an HTML select list of plugins.
*
* @since 1.6
*/
class PluginorderingField extends OrderingField
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
protected $type = 'Pluginordering';
/**
* Builds the query for the ordering list.
*
* @return \Joomla\Database\DatabaseQuery The query for the ordering form field.
*/
protected function getQuery()
{
$db = $this->getDatabase();
$folder = $this->form->getValue('folder');
// Build the query for the ordering list.
$query = $db->getQuery(true)
->select(
[
$db->quoteName('ordering', 'value'),
$db->quoteName('name', 'text'),
$db->quoteName('type'),
$db->quote('folder'),
$db->quote('extension_id'),
]
)
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
->where($db->quoteName('folder') . ' = :folder')
->order($db->quoteName('ordering'))
->bind(':folder', $folder);
return $query;
}
/**
* Retrieves the current Item's Id.
*
* @return integer The current item ID.
*/
protected function getItemId()
{
return (int) $this->form->getValue('extension_id');
}
}

View File

@ -0,0 +1,125 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\Helper;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Installer\Installer;
use Joomla\CMS\Object\CMSObject;
use Joomla\Filesystem\Path;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Plugins component helper.
*
* @since 1.6
*/
class PluginsHelper
{
public static $extension = 'com_plugins';
/**
* Returns an array of standard published state filter options.
*
* @return array The HTML code for the select tag
*/
public static function publishedOptions()
{
// Build the active state filter options.
$options = [];
$options[] = HTMLHelper::_('select.option', '1', 'JENABLED');
$options[] = HTMLHelper::_('select.option', '0', 'JDISABLED');
return $options;
}
/**
* Returns a list of folders filter options.
*
* @return object[] The HTML code for the select tag
*/
public static function folderOptions()
{
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select('DISTINCT(folder) AS value, folder AS text')
->from('#__extensions')
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
->order('folder');
$db->setQuery($query);
try {
$options = $db->loadObjectList();
} catch (\RuntimeException $e) {
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
}
return $options;
}
/**
* Returns a list of elements filter options.
*
* @return object[] The HTML code for the select tag
*/
public static function elementOptions()
{
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select('DISTINCT(element) AS value, element AS text')
->from('#__extensions')
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
->order('element');
$db->setQuery($query);
try {
$options = $db->loadObjectList();
} catch (\RuntimeException $e) {
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
}
return $options;
}
/**
* Parse the template file.
*
* @param string $templateBaseDir Base path to the template directory.
* @param string $templateDir Template directory.
*
* @return CMSObject|bool
*/
public function parseXMLTemplateFile($templateBaseDir, $templateDir)
{
$data = new CMSObject();
// Check of the xml file exists.
$filePath = Path::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml');
if (is_file($filePath)) {
$xml = Installer::parseXMLInstallFile($filePath);
if ($xml['type'] != 'template') {
return false;
}
foreach ($xml as $key => $value) {
$data->set($key, $value);
}
}
return $data;
}
}

View File

@ -0,0 +1,376 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\Model;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\MVC\Model\AdminModel;
use Joomla\CMS\Object\CMSObject;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Table\Table;
use Joomla\Filesystem\Path;
use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Plugin model.
*
* @since 1.6
*/
class PluginModel extends AdminModel
{
/**
* @var string The help screen key for the module.
* @since 1.6
*/
protected $helpKey = 'Plugins:_Name_of_Plugin';
/**
* @var string The help screen base URL for the module.
* @since 1.6
*/
protected $helpURL;
/**
* @var array An array of cached plugin items.
* @since 1.6
*/
protected $_cache;
/**
* Constructor.
*
* @param array $config An optional associative array of configuration settings.
* @param ?MVCFactoryInterface $factory The factory.
*
* @see \Joomla\CMS\MVC\Model\BaseDatabaseModel
* @since 3.2
*/
public function __construct($config = [], MVCFactoryInterface $factory = null)
{
$config = array_merge(
[
'event_after_save' => 'onExtensionAfterSave',
'event_before_save' => 'onExtensionBeforeSave',
'events_map' => [
'save' => 'extension',
],
],
$config
);
parent::__construct($config, $factory);
}
/**
* Method to get the record form.
*
* @param array $data Data for the form.
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
*
* @return Form|bool A Form object on success, false on failure.
*
* @since 1.6
*/
public function getForm($data = [], $loadData = true)
{
// The folder and element vars are passed when saving the form.
if (empty($data)) {
$item = $this->getItem();
$folder = $item->folder;
$element = $item->element;
} else {
$folder = ArrayHelper::getValue($data, 'folder', '', 'cmd');
$element = ArrayHelper::getValue($data, 'element', '', 'cmd');
}
// Add the default fields directory
Form::addFieldPath(JPATH_PLUGINS . '/' . $folder . '/' . $element . '/field');
// These variables are used to add data from the plugin XML files.
$this->setState('item.folder', $folder);
$this->setState('item.element', $element);
// Get the form.
$form = $this->loadForm('com_plugins.plugin', 'plugin', ['control' => 'jform', 'load_data' => $loadData]);
if (empty($form)) {
return false;
}
// Modify the form based on access controls.
if (!$this->canEditState((object) $data)) {
// Disable fields for display.
$form->setFieldAttribute('ordering', 'disabled', 'true');
$form->setFieldAttribute('enabled', 'disabled', 'true');
// Disable fields while saving.
// The controller has already verified this is a record you can edit.
$form->setFieldAttribute('ordering', 'filter', 'unset');
$form->setFieldAttribute('enabled', 'filter', 'unset');
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return mixed The data for the form.
*
* @since 1.6
*/
protected function loadFormData()
{
// Check the session for previously entered form data.
$data = Factory::getApplication()->getUserState('com_plugins.edit.plugin.data', []);
if (empty($data)) {
$data = $this->getItem();
}
$this->preprocessData('com_plugins.plugin', $data);
return $data;
}
/**
* Method to get a single record.
*
* @param integer $pk The id of the primary key.
*
* @return mixed Object on success, false on failure.
*/
public function getItem($pk = null)
{
$pk = (!empty($pk)) ? $pk : (int) $this->getState('plugin.id');
$cacheId = $pk;
if (\is_array($cacheId)) {
$cacheId = serialize($cacheId);
}
if (!isset($this->_cache[$cacheId])) {
// Get a row instance.
$table = $this->getTable();
// Attempt to load the row.
$return = $table->load(\is_array($pk) ? $pk : ['extension_id' => $pk, 'type' => 'plugin']);
// Check for a table object error.
if ($return === false) {
return false;
}
// Convert to the \Joomla\CMS\Object\CMSObject before adding other data.
$properties = $table->getProperties(1);
$this->_cache[$cacheId] = ArrayHelper::toObject($properties, CMSObject::class);
// Convert the params field to an array.
$registry = new Registry($table->params);
$this->_cache[$cacheId]->params = $registry->toArray();
// Get the plugin XML.
$path = Path::clean(JPATH_PLUGINS . '/' . $table->folder . '/' . $table->element . '/' . $table->element . '.xml');
if (file_exists($path)) {
$this->_cache[$cacheId]->xml = simplexml_load_file($path);
} else {
$this->_cache[$cacheId]->xml = null;
}
}
return $this->_cache[$cacheId];
}
/**
* Returns a reference to the Table object, always creating it.
*
* @param string $type The table type to instantiate.
* @param string $prefix A prefix for the table class name. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return Table A database object
*/
public function getTable($type = 'Extension', $prefix = '\\Joomla\\CMS\\Table\\', $config = [])
{
return Table::getInstance($type, $prefix, $config);
}
/**
* Auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* @return void
*
* @since 1.6
*/
protected function populateState()
{
// Execute the parent method.
parent::populateState();
$app = Factory::getApplication();
// Load the User state.
$pk = $app->getInput()->getInt('extension_id');
$this->setState('plugin.id', $pk);
}
/**
* Preprocess the form.
*
* @param Form $form A form object.
* @param mixed $data The data expected for the form.
* @param string $group Cache group name.
*
* @return void
*
* @since 1.6
*
* @throws \Exception if there is an error in the form event.
*/
protected function preprocessForm(Form $form, $data, $group = 'content')
{
$folder = $this->getState('item.folder');
$element = $this->getState('item.element');
$lang = Factory::getLanguage();
// Load the core and/or local language sys file(s) for the ordering field.
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select($db->quoteName('element'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
->where($db->quoteName('folder') . ' = :folder')
->bind(':folder', $folder);
$db->setQuery($query);
$elements = $db->loadColumn();
foreach ($elements as $elementa) {
$lang->load('plg_' . $folder . '_' . $elementa . '.sys', JPATH_ADMINISTRATOR)
|| $lang->load('plg_' . $folder . '_' . $elementa . '.sys', JPATH_PLUGINS . '/' . $folder . '/' . $elementa);
}
if (empty($folder) || empty($element)) {
$app = Factory::getApplication();
$app->redirect(Route::_('index.php?option=com_plugins&view=plugins', false));
}
$formFile = Path::clean(JPATH_PLUGINS . '/' . $folder . '/' . $element . '/' . $element . '.xml');
if (!file_exists($formFile)) {
throw new \Exception(Text::sprintf('COM_PLUGINS_ERROR_FILE_NOT_FOUND', $element . '.xml'));
}
// Load the core and/or local language file(s).
$lang->load('plg_' . $folder . '_' . $element, JPATH_ADMINISTRATOR)
|| $lang->load('plg_' . $folder . '_' . $element, JPATH_PLUGINS . '/' . $folder . '/' . $element);
if (file_exists($formFile)) {
// Get the plugin form.
if (!$form->loadFile($formFile, false, '//config')) {
throw new \Exception(Text::_('JERROR_LOADFILE_FAILED'));
}
}
// Attempt to load the xml file.
if (!$xml = simplexml_load_file($formFile)) {
throw new \Exception(Text::_('JERROR_LOADFILE_FAILED'));
}
// Get the help data from the XML file if present.
$help = $xml->xpath('/extension/help');
if (!empty($help)) {
$helpKey = trim((string) $help[0]['key']);
$helpURL = trim((string) $help[0]['url']);
$this->helpKey = $helpKey ?: $this->helpKey;
$this->helpURL = $helpURL ?: $this->helpURL;
}
// Trigger the default form events.
parent::preprocessForm($form, $data, $group);
}
/**
* A protected method to get a set of ordering conditions.
*
* @param object $table A record object.
*
* @return array An array of conditions to add to ordering queries.
*
* @since 1.6
*/
protected function getReorderConditions($table)
{
$db = $this->getDatabase();
return [
$db->quoteName('type') . ' = ' . $db->quote($table->type),
$db->quoteName('folder') . ' = ' . $db->quote($table->folder),
];
}
/**
* Override method to save the form data.
*
* @param array $data The form data.
*
* @return boolean True on success.
*
* @since 1.6
*/
public function save($data)
{
// Setup type.
$data['type'] = 'plugin';
return parent::save($data);
}
/**
* Get the necessary data to load an item help screen.
*
* @return object An object with key, url, and local properties for loading the item help screen.
*
* @since 1.6
*/
public function getHelp()
{
return (object) ['key' => $this->helpKey, 'url' => $this->helpURL];
}
/**
* Custom clean cache method, plugins are cached in 2 places for different clients.
*
* @param string $group Cache group name.
* @param integer $clientId No longer used, will be removed without replacement
* @deprecated 4.3 will be removed in 6.0
*
* @return void
*
* @since 1.6
*/
protected function cleanCache($group = null, $clientId = 0)
{
parent::cleanCache('com_plugins');
}
}

View File

@ -0,0 +1,291 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\Model;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\Database\DatabaseQuery;
use Joomla\Database\ParameterType;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Methods supporting a list of plugin records.
*
* @since 1.6
*/
class PluginsModel extends ListModel
{
/**
* Constructor.
*
* @param array $config An optional associative array of configuration settings.
* @param ?MVCFactoryInterface $factory The factory.
*
* @see \Joomla\CMS\MVC\Model\BaseDatabaseModel
* @since 3.2
*/
public function __construct($config = [], MVCFactoryInterface $factory = null)
{
if (empty($config['filter_fields'])) {
$config['filter_fields'] = [
'extension_id', 'a.extension_id',
'name', 'a.name',
'folder', 'a.folder',
'element', 'a.element',
'checked_out', 'a.checked_out',
'checked_out_time', 'a.checked_out_time',
'state', 'a.state',
'enabled', 'a.enabled',
'access', 'a.access', 'access_level',
'ordering', 'a.ordering',
'client_id', 'a.client_id',
];
}
parent::__construct($config, $factory);
}
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* @param string $ordering An optional ordering field.
* @param string $direction An optional direction (asc|desc).
*
* @return void
*
* @since 1.6
*/
protected function populateState($ordering = 'folder', $direction = 'asc')
{
// Load the parameters.
$params = ComponentHelper::getParams('com_plugins');
$this->setState('params', $params);
// List state information.
parent::populateState($ordering, $direction);
}
/**
* Method to get a store id based on model configuration state.
*
* This is necessary because the model is used by the component and
* different modules that might need different sets of data or different
* ordering requirements.
*
* @param string $id A prefix for the store id.
*
* @return string A store id.
*/
protected function getStoreId($id = '')
{
// Compile the store id.
$id .= ':' . $this->getState('filter.search');
$id .= ':' . $this->getState('filter.access');
$id .= ':' . $this->getState('filter.enabled');
$id .= ':' . $this->getState('filter.folder');
$id .= ':' . $this->getState('filter.element');
return parent::getStoreId($id);
}
/**
* Returns an object list.
*
* @param DatabaseQuery|string $query A database query object.
* @param integer $limitstart Offset.
* @param integer $limit The number of records.
*
* @return object[]
*/
protected function _getList($query, $limitstart = 0, $limit = 0)
{
$search = $this->getState('filter.search');
$ordering = $this->getState('list.ordering', 'ordering');
// If "Sort Table By:" is not set, set ordering to name
if ($ordering == '') {
$ordering = 'name';
}
$db = $this->getDatabase();
if ($ordering == 'name' || (!empty($search) && stripos($search, 'id:') !== 0)) {
$db->setQuery($query);
$result = $db->loadObjectList();
$this->translate($result);
if (!empty($search)) {
$escapedSearchString = $this->refineSearchStringToRegex($search, '/');
foreach ($result as $i => $item) {
if (!preg_match("/$escapedSearchString/i", $item->name)) {
unset($result[$i]);
}
}
}
$orderingDirection = strtolower($this->getState('list.direction'));
$direction = ($orderingDirection == 'desc') ? -1 : 1;
$result = ArrayHelper::sortObjects($result, $ordering, $direction, true, true);
$total = \count($result);
$this->cache[$this->getStoreId('getTotal')] = $total;
if ($total < $limitstart) {
$limitstart = 0;
}
$this->cache[$this->getStoreId('getStart')] = $limitstart;
return \array_slice($result, $limitstart, $limit ?: null);
}
if ($ordering === 'ordering') {
$query->order('a.folder ASC');
$ordering = 'a.ordering';
}
$query->order($db->quoteName($ordering) . ' ' . $this->getState('list.direction'));
if ($ordering === 'folder') {
$query->order('a.ordering ASC');
}
$result = parent::_getList($query, $limitstart, $limit);
$this->translate($result);
return $result;
}
/**
* Translate a list of objects.
*
* @param object[] &$items The array of objects.
*
* @return void
*/
protected function translate(&$items)
{
$lang = Factory::getLanguage();
foreach ($items as &$item) {
$source = JPATH_PLUGINS . '/' . $item->folder . '/' . $item->element;
$extension = 'plg_' . $item->folder . '_' . $item->element;
$lang->load($extension . '.sys', JPATH_ADMINISTRATOR)
|| $lang->load($extension . '.sys', $source);
$item->name = Text::_($item->name);
}
}
/**
* Build an SQL query to load the list data.
*
* @return DatabaseQuery
*/
protected function getListQuery()
{
// Create a new query object.
$db = $this->getDatabase();
$query = $db->getQuery(true);
// Select the required fields from the table.
$query->select(
$this->getState(
'list.select',
'a.extension_id , a.name, a.element, a.folder, a.checked_out, a.checked_out_time,' .
' a.enabled, a.access, a.ordering, a.note'
)
)
->from($db->quoteName('#__extensions') . ' AS a')
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'));
// Join over the users for the checked out user.
$query->select('uc.name AS editor')
->join('LEFT', '#__users AS uc ON uc.id=a.checked_out');
// Join over the asset groups.
$query->select('ag.title AS access_level')
->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access');
// Filter by access level.
if ($access = $this->getState('filter.access')) {
$access = (int) $access;
$query->where($db->quoteName('a.access') . ' = :access')
->bind(':access', $access, ParameterType::INTEGER);
}
// Filter by published state.
$published = (string) $this->getState('filter.enabled');
if (is_numeric($published)) {
$published = (int) $published;
$query->where($db->quoteName('a.enabled') . ' = :published')
->bind(':published', $published, ParameterType::INTEGER);
} elseif ($published === '') {
$query->whereIn($db->quoteName('a.enabled'), [0, 1]);
}
// Filter by state.
$query->where('a.state >= 0');
// Filter by folder.
if ($folder = $this->getState('filter.folder')) {
$query->where($db->quoteName('a.folder') . ' = :folder')
->bind(':folder', $folder);
}
// Filter by element.
if ($element = $this->getState('filter.element')) {
$query->where($db->quoteName('a.element') . ' = :element')
->bind(':element', $element);
}
// Filter by search in name or id.
$search = $this->getState('filter.search');
if (!empty($search)) {
if (stripos($search, 'id:') === 0) {
$ids = (int) substr($search, 3);
$query->where($db->quoteName('a.extension_id') . ' = :id');
$query->bind(':id', $ids, ParameterType::INTEGER);
}
}
return $query;
}
/**
* Method to get the data that should be injected in the form.
*
* @return mixed The data for the form.
*
* @since 3.5
*/
protected function loadFormData()
{
$data = parent::loadFormData();
// Set the selected filter values for pages that use the Layouts for filtering
$data->list['sortTable'] = $this->state->get('list.ordering');
$data->list['directionTable'] = $this->state->get('list.direction');
return $data;
}
}

View File

@ -0,0 +1,118 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\View\Plugin;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\ContentHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Object\CMSObject;
use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* View to edit a plugin.
*
* @since 1.5
*/
class HtmlView extends BaseHtmlView
{
/**
* The item object for the newsfeed
*
* @var CMSObject
*/
protected $item;
/**
* The form object for the newsfeed
*
* @var \Joomla\CMS\Form\Form
*/
protected $form;
/**
* The model state of the newsfeed
*
* @var \Joomla\Registry\Registry
*/
protected $state;
/**
* Display the view.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return void
*/
public function display($tpl = null)
{
$this->state = $this->get('State');
$this->item = $this->get('Item');
$this->form = $this->get('Form');
// Check for errors.
if (\count($errors = $this->get('Errors'))) {
throw new GenericDataException(implode("\n", $errors), 500);
}
$this->addToolbar();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 1.6
*/
protected function addToolbar()
{
Factory::getApplication()->getInput()->set('hidemainmenu', true);
$canDo = ContentHelper::getActions('com_plugins');
$toolbar = Toolbar::getInstance();
ToolbarHelper::title(Text::sprintf('COM_PLUGINS_MANAGER_PLUGIN', Text::_($this->item->name)), 'plug plugin');
// If not checked out, can save the item.
if ($canDo->get('core.edit')) {
$toolbar->apply('plugin.apply');
$toolbar->save('plugin.save');
}
$toolbar->cancel('plugin.cancel');
$toolbar->divider();
// Get the help information for the plugin item.
$lang = $this->getLanguage();
$help = $this->get('Help');
if ($help->url && $lang->hasKey($help->url)) {
$debug = $lang->setDebug(false);
$url = Text::_($help->url);
$lang->setDebug($debug);
} else {
$url = null;
}
$toolbar->inlinehelp();
$toolbar->help($help->key, false, $url);
}
}

View File

@ -0,0 +1,119 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Plugins\Administrator\View\Plugins;
use Joomla\CMS\Helper\ContentHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* View class for a list of plugins.
*
* @since 1.5
*/
class HtmlView extends BaseHtmlView
{
/**
* An array of items
*
* @var array
*/
protected $items;
/**
* The pagination object
*
* @var \Joomla\CMS\Pagination\Pagination
*/
protected $pagination;
/**
* The model state
*
* @var \Joomla\Registry\Registry
*/
protected $state;
/**
* Form object for search filters
*
* @var \Joomla\CMS\Form\Form
* @since 4.0.0
*/
public $filterForm;
/**
* The active search filters
*
* @var array
* @since 4.0.0
*/
public $activeFilters;
/**
* Display the view.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return void
*/
public function display($tpl = null)
{
$this->items = $this->get('Items');
$this->pagination = $this->get('Pagination');
$this->state = $this->get('State');
$this->filterForm = $this->get('FilterForm');
$this->activeFilters = $this->get('ActiveFilters');
// Check for errors.
if (\count($errors = $this->get('Errors'))) {
throw new GenericDataException(implode("\n", $errors), 500);
}
$this->addToolbar();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 1.6
*/
protected function addToolbar()
{
$canDo = ContentHelper::getActions('com_plugins');
$toolbar = Toolbar::getInstance();
ToolbarHelper::title(Text::_('COM_PLUGINS_MANAGER_PLUGINS'), 'plug plugin');
if ($canDo->get('core.edit.state')) {
$toolbar->publish('plugins.publish', 'JTOOLBAR_ENABLE')->listCheck(true);
$toolbar->unpublish('plugins.unpublish', 'JTOOLBAR_DISABLE')->listCheck(true);
$toolbar->checkin('plugins.checkin');
}
if ($canDo->get('core.admin')) {
$toolbar->preferences('com_plugins');
}
$toolbar->help('Plugins');
}
}

View File

@ -0,0 +1,137 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2009 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\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Router\Route;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('keepalive')
->useScript('form.validate');
$this->fieldsets = $this->form->getFieldsets('params');
$this->useCoreUI = true;
$input = Factory::getApplication()->getInput();
// In case of modal
$isModal = $input->get('layout') === 'modal';
$layout = $isModal ? 'modal' : 'edit';
$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : '';
?>
<form action="<?php echo Route::_('index.php?option=com_plugins&view=plugin&layout=' . $layout . $tmpl . '&extension_id=' . (int) $this->item->extension_id); ?>" method="post" name="adminForm" id="style-form" aria-label="<?php echo Text::_('COM_PLUGINS_FORM_EDIT'); ?>" class="form-validate">
<div class="main-card">
<?php echo HTMLHelper::_('uitab.startTabSet', 'myTab', ['active' => 'general', 'recall' => true, 'breakpoint' => 768]); ?>
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'general', Text::_('COM_PLUGINS_PLUGIN')); ?>
<div class="row mt-2">
<div class="col-lg-9">
<?php if ($this->item->xml) : ?>
<?php if ($this->item->xml->description) : ?>
<h2>
<?php
if ($this->item->xml) {
echo ($text = (string) $this->item->xml->name) ? Text::_($text) : $this->item->name;
} else {
echo Text::_('COM_PLUGINS_XML_ERR');
}
?>
</h2>
<div class="info-labels mb-1">
<span class="badge bg-secondary">
<?php echo $this->form->getValue('folder'); ?>
</span> /
<span class="badge bg-secondary">
<?php echo $this->form->getValue('element'); ?>
</span>
</div>
<div>
<?php
$this->fieldset = 'description';
$short_description = Text::_($this->item->xml->description);
$long_description = LayoutHelper::render('joomla.edit.fieldset', $this);
if (!$long_description) {
$truncated = HTMLHelper::_('string.truncate', $short_description, 550, true, false);
if (strlen($truncated) > 500) {
$long_description = $short_description;
$short_description = HTMLHelper::_('string.truncate', $truncated, 250);
if ($short_description == $long_description) {
$long_description = '';
}
}
}
?>
<p><?php echo $short_description; ?></p>
<?php if ($long_description) : ?>
<p class="readmore">
<a href="#" onclick="document.querySelector('[aria-controls=description]').click();">
<?php echo Text::_('JGLOBAL_SHOW_FULL_DESCRIPTION'); ?>
</a>
</p>
<?php endif; ?>
</div>
<?php endif; ?>
<?php else : ?>
<div class="alert alert-danger">
<span class="icon-exclamation-triangle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('ERROR'); ?></span>
<?php echo Text::_('COM_PLUGINS_XML_ERR'); ?>
</div>
<?php endif; ?>
<?php
$this->fieldset = 'basic';
$html = LayoutHelper::render('joomla.edit.fieldset', $this);
echo $html ? '<hr>' . $html : '';
?>
</div>
<div class="col-lg-3">
<?php
// Set main fields.
$this->fields = [
'enabled',
'access',
'ordering',
'folder',
'element',
'note',
]; ?>
<?php echo LayoutHelper::render('joomla.edit.global', $this); ?>
</div>
</div>
<?php echo HTMLHelper::_('uitab.endTab'); ?>
<?php if (isset($long_description) && $long_description != '') : ?>
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'description', Text::_('JGLOBAL_FIELDSET_DESCRIPTION')); ?>
<?php echo $long_description; ?>
<?php echo HTMLHelper::_('uitab.endTab'); ?>
<?php endif; ?>
<?php
$this->fieldsets = [];
$this->ignore_fieldsets = ['basic', 'description'];
echo LayoutHelper::render('joomla.edit.params', $this);
?>
<?php echo HTMLHelper::_('uitab.endTabSet'); ?>
</div>
<input type="hidden" name="task" value="">
<?php echo HTMLHelper::_('form.token'); ?>
</form>

View File

@ -0,0 +1,22 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
?>
<button id="applyBtn" type="button" class="hidden" onclick="Joomla.submitbutton('plugin.apply');"></button>
<button id="saveBtn" type="button" class="hidden" onclick="Joomla.submitbutton('plugin.save');"></button>
<button id="closeBtn" type="button" class="hidden" onclick="Joomla.submitbutton('plugin.cancel');"></button>
<div class="container-popup">
<?php $this->setLayout('edit'); ?>
<?php echo $this->loadTemplate(); ?>
</div>

View File

@ -0,0 +1,151 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_plugins
*
* @copyright (C) 2007 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\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Session\Session;
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('table.columns')
->useScript('multiselect');
$user = $this->getCurrentUser();
$listOrder = $this->escape($this->state->get('list.ordering'));
$listDirn = $this->escape($this->state->get('list.direction'));
$saveOrder = $listOrder == 'ordering';
if ($saveOrder) {
$saveOrderingUrl = 'index.php?option=com_plugins&task=plugins.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1';
HTMLHelper::_('draggablelist.draggable');
}
?>
<form action="<?php echo Route::_('index.php?option=com_plugins&view=plugins'); ?>" method="post" name="adminForm" id="adminForm">
<div id="j-main-container" class="j-main-container">
<?php echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this]); ?>
<?php if (empty($this->items)) : ?>
<div class="alert alert-info">
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else : ?>
<table class="table" id="pluginList">
<caption class="visually-hidden">
<?php echo Text::_('COM_PLUGINS_TABLE_CAPTION'); ?>,
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
</caption>
<thead>
<tr>
<td class="w-1 text-center">
<?php echo HTMLHelper::_('grid.checkall'); ?>
</td>
<th scope="col" class="w-1 text-center d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', '', 'ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING', 'icon-sort'); ?>
</th>
<th scope="col" class="w-1 text-center">
<?php echo HTMLHelper::_('searchtools.sort', 'JSTATUS', 'enabled', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="title">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_PLUGINS_NAME_HEADING', 'name', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-10 d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_PLUGINS_FOLDER_HEADING', 'folder', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-10 d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_PLUGINS_ELEMENT_HEADING', 'element', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-10 d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ACCESS', 'access', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-5 d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ID', 'extension_id', $listDirn, $listOrder); ?>
</th>
</tr>
</thead>
<tbody <?php if ($saveOrder) :
?> class="js-draggable" data-url="<?php echo $saveOrderingUrl; ?>" data-direction="<?php echo strtolower($listDirn); ?>" data-nested="true"<?php
endif; ?>>
<?php foreach ($this->items as $i => $item) :
$ordering = ($listOrder == 'ordering');
$canEdit = $user->authorise('core.edit', 'com_plugins');
$canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || is_null($item->checked_out);
$canChange = $user->authorise('core.edit.state', 'com_plugins') && $canCheckin;
?>
<tr class="row<?php echo $i % 2; ?>" data-draggable-group="<?php echo $item->folder; ?>">
<td class="text-center">
<?php echo HTMLHelper::_('grid.id', $i, $item->extension_id, false, 'cid', 'cb', $item->name); ?>
</td>
<td class="text-center d-none d-md-table-cell">
<?php
$iconClass = '';
if (!$canChange) {
$iconClass = ' inactive';
} elseif (!$saveOrder) {
$iconClass = ' inactive" title="' . Text::_('JORDERINGDISABLED');
}
?>
<span class="sortable-handler<?php echo $iconClass; ?>">
<span class="icon-ellipsis-v" aria-hidden="true"></span>
</span>
<?php if ($canChange && $saveOrder) : ?>
<input type="text" name="order[]" size="5" value="<?php echo $item->ordering; ?>" class="width-20 text-area-order hidden">
<?php endif; ?>
</td>
<td class="text-center">
<?php echo HTMLHelper::_('jgrid.published', $item->enabled, $i, 'plugins.', $canChange); ?>
</td>
<th scope="row">
<?php if ($item->checked_out) : ?>
<?php echo HTMLHelper::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'plugins.', $canCheckin); ?>
<?php endif; ?>
<?php if ($canEdit) : ?>
<a href="<?php echo Route::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . (int) $item->extension_id); ?>" title="<?php echo Text::_('JACTION_EDIT'); ?> <?php echo $this->escape($item->name); ?>">
<?php echo $item->name; ?></a>
<?php if (!empty($item->note)) : ?>
<div class="small">
<?php echo Text::sprintf('JGLOBAL_LIST_NOTE', $this->escape($item->note)); ?>
</div>
<?php endif; ?>
<?php else : ?>
<?php echo $item->name; ?>
<?php endif; ?>
</th>
<td class="small d-none d-md-table-cell">
<?php echo $this->escape($item->folder); ?>
</td>
<td class="small d-none d-md-table-cell">
<?php echo $this->escape($item->element); ?>
</td>
<td class="small d-none d-md-table-cell">
<?php echo $this->escape($item->access_level); ?>
</td>
<td class="d-none d-md-table-cell">
<?php echo (int) $item->extension_id; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php // load the pagination. ?>
<?php echo $this->pagination->getListFooter(); ?>
<?php endif; ?>
<input type="hidden" name="task" value="">
<input type="hidden" name="boxchecked" value="0">
<?php echo HTMLHelper::_('form.token'); ?>
</div>
</form>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<layout title="COM_PLUGINS_PLUGINS_VIEW_DEFAULT_TITLE">
<message>
<![CDATA[COM_PLUGINS_PLUGINS_VIEW_DEFAULT_DESC]]>
</message>
</layout>
</metadata>