private function _createAdminMenus($parent)
{
$db = $parent->getParent()->getDbo();
/** @var \JTableMenu $table */
$table = \JTable::getInstance('menu');
$option = $parent->get('element');
// If a component exists with this option in the table then we don't need to add menus
$query = $db->getQuery(true)->select('m.id, e.extension_id')->from('#__menu AS m')->join('LEFT', '#__extensions AS e ON m.component_id = e.extension_id')->where('m.parent_id = 1')->where('m.client_id = 1')->where('e.type = ' . $db->quote('component'))->where('e.element = ' . $db->quote($option));
$db->setQuery($query);
$componentrow = $db->loadObject();
// Let's find the extension id
$query->clear()->select('e.extension_id')->from('#__extensions AS e')->where('e.element = ' . $db->quote($option));
$db->setQuery($query);
$component_id = $db->loadResult();
// Ok, now its time to handle the menus. Start with the component root menu, then handle submenus.
$menuElement = $parent->get('manifest')->administration->menu;
// We need to insert the menu item as the last child of Joomla!'s menu root node. By default this is the
// menu item with ID=1. However, some crappy upgrade scripts enjoy screwing it up. Hey, ho, the workaround
// way I go.
$query = $db->getQuery(true)->select($db->qn('id'))->from($db->qn('#__menu'))->where($db->qn('id') . ' = ' . $db->q(1));
$rootItemId = $db->setQuery($query)->loadResult();
if (is_null($rootItemId)) {
// Guess what? The Problem has happened. Let's find the root node by title.
$rootItemId = null;
$query = $db->getQuery(true)->select($db->qn('id'))->from($db->qn('#__menu'))->where($db->qn('title') . ' = ' . $db->q('Menu_Item_Root'));
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId)) {
// For crying out loud, did that idiot changed the title too?! Let's find it by alias.
$rootItemId = null;
$query = $db->getQuery(true)->select($db->qn('id'))->from($db->qn('#__menu'))->where($db->qn('alias') . ' = ' . $db->q('root'));
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId)) {
// Dude. Dude! Duuuuuuude! The alias is screwed up, too?! Find it by component ID.
$rootItemId = null;
$query = $db->getQuery(true)->select($db->qn('id'))->from($db->qn('#__menu'))->where($db->qn('component_id') . ' = ' . $db->q('0'));
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId)) {
// Your site is more of a "shite" than a "site". Let's try with minimum lft value.
$rootItemId = null;
$query = $db->getQuery(true)->select($db->qn('id'))->from($db->qn('#__menu'))->order($db->qn('lft') . ' ASC');
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId)) {
// I quit. Your site is broken. What the hell are you doing with it? I'll just throw an error.
throw new Exception("Your site is broken. There is no root menu item. As a result it is impossible to create menu items. The installation of this component has failed. Please fix your database and retry!", 500);
}
/** @var \SimpleXMLElement $menuElement */
if ($menuElement) {
$data = array();
$data['menutype'] = 'main';
$data['client_id'] = 1;
$data['title'] = (string) trim($menuElement);
$data['alias'] = (string) $menuElement;
$data['link'] = 'index.php?option=' . $option;
$data['type'] = 'component';
$data['published'] = 0;
$data['parent_id'] = 1;
$data['component_id'] = $component_id;
$data['img'] = (string) $menuElement->attributes()->img ? (string) $menuElement->attributes()->img : 'class:component';
$data['home'] = 0;
$data['path'] = '';
$data['params'] = '';
} else {
$data = array();
$data['menutype'] = 'main';
$data['client_id'] = 1;
$data['title'] = $option;
$data['alias'] = $option;
$data['link'] = 'index.php?option=' . $option;
$data['type'] = 'component';
$data['published'] = 0;
$data['parent_id'] = 1;
$data['component_id'] = $component_id;
$data['img'] = 'class:component';
$data['home'] = 0;
$data['path'] = '';
$data['params'] = '';
}
try {
$table->setLocation($rootItemId, 'last-child');
} catch (\InvalidArgumentException $e) {
JLog::add($e->getMessage(), JLog::WARNING, 'jerror');
return false;
}
if (!$table->bind($data) || !$table->check() || !$table->store()) {
// The menu item already exists. Delete it and retry instead of throwing an error.
$query->clear()->select('id')->from('#__menu')->where('menutype = ' . $db->quote('main'))->where('client_id = 1')->where('link = ' . $db->quote('index.php?option=' . $option))->where('type = ' . $db->quote('component'))->where('parent_id = 1')->where('home = 0');
$db->setQuery($query);
$menu_ids_level1 = $db->loadColumn();
if (empty($menu_ids_level1)) {
// Oops! Could not get the menu ID. Go back and rollback changes.
\JError::raiseWarning(1, $table->getError());
return false;
} else {
$ids = implode(',', $menu_ids_level1);
$query->clear()->select('id')->from('#__menu')->where('menutype = ' . $db->quote('main'))->where('client_id = 1')->where('type = ' . $db->quote('component'))->where('parent_id in (' . $ids . ')')->where('level = 2')->where('home = 0');
$db->setQuery($query);
$menu_ids_level2 = $db->loadColumn();
$ids = implode(',', array_merge($menu_ids_level1, $menu_ids_level2));
// Remove the old menu item
$query->clear()->delete('#__menu')->where('id in (' . $ids . ')');
$db->setQuery($query);
$db->execute();
// Retry creating the menu item
$table->setLocation($rootItemId, 'last-child');
if (!$table->bind($data) || !$table->check() || !$table->store()) {
// Install failed, warn user and rollback changes
\JError::raiseWarning(1, $table->getError());
return false;
}
}
}
/*
* Since we have created a menu item, we add it to the installation step stack
* so that if we have to rollback the changes we can undo it.
*/
$parent->getParent()->pushStep(array('type' => 'menu', 'id' => $component_id));
/*
* Process SubMenus
*/
if (!$parent->get('manifest')->administration->submenu) {
return true;
}
$parent_id = $table->id;
/** @var \SimpleXMLElement $child */
foreach ($parent->get('manifest')->administration->submenu->menu as $child) {
$data = array();
$data['menutype'] = 'main';
$data['client_id'] = 1;
$data['title'] = (string) trim($child);
$data['alias'] = (string) $child;
$data['type'] = 'component';
$data['published'] = 0;
$data['parent_id'] = $parent_id;
$data['component_id'] = $component_id;
$data['img'] = (string) $child->attributes()->img ? (string) $child->attributes()->img : 'class:component';
$data['home'] = 0;
// Set the sub menu link
if ((string) $child->attributes()->link) {
$data['link'] = 'index.php?' . $child->attributes()->link;
} else {
$request = array();
if ((string) $child->attributes()->act) {
$request[] = 'act=' . $child->attributes()->act;
}
if ((string) $child->attributes()->task) {
$request[] = 'task=' . $child->attributes()->task;
}
if ((string) $child->attributes()->controller) {
$request[] = 'controller=' . $child->attributes()->controller;
}
if ((string) $child->attributes()->view) {
$request[] = 'view=' . $child->attributes()->view;
}
if ((string) $child->attributes()->layout) {
$request[] = 'layout=' . $child->attributes()->layout;
}
if ((string) $child->attributes()->sub) {
$request[] = 'sub=' . $child->attributes()->sub;
}
$qstring = count($request) ? '&' . implode('&', $request) : '';
$data['link'] = 'index.php?option=' . $option . $qstring;
}
$table = \JTable::getInstance('menu');
try {
$table->setLocation($parent_id, 'last-child');
} catch (\InvalidArgumentException $e) {
return false;
}
if (!$table->bind($data) || !$table->check() || !$table->store()) {
// Install failed, rollback changes
return false;
}
/*
* Since we have created a menu item, we add it to the installation step stack
* so that if we have to rollback the changes we can undo it.
*/
$parent->getParent()->pushStep(array('type' => 'menu', 'id' => $component_id));
}
return true;
}