diff --git a/administrator/components/com_menus/models/fields/menuitembytype.php b/administrator/components/com_menus/models/fields/menuitembytype.php
new file mode 100644
index 0000000000000..059e0308b0f44
--- /dev/null
+++ b/administrator/components/com_menus/models/fields/menuitembytype.php
@@ -0,0 +1,278 @@
+$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 the the value.
+ * @param mixed $value The value of the property.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function __set($name, $value)
+ {
+ switch ($name)
+ {
+ case 'menuType':
+ $this->menuType = (string) $value;
+ break;
+
+ case 'clientId':
+ $this->clientId = (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 __DEPLOY_VERSION__
+ */
+ 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 = JFactory::getApplication('administrator');
+ $currentMenuType = $app->getUserState('com_menus.items.menutype', '');
+ $menuType = $app->input->getString('menutype', $currentMenuType);
+ }
+
+ $this->menuType = $menuType;
+ $this->clientId = (int) $this->element['client_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 __DEPLOY_VERSION__
+ */
+ protected function getGroups()
+ {
+ $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 = JFactory::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)
+ {
+ // 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));
+
+ // Displays language code if not set to All
+ if ($link->language !== '*')
+ {
+ $lang = ' (' . $link->language . ')';
+ }
+ else
+ {
+ $lang = '';
+ }
+
+ $groups[$menuTitle][] = JHtml::_('select.option',
+ $link->value, $levelPrefix . $link->text . $lang,
+ '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)
+ {
+ $levelPrefix = str_repeat('- ', $link->level - 1);
+
+ // Displays language code if not set to All
+ if ($link->language !== '*')
+ {
+ $lang = ' (' . $link->language . ')';
+ }
+ else
+ {
+ $lang = '';
+ }
+
+ $groups[$menu->title][] = JHtml::_('select.option',
+ $link->value,
+ $levelPrefix . $link->text . $lang,
+ 'value',
+ 'text',
+ in_array($link->type, $this->disable)
+ );
+ }
+ }
+ }
+
+ // Merge any additional groups in the XML definition.
+ $groups = array_merge(parent::getGroups(), $groups);
+
+ return $groups;
+ }
+}
diff --git a/administrator/components/com_menus/models/forms/filter_items.xml b/administrator/components/com_menus/models/forms/filter_items.xml
index 2e6e14f3906b1..28672454e21f4 100644
--- a/administrator/components/com_menus/models/forms/filter_items.xml
+++ b/administrator/components/com_menus/models/forms/filter_items.xml
@@ -74,6 +74,15 @@
>
+
+
+
getUserState('com_menus.items.filter');
+ $data['parent_id'] = (isset($filters['parent_id']) ? $filters['parent_id'] : null);
$data['published'] = (isset($filters['published']) ? $filters['published'] : null);
$data['language'] = (isset($filters['language']) ? $filters['language'] : null);
$data['access'] = (!empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access'));
diff --git a/administrator/components/com_menus/models/items.php b/administrator/components/com_menus/models/items.php
index 9febfb9e122b9..20fad614a1e88 100644
--- a/administrator/components/com_menus/models/items.php
+++ b/administrator/components/com_menus/models/items.php
@@ -44,6 +44,7 @@ public function __construct($config = array())
'path', 'a.path',
'client_id', 'a.client_id',
'home', 'a.home',
+ 'parent_id', 'a.parent_id',
'a.ordering'
);
@@ -90,9 +91,6 @@ protected function populateState($ordering = 'a.lft', $direction = 'asc')
$this->context .= '.' . $forcedLanguage;
}
- $parentId = $this->getUserStateFromRequest($this->context . '.filter.parent_id', 'filter_parent_id');
- $this->setState('filter.parent_id', $parentId);
-
$search = $this->getUserStateFromRequest($this->context . '.search', 'filter_search');
$this->setState('filter.search', $search);
diff --git a/administrator/language/en-GB/en-GB.com_menus.ini b/administrator/language/en-GB/en-GB.com_menus.ini
index 3ec887b94e82b..aea1ebe5a6afd 100644
--- a/administrator/language/en-GB/en-GB.com_menus.ini
+++ b/administrator/language/en-GB/en-GB.com_menus.ini
@@ -37,6 +37,9 @@ COM_MENUS_FIELD_VALUE_NEW_WITH_NAV="New Window With Navigation"
COM_MENUS_FIELD_VALUE_NEW_WITHOUT_NAV="New Without Navigation"
COM_MENUS_FIELD_VALUE_PARENT="Parent"
COM_MENUS_FIELDSET_RULES="Permissions"
+COM_MENUS_FILTER_PARENT_MENU_ITEM_DESC="Filters the menu items list where the parent is this selected menu item."
+COM_MENUS_FILTER_PARENT_MENU_ITEM_LABEL="Parent Menu Item"
+COM_MENUS_FILTER_SELECT_PARENT_MENU_ITEM="- Select Parent Menu Item -"
COM_MENUS_GRID_UNSET_LANGUAGE="Unset %s Default"
COM_MENUS_HEADING_ASSIGN_MODULE="Module"
COM_MENUS_HEADING_ASSOCIATION="Association"