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 @@
>
+
+
+