domain_id = CRM_Core_Config::domainID(); $menu->find(); while ($menu->fetch()) { if ($menu->title) { $menus[$menu->path] = $menu->title; } } return $menus; } /** * Function to add/update navigation record * * @param array associated array of submitted values * * @return object navigation object * @static */ 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; } /** * Takes a bunch of params that are needed to match certain criteria and * retrieves the relevant objects. Typically the valid params are only * contact_id. We'll tweak this function to be more full featured over a period * of time. This is the inverse function of create. It also stores all the retrieved * values in the default array * * @param array $params (reference ) an assoc array of name/value pairs * @param array $defaults (reference ) an assoc array to hold the flattened values * * @return object CRM_Core_BAO_Navigation object on success, null otherwise * @access public * @static */ 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 $parentID parent_id of a menu * @param $menuID menu id * * @return $weight string * @static */ 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 $navigations returns associated array * @static */ 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 */ 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 */ 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; } } /** * Function to build navigation tree * * @param array $navigationTree nested array of menus * @param int $parentID parent id * @param boolean $navigationMenu true when called for building top navigation menu * * @return array $navigationTree nested array of menus * @static */ 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; } /** * Function to build menu * * @param boolean $json by default output is html * @param boolean $navigationMenu true when called for building top navigation menu * * @return returns html or json object * @static */ 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 .= '