diff --git a/administrator/components/com_menus/Field/MenuItemByComponentField.php b/administrator/components/com_menus/Field/MenuItemByComponentField.php new file mode 100644 index 0000000000000..b1898b1e68e23 --- /dev/null +++ b/administrator/components/com_menus/Field/MenuItemByComponentField.php @@ -0,0 +1,324 @@ +$name; + } + + return parent::__get($name); + } + + /** + * Method to set certain otherwise inaccessible properties of the form field object. + * + * @param string $name The property name for which to set the value. + * @param mixed $value The value of the property. + * + * @return void + * + * @since 3.8.0 + */ + public function __set($name, $value) + { + switch ($name) + { + case 'menuType': + $this->menuType = (string) $value; + break; + + case 'clientId': + $this->clientId = (int) $value; + break; + + case 'componentId': + $this->componentId = (int) $value; + break; + + case 'language': + case 'published': + case 'disable': + $value = (string) $value; + $this->$name = $value ? explode(',', $value) : array(); + break; + + default: + parent::__set($name, $value); + } + + } + + /** + * Method to attach a JForm object to the field. + * + * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * + * @return boolean True on success. + * + * @see JFormField::setup() + * @since 3.8.0 + */ + public function setup(\SimpleXMLElement $element, $value, $group = null) + { + $result = parent::setup($element, $value, $group); + + if ($result == true) + { + $menuType = (string) $this->element['menu_type']; + + if (!$menuType) + { + $app = Factory::getApplication(); + $currentMenuType = $app->getUserState('com_menus.items.menutype', ''); + $menuType = $app->input->getString('menutype', $currentMenuType); + } + + $this->menuType = $menuType; + $this->clientId = (int) $this->element['client_id']; + $this->componentId = (int) $this->element['component_id']; + $this->published = $this->element['published'] ? explode(',', (string) $this->element['published']) : array(); + $this->disable = $this->element['disable'] ? explode(',', (string) $this->element['disable']) : array(); + $this->language = $this->element['language'] ? explode(',', (string) $this->element['language']) : array(); + } + + return $result; + } + + /** + * Method to get the field option groups. + * + * @return array The field option objects as a nested array in groups. + * + * @since 3.8.0 + */ + protected function getGroups() + { + $lang = Factory::getLanguage(); + $extension = 'com_menu'; + $base_dir = JPATH_SITE; + $language_tag = 'en-GB'; + $reload = true; + $lang->load($extension, $base_dir, $language_tag, $reload); + + + $groups = array(); + + $menuType = $this->menuType; + + // Get the menu items. + $items = MenusHelper::getMenuLinks($menuType, 0, 0, $this->published, $this->language, $this->clientId); + + // Build group for a specific menu type. + if ($menuType) + { + + // If the menutype is empty, group the items by menutype. + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__menu_types')) + ->where($db->quoteName('menutype') . ' = ' . $db->quote($menuType)); + $db->setQuery($query); + + + try + { + $menuTitle = $db->loadResult(); + } + catch (\RuntimeException $e) + { + $menuTitle = $menuType; + } + + // Initialize the group. + $groups[$menuTitle] = array(); + + // Build the options array. + foreach ($items as $key => $link) + { + $lang->load($link->componentname . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($link->componentname . '.sys', JPATH_ADMINISTRATOR . '/components/' . $link->componentname, null, false, true); + + + // Unset if item is menu_item_root + if ($link->text === 'Menu_Item_Root') + { + unset($items[$key]); + continue; + } + + $levelPrefix = str_repeat('- ', max(0, $link->level - 1)); + + + $link->componentname = Text::_($link->componentname); + $link->component_id = $link->component_id . ":" . $link->menutype; + + $groups[$menuTitle][] = HTMLHelper::_('select.option', + $link->component_id, $levelPrefix . $link->componentname, + 'value', + 'text', + in_array($link->type, $this->disable) + ); + } + } + // Build groups for all menu types. + else + { + // Build the groups arrays. + foreach ($items as $menu) + { + + // Initialize the group. + $groups[$menu->title] = array(); + + // Build the options array. + foreach ($menu->links as $link) + { + $lang->load($link->componentname . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($link->componentname . '.sys', JPATH_ADMINISTRATOR . '/components/' . $link->componentname, null, false, true); + + $levelPrefix = str_repeat('- ', $link->level - 1); + + $link->componentname = Text::_($link->componentname); + $link->component_id = $link->component_id . ":" . $link->menutype; + + $groups[$menu->title][] = HTMLHelper::_('select.option', + $link->component_id, + Text::_($link->componentname), + 'value', + 'text', + in_array($link->type, $this->disable) + ); + } + } + } + + $tmp_groups = array(); + + foreach ($groups as $key => $currentGroup) + { + // Build temporary array for array_unique + $tmp = array(); + foreach ($currentGroup as $k => $v) + $tmp[$k] = $v->value; + + // Find duplicates in temporary array + $tmp = array_unique($tmp); + + // Remove the duplicates from original array + foreach ($currentGroup as $k => $v) + { + if (!array_key_exists($k, $tmp)) + unset($currentGroup[$k]); + } + $tmp_groups[$key] = $currentGroup; + } + + + // Merge any additional groups in the XML definition. + $groups = array_merge(parent::getGroups(), $tmp_groups); + + return $groups; + } +} diff --git a/administrator/components/com_menus/Helper/MenusHelper.php b/administrator/components/com_menus/Helper/MenusHelper.php index b34d78b00bd8f..8dc905afc359b 100644 --- a/administrator/components/com_menus/Helper/MenusHelper.php +++ b/administrator/components/com_menus/Helper/MenusHelper.php @@ -159,7 +159,8 @@ public static function getMenuLinks($menuType = null, $parentId = 0, $mode = 0, a.template_style_id, a.checked_out, a.language, - a.lft' + a.lft, + a.component_id' ) ->from('#__menu AS a'); @@ -268,9 +269,6 @@ public static function getMenuLinks($menuType = null, $parentId = 0, $mode = 0, if (isset($rlu[$link->menutype])) { $rlu[$link->menutype]->links[] = & $link; - - // Cleanup garbage. - unset($link->menutype); } } diff --git a/administrator/components/com_menus/Model/ItemsModel.php b/administrator/components/com_menus/Model/ItemsModel.php index 8b04eb16d37c1..5d0fae3e08205 100644 --- a/administrator/components/com_menus/Model/ItemsModel.php +++ b/administrator/components/com_menus/Model/ItemsModel.php @@ -55,7 +55,8 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu 'client_id', 'a.client_id', 'home', 'a.home', 'parent_id', 'a.parent_id', - 'a.ordering' + 'parent_id', 'a.parent_id', + 'component_id', 'a.component_id' ); $assoc = Associations::isEnabled(); @@ -111,6 +112,9 @@ protected function populateState($ordering = 'a.lft', $direction = 'asc') $parentId = $this->getUserStateFromRequest($this->context . '.filter.parent_id', 'filter_parent_id'); $this->setState('filter.parent_id', $parentId); + $componentId = $this->getUserStateFromRequest($this->context . '.filter.component_id', 'filter_component_id'); + $this->setState('filter.component_id', $componentId); + $level = $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level'); $this->setState('filter.level', $level); @@ -361,6 +365,9 @@ protected function getListQuery() // Filter on the published state. $published = $this->getState('filter.published'); + // Filter on the component id state. + $componentId = $this->getState('filter.component_id'); + if (is_numeric($published)) { $query->where('a.published = ' . (int) $published); @@ -370,6 +377,15 @@ protected function getListQuery() $query->where('a.published IN (0, 1)'); } + if (!empty($componentId)){ + if (is_numeric(explode(":",$componentId)[0])) + { + $query->where('a.component_id = ' . (int)explode(":",$componentId)[0]); + + $query->where("a.menutype = '" . (string)explode(":",$componentId)[1]."'"); + } + } + // Filter by search in title, alias or id if ($search = trim($this->getState('filter.search'))) { diff --git a/administrator/components/com_menus/forms/filter_items.xml b/administrator/components/com_menus/forms/filter_items.xml index 94740135d3686..02ca9e09c2e76 100644 --- a/administrator/components/com_menus/forms/filter_items.xml +++ b/administrator/components/com_menus/forms/filter_items.xml @@ -71,6 +71,15 @@ > + + +