简体   繁体   中英

Programmatically Create Menu Item in Joomla

I have created a component in joomla 2.5 that creates a new article and adds that article to a menu item.

Creating the article is working fine, but I am having some trouble with creating the menu item.

I have the following code:

                //add the article to a menu item
                $menuTable = JTable::getInstance('Menu', 'JTable', array());

                    $menuData = array(
                    'menutype' => 'client-pages',
                    'title' => $data[name],
                    'type' => 'component',
                    'component_id' => 22,                  
                    'link' => 'index.php?option=com_content&view=article&id='.$resultID,
                    'language' => '*',
                    'published' => 1,
                    'parent_id' => '1',
                    'level' => 1,
                );

                // Bind data
                if (!$menuTable->bind($menuData))
                {
                    $this->setError($menuTable->getError());
                    return false;
                }

                // Check the data.
                if (!$menuTable->check())
                {
                    $this->setError($menuTable->getError());
                    return false;
                }

                // Store the data.
                if (!$menuTable->store())
                {
                    $this->setError($menuTable->getError());
                    return false;
                }

The error seems to be with setting the parent_id and level. On debugging libraries/joomla/database/tablenested.php sets the parent_id and level to 0. This caused the following error on my administrator page:

Warning: str_repeat() [function.str-repeat]: Second argument has to be greater than or equal to 0 in /Applications/MAMP/htdocs/joomla_2_5/administrator/components/com_menus/views/items/tmpl/default.php on line 129

Try using JTableNested::setLocation($referenceId, $position = 'after'):

$table->setLocation($parent_id, 'last-child');

I also think that you need to rebuild the path:

// Rebuild the tree path.
if (!$table->rebuildPath($table->id)) {
    $this->setError($table->getError());
    return false;
}

If it still doesn't work, try to find out what MenusModelItem::save does that you don't.

$table->setLocation($parent_id, 'last-child');

is all that is needed to ensure that left/right values are created correctly for the new menu item. There is no need to rebuild the path as this is now handled by JTableMenu's store method.

Additionally, the convenience method "save" can be used to bind, check and store the menu item:

$menuItem = array(
            'menutype' => 'client-pages',
            'title' => $data[name],
            'type' => 'component',
            'component_id' => 22,                  
            'link' => 'index.php?option=com_content&view=article&id='.$resultID,
            'language' => '*',
            'published' => 1,
            'parent_id' => $parent_id,
            'level' => 1,
        );

$menuTable = JTable::getInstance('Menu', 'JTable', array());

$menuTable->setLocation($parent_id, 'last-child');

if (!$menuTable->save($menuItem)) {
    throw new Exception($menuTable->getError());
    return false;
}

Somehow $menutable does not update parent_id and level in database table so you have to manually update those two fields by joomla query.

$menuTable = JTable::getInstance('Menu', 'JTable', array());

        $menuData = array(
            'menutype' => 'client-pages',
            'title' => $data[name],
            'type' => 'component',
            'component_id' => 22,                  
            'link' => 'index.php?option=com_content&view=article&id='.$resultID,
            'language' => '*',
            'published' => 1,
            'parent_id' => '1',
            'level' => 1,
        );

        // Bind data
        if (!$menuTable->bind($menuData))
        {
            $this->setError($menuTable->getError());
            return false;
        }

        // Check the data.
        if (!$menuTable->check())
        {
            $this->setError($menuTable->getError());
            return false;
        }

        // Store the data.
        if (!$menuTable->store())
        {
            $this->setError($menuTable->getError());
            return false;
        }

        $db   = $this->getDbo();
        $qry = "UPDATE `#__menu` SET `parent_id` = 1 , `level` = 1 WHERE `id` = ".$menuTable->id;
        $db->setQuery($qry);
        $db->query();

This code worked for me

 JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_menus/tables/');

                $menuTable =& JTable::getInstance('menu', 'menusTable');

                $menuData = array(
                        'menutype' => 'client-pages',
                        'title' => 'mytrialmenu',
                        'type' => 'component',
                        'component_id' => 22,
                        'link' => 'index.php?option=index.php?                    option='com_content&view=article&id='.$resultID,
                        'language' => '*',
                        'published' => 1,
                        'parent_id' => 'choose some parent',
                        'level' => 1,
                );
                // Bind data
                if (!$row->bind($menuData))
                {
                    $this->setError($menuTable->getError());
                    return false;
                }

                // Check the data.
                if (!$row->check())
                {
                    $this->setError($menuTable->getError());
                    return false;
                }

                // Store the data.
                if (!$row->store())
                {
                    $this->setError($menuTable->getError());
                    return false;
                }

I think the reason is menusTable extends JnestedTable which is required for manipulating lft and rgt fields in the menu table

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM