copyValues($params); $navigation->save(); return $navigation; } /** * Fetch object based on array of properties. * * @param array $params * (reference ) an assoc array of name/value pairs. * @param array $defaults * (reference ) an assoc array to hold the flattened values. * * @return CRM_Core_BAO_Navigation|null * object on success, NULL otherwise */ public static function retrieve(&$params, &$defaults) { $navigation = new CRM_Core_DAO_Navigation(); $navigation->copyValues($params); $navigation->domain_id = CRM_Core_Config::domainID(); if ($navigation->find(TRUE)) { CRM_Core_DAO::storeValues($navigation, $defaults); return $navigation; } return NULL; } /** * Calculate navigation weight. * * @param int $parentID * Parent_id of a menu. * @param int $menuID * Menu id. * * @return int * $weight string */ public static function calculateWeight($parentID = NULL, $menuID = NULL) { $domainID = CRM_Core_Config::domainID(); $weight = 1; // we reset weight for each parent, i.e we start from 1 to n // calculate max weight for top level menus, if parent id is absent if (!$parentID) { $query = "SELECT max(weight) as weight FROM civicrm_navigation WHERE parent_id IS NULL AND domain_id = $domainID"; } else { // if parent is passed, we need to get max weight for that particular parent $query = "SELECT max(weight) as weight FROM civicrm_navigation WHERE parent_id = {$parentID} AND domain_id = $domainID"; } $dao = CRM_Core_DAO::executeQuery($query); $dao->fetch(); return $weight = $weight + $dao->weight; } /** * Get formatted menu list. * * @return array * returns associated array */ public static function getNavigationList() { $cacheKeyString = "navigationList"; $whereClause = ''; $config = CRM_Core_Config::singleton(); // check if we can retrieve from database cache $navigations = CRM_Core_BAO_Cache::getItem('navigation', $cacheKeyString); if (!$navigations) { $domainID = CRM_Core_Config::domainID(); $query = " SELECT id, label, parent_id, weight, is_active, name FROM civicrm_navigation WHERE domain_id = $domainID"; $result = CRM_Core_DAO::executeQuery($query); $pidGroups = array(); while ($result->fetch()) { $pidGroups[$result->parent_id][$result->label] = $result->id; } foreach ($pidGroups[''] as $label => $val) { $pidGroups[''][$label] = self::_getNavigationValue($val, $pidGroups); } $navigations = array(); self::_getNavigationLabel($pidGroups[''], $navigations); CRM_Core_BAO_Cache::setItem($navigations, 'navigation', $cacheKeyString); } return $navigations; } /** * Helper function for getNavigationList(). * * @param array $list * Menu info. * @param array $navigations * Navigation menus. * @param string $separator * Menu separator. */ public static function _getNavigationLabel($list, &$navigations, $separator = '') { $i18n = CRM_Core_I18n::singleton(); foreach ($list as $label => $val) { if ($label == 'navigation_id') { continue; } $translatedLabel = $i18n->crm_translate($label, array('context' => 'menu')); $navigations[is_array($val) ? $val['navigation_id'] : $val] = "{$separator}{$translatedLabel}"; if (is_array($val)) { self::_getNavigationLabel($val, $navigations, $separator . '    '); } } } /** * Helper function for getNavigationList(). * * @param string $val * Menu name. * @param array $pidGroups * Parent menus. * * @return array */ public static function _getNavigationValue($val, &$pidGroups) { if (array_key_exists($val, $pidGroups)) { $list = array('navigation_id' => $val); foreach ($pidGroups[$val] as $label => $id) { $list[$label] = self::_getNavigationValue($id, $pidGroups); } unset($pidGroups[$val]); return $list; } else { return $val; } } /** * Build navigation tree. * * @return array * nested array of menus */ public static function buildNavigationTree() { $domainID = CRM_Core_Config::domainID(); $navigationTree = array(); $navigationMenu = new self(); $navigationMenu->domain_id = $domainID; $navigationMenu->orderBy('parent_id, weight'); $navigationMenu->find(); while ($navigationMenu->fetch()) { $navigationTree[$navigationMenu->id] = array( 'attributes' => array( 'label' => $navigationMenu->label, 'name' => $navigationMenu->name, 'url' => $navigationMenu->url, 'icon' => $navigationMenu->icon, 'weight' => $navigationMenu->weight, 'permission' => $navigationMenu->permission, 'operator' => $navigationMenu->permission_operator, 'separator' => $navigationMenu->has_separator, 'parentID' => $navigationMenu->parent_id, 'navID' => $navigationMenu->id, 'active' => $navigationMenu->is_active, ), ); } return self::buildTree($navigationTree); } /** * Convert flat array to nested. * * @param array $elements * @param int|null $parentId * * @return array */ private static function buildTree($elements, $parentId = NULL) { $branch = array(); foreach ($elements as $id => $element) { if ($element['attributes']['parentID'] == $parentId) { $children = self::buildTree($elements, $id); if ($children) { $element['child'] = $children; } $branch[$id] = $element; } } return $branch; } /** * Build menu. * * @return string */ public static function buildNavigation() { $navigations = self::buildNavigationTree(); $navigationString = ''; // run the Navigation through a hook so users can modify it CRM_Utils_Hook::navigationMenu($navigations); self::fixNavigationMenu($navigations); // Hooks have added menu items in an arbitrary order. We need to order by // weight again. I would put this function directly after // CRM_Utils_Hook::navigationMenu but for some reason, fixNavigationMenu is // moving items added by hooks on the end of the menu. Hence I do it // afterwards self::orderByWeight($navigations); //skip children menu item if user don't have access to parent menu item $skipMenuItems = array(); foreach ($navigations as $key => $value) { // Home is a special case if ($value['attributes']['name'] != 'Home') { $name = self::getMenuName($value, $skipMenuItems); if ($name) { //separator before if (isset($value['attributes']['separator']) && $value['attributes']['separator'] == 2) { $navigationString .= ''; } $removeCharacters = array('/', '!', '&', '*', ' ', '(', ')', '.'); $navigationString .= '