diff --git a/administrator/components/com_installer/forms/filter_manage.xml b/administrator/components/com_installer/forms/filter_manage.xml index acf8a4dcb9e34..977a73c9ae01d 100644 --- a/administrator/components/com_installer/forms/filter_manage.xml +++ b/administrator/components/com_installer/forms/filter_manage.xml @@ -28,6 +28,16 @@ + + + + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\Component\Installer\Administrator\Field; + +use Joomla\CMS\Form\Field\ListField; +use Joomla\Component\Installer\Administrator\Helper\InstallerHelper; + +/** + * Package field. + * + * Selects the extension ID of an extension of the "package" type. + * + * @since __DEPLOY_VERSION__ + */ +class PackageField extends ListField +{ + /** + * Method to get the field options. + * + * @return array The field option objects. + * @since __DEPLOY_VERSION__ + */ + protected function getOptions() + { + $options = InstallerHelper::getPackageOptions(); + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_installer/src/Helper/InstallerHelper.php b/administrator/components/com_installer/src/Helper/InstallerHelper.php index 83c7f39d6efa9..501b9adec5642 100644 --- a/administrator/components/com_installer/src/Helper/InstallerHelper.php +++ b/administrator/components/com_installer/src/Helper/InstallerHelper.php @@ -16,6 +16,7 @@ use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Object\CMSObject; +use Joomla\Database\DatabaseDriver; use Joomla\Database\ParameterType; use SimpleXMLElement; @@ -119,6 +120,66 @@ public static function getStateOptions() return $options; } + /** + * Get a list of filter options for extensions of the "package" type. + * + * @return array + * @since __DEPLOY_VERSION__ + */ + public static function getPackageOptions(): array + { + $options = []; + + /** @var DatabaseDriver $db The application's database driver object */ + $db = Factory::getContainer()->get(DatabaseDriver::class); + $query = $db->getQuery(true) + ->select( + $db->quoteName( + [ + 'extension_id', + 'name', + 'element', + ] + ) + ) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('package')); + $extensions = $db->setQuery($query)->loadObjectList() ?: []; + + if (empty($extensions)) + { + return $options; + } + + $language = Factory::getApplication()->getLanguage(); + $arrayKeys = array_map( + function (object $entry) use ($language): string + { + $language->load($entry->element, JPATH_ADMINISTRATOR); + + return Text::_($entry->name); + }, + $extensions + ); + $arrayValues = array_map( + function (object $entry): int + { + return $entry->extension_id; + }, + $extensions + ); + + $extensions = array_combine($arrayKeys, $arrayValues); + ksort($extensions); + + foreach ($extensions as $label => $id) + { + $options[] = HTMLHelper::_('select.option', $id, $label); + } + + return $options; + } + /** * Get a list of filter options for the application statuses. * diff --git a/administrator/components/com_installer/src/Model/ManageModel.php b/administrator/components/com_installer/src/Model/ManageModel.php index 456cc38e76100..dccc8903d5769 100644 --- a/administrator/components/com_installer/src/Model/ManageModel.php +++ b/administrator/components/com_installer/src/Model/ManageModel.php @@ -81,6 +81,7 @@ protected function populateState($ordering = 'name', $direction = 'asc') // Load the filter state. $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); + $this->setState('filter.package_id', $this->getUserStateFromRequest($this->context . '.filter.package_id', 'filter_package_id', null, 'int')); $this->setState('filter.status', $this->getUserStateFromRequest($this->context . '.filter.status', 'filter_status', '', 'string')); $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); @@ -330,11 +331,12 @@ protected function getListQuery() ->where('state = 0'); // Process select filters. - $status = $this->getState('filter.status', ''); - $type = $this->getState('filter.type'); - $clientId = $this->getState('filter.client_id', ''); - $folder = $this->getState('filter.folder'); - $core = $this->getState('filter.core', ''); + $status = $this->getState('filter.status', ''); + $type = $this->getState('filter.type'); + $clientId = $this->getState('filter.client_id', ''); + $folder = $this->getState('filter.folder'); + $core = $this->getState('filter.core', ''); + $packageId = $this->getState('filter.package_id', ''); if ($status !== '') { @@ -368,6 +370,16 @@ protected function getListQuery() ->bind(':clientid', $clientId, ParameterType::INTEGER); } + if ($packageId !== '') + { + $packageId = (int) $packageId; + $query->where( + '((' . $db->quoteName('package_id') . ' = :packageId1) OR ' + . '(' . $db->quoteName('extension_id') . ' = :packageId2))' + ) + ->bind([':packageId1',':packageId2'], $packageId, ParameterType::INTEGER); + } + if ($folder) { $folder = $folder === '*' ? '' : $folder; diff --git a/administrator/language/en-GB/com_installer.ini b/administrator/language/en-GB/com_installer.ini index 7ecb634a9d45a..7012fa0c5d09e 100644 --- a/administrator/language/en-GB/com_installer.ini +++ b/administrator/language/en-GB/com_installer.ini @@ -102,6 +102,8 @@ COM_INSTALLER_LANGUAGES_AVAILABLE_LANGUAGES="Available Languages" COM_INSTALLER_LANGUAGES_FILTER_SEARCH_DESC="Search in language name and language tag." COM_INSTALLER_LANGUAGES_FILTER_SEARCH_LABEL="Search Languages" COM_INSTALLER_LANGUAGES_TABLE_CAPTION="Table of Available Languages" +COM_INSTALLER_MANAGE_FILTER_PACKAGE_ID_LABEL="Package" +COM_INSTALLER_MANAGE_FILTER_PACKAGE_ID_DESC="Search for a package extension and extensions included with that package extension." COM_INSTALLER_MANAGE_FILTER_SEARCH_DESC="Search in extension name. Prefix with ID: to search for an extension ID." COM_INSTALLER_MANAGE_FILTER_SEARCH_LABEL="Search Extensions" COM_INSTALLER_MANAGE_TABLE_CAPTION="Table of Extensions" @@ -280,6 +282,7 @@ COM_INSTALLER_VALUE_CORE_SELECT="- Select Extensions -" COM_INSTALLER_VALUE_CORE_YES="Core Extensions" COM_INSTALLER_VALUE_FOLDER_NONAPPLICABLE="N/A" COM_INSTALLER_VALUE_FOLDER_SELECT="- Select Folder -" +COM_INSTALLER_VALUE_PACKAGE_ID_SELECT="- Select Package -" COM_INSTALLER_VALUE_STATE_SELECT="- Select Status -" COM_INSTALLER_VALUE_SUPPORTED_EXISTS="Download Key valid" COM_INSTALLER_VALUE_SUPPORTED_MISSING="Download Key invalid"