domain_id = CRM_Core_Config::domainID(); $menu->find(); while ($menu->fetch()) { if ($menu->title) { $menus[$menu->path] = $menu->title; } } return $menus; } /** * Add/update navigation record. * * @param array $params Submitted values * * @return CRM_Core_DAO_Navigation * navigation object */ public static function add(&$params) { $navigation = new CRM_Core_DAO_Navigation(); $params['is_active'] = CRM_Utils_Array::value('is_active', $params, FALSE); $params['has_separator'] = CRM_Utils_Array::value('has_separator', $params, FALSE); if (!isset($params['id']) || (CRM_Utils_Array::value('parent_id', $params) != CRM_Utils_Array::value('current_parent_id', $params)) ) { /* re/calculate the weight, if the Parent ID changed OR create new menu */ if ($navName = CRM_Utils_Array::value('name', $params)) { $params['name'] = $navName; } elseif ($navLabel = CRM_Utils_Array::value('label', $params)) { $params['name'] = $navLabel; } $params['weight'] = self::calculateWeight(CRM_Utils_Array::value('parent_id', $params)); } if (array_key_exists('permission', $params) && is_array($params['permission'])) { $params['permission'] = implode(',', $params['permission']); } $navigation->copyValues($params); $navigation->domain_id = CRM_Core_Config::domainID(); $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 {$whereClause} ORDER BY parent_id, weight ASC"; $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. * * @param array $navigationTree * Nested array of menus. * @param int $parentID * Parent id. * @param bool $navigationMenu * True when called for building top navigation menu. * * @return array * nested array of menus */ public static function buildNavigationTree(&$navigationTree, $parentID, $navigationMenu = TRUE) { $whereClause = " parent_id IS NULL"; if ($parentID) { $whereClause = " parent_id = {$parentID}"; } $domainID = CRM_Core_Config::domainID(); // get the list of menus $query = " SELECT id, label, url, permission, permission_operator, has_separator, parent_id, is_active, name FROM civicrm_navigation WHERE {$whereClause} AND domain_id = $domainID ORDER BY parent_id, weight"; $navigation = CRM_Core_DAO::executeQuery($query); $config = CRM_Core_Config::singleton(); while ($navigation->fetch()) { $label = $navigation->label; if (!$navigationMenu) { $label = addcslashes($label, '"'); } // for each menu get their children $navigationTree[$navigation->id] = array( 'attributes' => array( 'label' => $label, 'name' => $navigation->name, 'url' => $navigation->url, 'permission' => $navigation->permission, 'operator' => $navigation->permission_operator, 'separator' => $navigation->has_separator, 'parentID' => $navigation->parent_id, 'navID' => $navigation->id, 'active' => $navigation->is_active, ), ); self::buildNavigationTree($navigationTree[$navigation->id]['child'], $navigation->id, $navigationMenu); } return $navigationTree; } /** * Build menu. * * @param bool $json * By default output is html. * @param bool $navigationMenu * True when called for building top navigation menu. * * @return string * html or json string */ public static function buildNavigation($json = FALSE, $navigationMenu = TRUE) { $navigations = array(); self::buildNavigationTree($navigations, $parent = NULL, $navigationMenu); $navigationString = NULL; // run the Navigation through a hook so users can modify it CRM_Utils_Hook::navigationMenu($navigations); $i18n = CRM_Core_I18n::singleton(); //skip children menu item if user don't have access to parent menu item $skipMenuItems = array(); foreach ($navigations as $key => $value) { if ($json) { if ($navigationString) { $navigationString .= '},'; } $data = $value['attributes']['label']; $class = ''; if (!$value['attributes']['active']) { $class = ', "attr": { "class" : "disabled"} '; } $l10nName = $i18n->crm_translate($data, array('context' => 'menu')); $navigationString .= ' { "attr": { "id" : "node_' . $key . '"}, "data": { "title":"' . $l10nName . '"' . $class . '}'; } else { // 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 .= '