' . t('About') . ''; $output .= '
' . t("The Menu link module defines a menu link field type for the Field module. A menu link field may be used to place links into a menu that link to it's entity. See the Field module help page for more information about fields.", array('@field-help' => url('admin/help/field'), '@filter-help' => url('admin/help/filter'))) . '
'; return $output; } } /** * Load multiple menu links, access checked and link translated for rendering. * * This function should never be called from within node_load() or any other * function used as a menu object load function since an infinite recursion may * occur. * * @param $mlids array * An array of menu link IDs. * @param $conditions array * An associative array of conditions on the {menu_links} * table, where the keys are the database fields and the values are the * values those fields must have. * * @return * An array of menu links indexed by mlid. * * @see menu_link_load() * * @todo Remove this function when http://drupal.org/node/1034732 lands. */ function menu_link_load_multiple(array $mlids, array $conditions = array()) { $query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC)); $query->leftJoin('menu_router', 'm', 'm.path = ml.router_path'); $query->fields('ml'); // Weight should be taken from {menu_links}, not {menu_router}. $query->addField('ml', 'weight', 'link_weight'); $query->fields('m'); if (!empty($mlids)) { $query->condition('ml.mlid', $mlids, 'IN'); } if (!empty($conditions)) { foreach ($conditions as $field => $value) { $query->condition('ml.' . $field, $value); } } $items = array(); foreach ($query->execute() as $item) { $item['weight'] = $item['link_weight']; $items[$item['mlid']] = $item; _menu_link_translate($items[$item['mlid']]); } return $items; } /** * Delete multiple menu links. * * @param $mlids array * An array of menu link IDs. * @param $force boolean * Forces deletion. Internal use only, setting to TRUE is discouraged. * * @see menu_link_delete() * * @todo Remove this function when http://drupal.org/node/1034732 lands. */ function menu_link_delete_multiple(array $mlids, $force = FALSE) { if (!empty($mlids)) { $query = db_select('menu_links') ->fields('menu_links') ->condition('mlid', $mlids, 'IN'); if (!$force) { // Exclude links belonging to system module except if they are marked // updated (generated during update from Drupal 5). $query->condition(db_or()->condition('module', 'system', '<>')->condition('updated', 0, '<>')); } $links_to_delete = $query->execute()->fetchAllAssoc('mlid', PDO::FETCH_ASSOC); if (!empty($links_to_delete)) { $links_with_children = array(); $parent_mlids = array(); $affected_menus = array(); foreach ($links_to_delete as $item) { if ($item['has_children']) { $links_with_children[$item['mlid']] = $item['mlid']; } $parent_mlids[$item['plid']] = $item['plid']; $affected_menus[$item['menu_name']] = $item['menu_name']; } $parent_mlids = array_diff_key($parent_mlids, array(0 => 0) + array_keys($links_to_delete)); // Re-parent any children to it's closest parent that is not deleted. if (!empty($links_with_children)) { $children = menu_link_load_multiple(array(), array('plid' => $links_with_children)); foreach ($children as $item) { while (isset($links_to_delete[$item['plid']])) { $item['plid'] = $links_to_delete[$item['plid']]['plid']; } menu_link_save($item); } } db_delete('menu_links')->condition('mlid', array_keys($links_to_delete), 'IN')->execute(); foreach ($links_to_delete as $item) { // Notify modules we have deleted the item. module_invoke_all('menu_link_delete', $item); // Update the has_children status of the parent. _menu_update_parental_status($item); } // Update the has_children status of parents of deleted links. // @todo fix query und use this instead of _menu_update_parental_status($item); /*if (!empty($parent_mlids)) { $exists_query = db_select('menu_links', 'child') ->fields('child', array('mlid')) ->condition('child.hidden', 0) ->where('child.plid = parent.mlid') ->where('child.menu_name = parent.menu_name') ->range(0, 1); db_update('menu_links', 'parent') ->fields(array('has_children' => 0)) ->condition('has_children', 1) ->condition('mlid', $parent_mlids, 'IN') ->notExists($exists_query) ->execute(); }*/ // Clear caches. foreach ($affected_menus as $menu_name) { menu_cache_clear($menu_name); } _menu_clear_page_cache(); } } } /** * Implements hook_menu_delete(). */ function menu_link_menu_delete($menu) { // Menu should not be removed from settings of menu_link field instances; menus // have a machine name so they can be recreated. Non existant menus won't be // available in the field widgets. } /** * Implements hook_menu_link_alter(). * * @see http://drupal.org/node/1087888 * Add $prior_link to hook_menu_link_update(). */ function menu_link_menu_link_alter($item = NULL) { static $existing_item; if (isset($item)) { $existing_item = FALSE; if (isset($item['mlid'])) { if ($existing_item = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $item['mlid']))->fetchAssoc()) { $existing_item['options'] = unserialize($existing_item['options']); } } if ($existing_item['module'] == 'menu_link') { } } return $existing_item; } /** * Implements hook_menu_link_update(). * * Synchronize menu_link fields with the updated menu link. */ function menu_link_menu_link_update($item) { $prior_item = menu_link_menu_link_alter(); if ($item['module'] == 'menu_link' && empty($item['menu_link_field_save'])) { static $entity_paths; if (empty($entity_paths)) { $entity_get_info = entity_get_info(); foreach ($entity_get_info as $entity_type => $entity_info) { if (isset($entity_info['path'])) { $entity_path = str_replace('%' . $entity_type, '%', $entity_info['path']); $entity_paths[$entity_path] = $entity_type; } } } if (isset($entity_paths[$item['router_path']])) { // Get entity type $entity_type = $entity_paths[$item['router_path']]; // Get path to entity without wildcard $router_path = str_replace('%','',$item['router_path']); // Get Entity ID $entity_id = str_replace($router_path, '', $item['link_path']); // Load entity $entity = array_shift(entity_load($entity_type, array($entity_id))); // Get bundle list( , , $bundle) = entity_extract_ids($entity_type, $entity); $save_entity = FALSE; foreach (field_info_instances($entity_type, $bundle) as $instance) { $field_name = $instance['field_name']; $field = field_info_field($field_name); if ($field['module'] == 'menu_link') { // Check if field exist on this entity if (isset($entity->{$field_name}) && !empty($entity->{$field_name})) { // Check if content is the same as current path for each language foreach ($entity->{$field_name} as $lang => $items) { // for each contents of fields foreach ($items as $i => $field_item) { // Check if it's current item if ($field_item['mlid'] == $item['mlid']) { // So give it updated options foreach ($entity->{$field_name}[$lang][$i] as $option_name => $option_value) { $entity->{$field_name}[$lang][$i][$option_name] = $item[$option_name]; } $save_entity = TRUE; break; // We found item in field content so break to next field } } } } } } // Entity has been edited so save it if ($save_entity) { entity_save($entity_name, $entity); } } } } /** * Implements hook_menu_link_delete(). * * Remove link from all menu_link fields. Note that this module disables the * possibility to delete menu links through the Admin > Structure > Menus * interface that are used in a menu_link field (by storing menu links under its * own module instead of system). So this hook may not be neccessary at all. */ function menu_link_menu_link_delete($item) { if ($item['module'] == 'menu_link' && empty($item['menu_link_field_save'])) { // TODO } } /** * Implements hook_field_update_forbid(). */ function menu_link_field_update_forbid($field, $prior_field, $has_data) { if ($field['field_name'] == MENU_LINK_DEFAULT_FIELD) { if (!empty($field['settings']['link_path_field'])) { throw new FieldUpdateForbiddenException(t('The link path cannot not be exposed for the ":menu_link_field" field.', array(':menu_link_field' => MENU_LINK_DEFAULT_FIELD))); } } } /** * Implementation of hook_views_api(). */ function menu_link_views_api() { return array( 'api' => 3, 'path' => drupal_get_path('module', 'menu_link'), ); }