Loading includes/features.menu.inc +206 −37 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ function menu_features_api() { 'feature_source' => TRUE, 'default_file' => FEATURES_DEFAULTS_INCLUDED, ), // DEPRECATED // DEPRECATED. 'menu' => array( 'name' => t('Menu items'), 'default_hook' => 'menu_default_items', Loading @@ -29,6 +29,7 @@ function menu_features_api() { /** * Implements hook_features_export(). * * DEPRECATED: This implementation simply migrates deprecated `menu` items * to the `menu_links` type. */ Loading Loading @@ -61,7 +62,7 @@ function menu_custom_features_export($data, &$export, $module_name = '') { $export['dependencies']['features'] = 'features'; $export['dependencies']['menu'] = 'menu'; // Collect a menu to module map // Collect a menu to module map. $pipe = array(); $map = features_get_default_map('menu_custom', 'menu_name'); foreach ($data as $menu_name) { Loading @@ -77,7 +78,7 @@ function menu_custom_features_export($data, &$export, $module_name = '') { } /** * Implements hook_features_export_render() * Implements hook_features_export_render(). */ function menu_custom_features_export_render($module, $data) { $code = array(); Loading Loading @@ -132,7 +133,7 @@ function menu_custom_features_rebuild($module) { function menu_links_features_export_options() { global $menu_admin; // Need to set this to TRUE in order to get menu links that the // current user may not have access to (i.e. user/login) // current user may not have access to (i.e. user/login). $menu_admin = TRUE; $use_menus = array_intersect_key(menu_get_menus(), array_flip(array_filter(variable_get('features_admin_menu_links_menus', array_keys(menu_get_menus()))))); $menu_links = menu_parent_options($use_menus, array('mlid' => 0)); Loading @@ -141,6 +142,12 @@ function menu_links_features_export_options() { list($menu_name, $mlid) = explode(':', $key, 2); if ($mlid != 0) { $link = menu_link_load($mlid); // UUID URL handling. if (module_exists('uuid')) { _features_set_menu_link_uuid_path($link); } $identifier = menu_links_features_identifier($link, TRUE); $options[$identifier] = "{$menu_name}: {$name}"; } Loading @@ -158,16 +165,16 @@ function menu_links_features_identifier($link, $old = FALSE) { // The old identifier is requested. if ($old) { // if identifier already exists // If identifier already exists. if (isset($link['options']['identifier'])) { return $link['options']['identifier']; } // providing backward compatibility and allowing/enabling multiple links with same paths // Providing backward compatibility and allowing/enabling multiple links with same paths. else { $identifier = isset($link['menu_name'], $link['link_path']) ? "{$link['menu_name']}:{$link['link_path']}" : FALSE; // Checking if there are multiples of this identifier // Checking if there are multiples of this identifier. if (features_menu_link_load($identifier) !== FALSE) { // this is where we return the upgrade posibility for links. // This is where we return the upgrade posibility for links. return $identifier; } } Loading @@ -185,11 +192,16 @@ function menu_links_features_export($data, &$export, $module_name = '') { $export['dependencies']['features'] = 'features'; $export['dependencies']['menu'] = 'menu'; // Collect a link to module map // Collect a link to module map. $pipe = array(); $map = features_get_default_map('menu_links', 'menu_links_features_identifier'); foreach ($data as $key => $identifier) { if ($link = features_menu_link_load($identifier)) { // UUID URL handling. // Without this, features info file will lose UUID for menu links. if (module_exists('uuid')) { _features_set_menu_link_uuid_path($link); } // If this link is provided by a different module, add it as a dependency. $new_identifier = menu_links_features_identifier($link, empty($export)); if (isset($map[$identifier]) && $map[$identifier] != $module_name) { Loading @@ -201,7 +213,14 @@ function menu_links_features_export($data, &$export, $module_name = '') { // For now, exclude a variety of common menus from automatic export. // They may still be explicitly included in a Feature if the builder // chooses to do so. if (!in_array($link['menu_name'], array('features', 'primary-links', 'secondary-links', 'navigation', 'admin', 'devel'))) { if (!in_array($link['menu_name'], array( 'features', 'primary-links', 'secondary-links', 'navigation', 'admin', 'devel', ))) { $pipe['menu_custom'][] = $link['menu_name']; } } Loading @@ -210,7 +229,68 @@ function menu_links_features_export($data, &$export, $module_name = '') { } /** * Implements hook_features_export_render() * Helper function to set UUID data for menu items. */ function _features_set_menu_link_uuid_path(&$link) { // UUID URL handling. if (module_exists('uuid') && in_array( $link['router_path'], array('node/%', 'taxonomy/term/%', 'user/%', 'uuid')) ) { $entity_type = 'node'; switch ($link['router_path']) { case 'taxonomy/term/%': $entity_type = 'taxonomy_term'; break; case 'user/%': $entity_type = 'user'; break; case 'uuid': // Restore the internal path instead of the UUID path. $uri = explode('/', $link['link_path']); if (count($uri) == 3 && $uri[0] == 'uuid') { $entity_data = uuid_uri_array_to_data($uri); $entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid'])); if (!empty($entities)) { $entity_type = $entity_data['entity_type']; $entity = reset($entities); $internal_uri = entity_uri($entity_data['entity_type'], $entity); $link['link_path'] = $internal_uri['path']; } } // The router path is set to 'uuid', but the link path is not a UUID // path. else { switch ($uri[0]) { case 'taxonomy': $entity_type = 'taxonomy_term'; break; case 'user': $entity_type = 'user'; break; } } break; } $path_position = substr_count($link['link_path'], '/'); $entity = menu_get_object($entity_type, $path_position, $link['link_path']); if ($entity && isset($entity->uuid)) { $link['uuid'] = $entity->uuid; $link['link_path'] = 'uuid/' . $entity_type . '/' . $entity->uuid; $link['router_path'] = 'uuid'; } if ($entity && isset($entity->vuuid)) { $link['vuuid'] = $entity->vuuid; } } } /** * Implements hook_features_export_render(). */ function menu_links_features_export_render($module, $data, $export = NULL) { $code = array(); Loading @@ -221,10 +301,20 @@ function menu_links_features_export_render($module, $data, $export = NULL) { foreach ($data as $identifier) { if ($link = features_menu_link_load($identifier)) { // UUID URL handling. if (module_exists('uuid')) { _features_set_menu_link_uuid_path($link); } $new_identifier = menu_links_features_identifier($link, empty($export)); // Replace plid with a parent path. if (!empty($link['plid']) && $parent = menu_link_load($link['plid'])) { // UUID URL handling. if (module_exists('uuid')) { _features_set_menu_link_uuid_path($parent); } // If the new identifier is different than the old, maintain // 'parent_path' for backwards compatibility. if ($new_identifier != menu_links_features_identifier($link)) { Loading @@ -237,11 +327,25 @@ function menu_links_features_export_render($module, $data, $export = NULL) { } if (!isset($link['options']['identifier'])) { // Create the identifier only if it doesn't exists. // Create the identifier only if it doesn't exist. $link['options']['identifier'] = $new_identifier; if (!empty($export)) { // Identifiers are renewed. We need to update them in the DB. $temp = $link; // Start uuid handling. if (module_exists('uuid')) { // Restore the internal path instead of the UUID path. $uri = explode('/', $temp['link_path']); if ($uri[0] == 'uuid' && count($uri) == 3) { $entity_data = uuid_uri_array_to_data($uri); $entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid'])); if (!empty($entities)) { $entity = reset($entities); $internal_uri = entity_uri($entity_data['entity_type'], $entity); $temp['link_path'] = $internal_uri['path']; } } } // End of uuid handling. menu_link_save($temp); } } Loading Loading @@ -328,6 +432,23 @@ function menu_links_features_rebuild_ordered($menu_links, $reset = FALSE) { $existing = features_menu_link_load($identifier); if (!$existing || in_array($link, $menu_links)) { // Restore the internal path instead of the UUID path. $internal_path = ''; $uri = explode('/', $link['link_path']); if (module_exists('uuid') && $uri[0] == 'uuid' && count($uri) == 3) { $entity_data = uuid_uri_array_to_data($uri); $entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid'])); if (!empty($entities)) { $entity = reset($entities); $internal_uri = entity_uri($entity_data['entity_type'], $entity); $internal_path = $internal_uri['path']; } } $link_paths = array($link['link_path']); if (!empty($internal_path)) { $link['link_path'] = $internal_path; } // Retrieve the mlid if this is an existing item. if ($existing) { $link['mlid'] = $existing['mlid']; Loading @@ -350,7 +471,8 @@ function menu_links_features_rebuild_ordered($menu_links, $reset = FALSE) { /** * Load a menu link by its menu_name_cleantitle:link_path identifier. * Also matches links with unique menu_name:link_path * * Also matches links with unique menu_name:link_path. */ function features_menu_link_load($identifier) { $menu_name = ''; Loading @@ -366,10 +488,43 @@ function features_menu_link_load($identifier) { $clean_title = ''; list($menu_name, $link_path) = explode(':', $identifier, 2); } // Menu item can link either to internal URL or UUID URL. $internal_path = ''; $uri = explode('/', $link_path); if (module_exists('uuid') && $uri[0] == 'uuid' && count($uri) == 3) { $entity_data = uuid_uri_array_to_data($uri); $entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid'])); if (!empty($entities)) { $entity = reset($entities); $internal_uri = entity_uri($entity_data['entity_type'], $entity); $internal_path = $internal_uri['path']; } } $link_paths = array($link_path); if (!empty($internal_path)) { $link_paths = array($internal_path); } $links = db_select('menu_links') ->fields('menu_links', array('menu_name', 'mlid', 'plid', 'link_path', 'router_path', 'link_title', 'options', 'module', 'hidden', 'external', 'has_children', 'expanded', 'weight', 'customized')) ->fields('menu_links', array( 'menu_name', 'mlid', 'plid', 'link_path', 'router_path', 'link_title', 'options', 'module', 'hidden', 'external', 'has_children', 'expanded', 'weight', 'customized', )) ->condition('menu_name', $menu_name) ->condition('link_path', $link_path) ->condition('link_path', $link_paths, 'IN') ->addTag('features_menu_link') ->execute() ->fetchAllAssoc('mlid'); Loading @@ -380,7 +535,6 @@ function features_menu_link_load($identifier) { // Title or previous identifier matches. if ((isset($link->options['identifier']) && strcmp($link->options['identifier'], $identifier) == 0) || (isset($clean_title) && strcmp(features_clean_title($link->link_title), $clean_title) == 0)) { return (array) $link; } } Loading @@ -389,14 +543,29 @@ function features_menu_link_load($identifier) { // -- providing an upgrade possibility for links saved in a feature before the // new identifier-pattern was added. if (count($links) == 1 && empty($clean_title)) { $link = reset($links); // get the first item // Get the first item. $link = reset($links); return (array) $link; } // If link_path was changed on an existing link, we need to find it by // searching for link_title. elseif (isset($clean_title)) { $links = db_select('menu_links') ->fields('menu_links', array('menu_name', 'mlid', 'plid', 'link_path', 'router_path', 'link_title', 'options', 'module', 'hidden', 'external', 'has_children', 'expanded', 'weight')) ->fields('menu_links', array( 'menu_name', 'mlid', 'plid', 'link_path', 'router_path', 'link_title', 'options', 'module', 'hidden', 'external', 'has_children', 'expanded', 'weight', )) ->condition('menu_name', $menu_name) ->execute() ->fetchAllAssoc('mlid'); Loading @@ -419,7 +588,7 @@ function features_menu_link_load($identifier) { } /** * Returns a lowercase clean string with only letters, numbers and dashes * Returns a lowercase clean string with only letters, numbers and dashes. */ function features_clean_title($str) { return strtolower(preg_replace_callback('/(\s)|([^a-zA-Z\-0-9])/i', '_features_clean_title', $str)); Loading Loading
includes/features.menu.inc +206 −37 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ function menu_features_api() { 'feature_source' => TRUE, 'default_file' => FEATURES_DEFAULTS_INCLUDED, ), // DEPRECATED // DEPRECATED. 'menu' => array( 'name' => t('Menu items'), 'default_hook' => 'menu_default_items', Loading @@ -29,6 +29,7 @@ function menu_features_api() { /** * Implements hook_features_export(). * * DEPRECATED: This implementation simply migrates deprecated `menu` items * to the `menu_links` type. */ Loading Loading @@ -61,7 +62,7 @@ function menu_custom_features_export($data, &$export, $module_name = '') { $export['dependencies']['features'] = 'features'; $export['dependencies']['menu'] = 'menu'; // Collect a menu to module map // Collect a menu to module map. $pipe = array(); $map = features_get_default_map('menu_custom', 'menu_name'); foreach ($data as $menu_name) { Loading @@ -77,7 +78,7 @@ function menu_custom_features_export($data, &$export, $module_name = '') { } /** * Implements hook_features_export_render() * Implements hook_features_export_render(). */ function menu_custom_features_export_render($module, $data) { $code = array(); Loading Loading @@ -132,7 +133,7 @@ function menu_custom_features_rebuild($module) { function menu_links_features_export_options() { global $menu_admin; // Need to set this to TRUE in order to get menu links that the // current user may not have access to (i.e. user/login) // current user may not have access to (i.e. user/login). $menu_admin = TRUE; $use_menus = array_intersect_key(menu_get_menus(), array_flip(array_filter(variable_get('features_admin_menu_links_menus', array_keys(menu_get_menus()))))); $menu_links = menu_parent_options($use_menus, array('mlid' => 0)); Loading @@ -141,6 +142,12 @@ function menu_links_features_export_options() { list($menu_name, $mlid) = explode(':', $key, 2); if ($mlid != 0) { $link = menu_link_load($mlid); // UUID URL handling. if (module_exists('uuid')) { _features_set_menu_link_uuid_path($link); } $identifier = menu_links_features_identifier($link, TRUE); $options[$identifier] = "{$menu_name}: {$name}"; } Loading @@ -158,16 +165,16 @@ function menu_links_features_identifier($link, $old = FALSE) { // The old identifier is requested. if ($old) { // if identifier already exists // If identifier already exists. if (isset($link['options']['identifier'])) { return $link['options']['identifier']; } // providing backward compatibility and allowing/enabling multiple links with same paths // Providing backward compatibility and allowing/enabling multiple links with same paths. else { $identifier = isset($link['menu_name'], $link['link_path']) ? "{$link['menu_name']}:{$link['link_path']}" : FALSE; // Checking if there are multiples of this identifier // Checking if there are multiples of this identifier. if (features_menu_link_load($identifier) !== FALSE) { // this is where we return the upgrade posibility for links. // This is where we return the upgrade posibility for links. return $identifier; } } Loading @@ -185,11 +192,16 @@ function menu_links_features_export($data, &$export, $module_name = '') { $export['dependencies']['features'] = 'features'; $export['dependencies']['menu'] = 'menu'; // Collect a link to module map // Collect a link to module map. $pipe = array(); $map = features_get_default_map('menu_links', 'menu_links_features_identifier'); foreach ($data as $key => $identifier) { if ($link = features_menu_link_load($identifier)) { // UUID URL handling. // Without this, features info file will lose UUID for menu links. if (module_exists('uuid')) { _features_set_menu_link_uuid_path($link); } // If this link is provided by a different module, add it as a dependency. $new_identifier = menu_links_features_identifier($link, empty($export)); if (isset($map[$identifier]) && $map[$identifier] != $module_name) { Loading @@ -201,7 +213,14 @@ function menu_links_features_export($data, &$export, $module_name = '') { // For now, exclude a variety of common menus from automatic export. // They may still be explicitly included in a Feature if the builder // chooses to do so. if (!in_array($link['menu_name'], array('features', 'primary-links', 'secondary-links', 'navigation', 'admin', 'devel'))) { if (!in_array($link['menu_name'], array( 'features', 'primary-links', 'secondary-links', 'navigation', 'admin', 'devel', ))) { $pipe['menu_custom'][] = $link['menu_name']; } } Loading @@ -210,7 +229,68 @@ function menu_links_features_export($data, &$export, $module_name = '') { } /** * Implements hook_features_export_render() * Helper function to set UUID data for menu items. */ function _features_set_menu_link_uuid_path(&$link) { // UUID URL handling. if (module_exists('uuid') && in_array( $link['router_path'], array('node/%', 'taxonomy/term/%', 'user/%', 'uuid')) ) { $entity_type = 'node'; switch ($link['router_path']) { case 'taxonomy/term/%': $entity_type = 'taxonomy_term'; break; case 'user/%': $entity_type = 'user'; break; case 'uuid': // Restore the internal path instead of the UUID path. $uri = explode('/', $link['link_path']); if (count($uri) == 3 && $uri[0] == 'uuid') { $entity_data = uuid_uri_array_to_data($uri); $entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid'])); if (!empty($entities)) { $entity_type = $entity_data['entity_type']; $entity = reset($entities); $internal_uri = entity_uri($entity_data['entity_type'], $entity); $link['link_path'] = $internal_uri['path']; } } // The router path is set to 'uuid', but the link path is not a UUID // path. else { switch ($uri[0]) { case 'taxonomy': $entity_type = 'taxonomy_term'; break; case 'user': $entity_type = 'user'; break; } } break; } $path_position = substr_count($link['link_path'], '/'); $entity = menu_get_object($entity_type, $path_position, $link['link_path']); if ($entity && isset($entity->uuid)) { $link['uuid'] = $entity->uuid; $link['link_path'] = 'uuid/' . $entity_type . '/' . $entity->uuid; $link['router_path'] = 'uuid'; } if ($entity && isset($entity->vuuid)) { $link['vuuid'] = $entity->vuuid; } } } /** * Implements hook_features_export_render(). */ function menu_links_features_export_render($module, $data, $export = NULL) { $code = array(); Loading @@ -221,10 +301,20 @@ function menu_links_features_export_render($module, $data, $export = NULL) { foreach ($data as $identifier) { if ($link = features_menu_link_load($identifier)) { // UUID URL handling. if (module_exists('uuid')) { _features_set_menu_link_uuid_path($link); } $new_identifier = menu_links_features_identifier($link, empty($export)); // Replace plid with a parent path. if (!empty($link['plid']) && $parent = menu_link_load($link['plid'])) { // UUID URL handling. if (module_exists('uuid')) { _features_set_menu_link_uuid_path($parent); } // If the new identifier is different than the old, maintain // 'parent_path' for backwards compatibility. if ($new_identifier != menu_links_features_identifier($link)) { Loading @@ -237,11 +327,25 @@ function menu_links_features_export_render($module, $data, $export = NULL) { } if (!isset($link['options']['identifier'])) { // Create the identifier only if it doesn't exists. // Create the identifier only if it doesn't exist. $link['options']['identifier'] = $new_identifier; if (!empty($export)) { // Identifiers are renewed. We need to update them in the DB. $temp = $link; // Start uuid handling. if (module_exists('uuid')) { // Restore the internal path instead of the UUID path. $uri = explode('/', $temp['link_path']); if ($uri[0] == 'uuid' && count($uri) == 3) { $entity_data = uuid_uri_array_to_data($uri); $entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid'])); if (!empty($entities)) { $entity = reset($entities); $internal_uri = entity_uri($entity_data['entity_type'], $entity); $temp['link_path'] = $internal_uri['path']; } } } // End of uuid handling. menu_link_save($temp); } } Loading Loading @@ -328,6 +432,23 @@ function menu_links_features_rebuild_ordered($menu_links, $reset = FALSE) { $existing = features_menu_link_load($identifier); if (!$existing || in_array($link, $menu_links)) { // Restore the internal path instead of the UUID path. $internal_path = ''; $uri = explode('/', $link['link_path']); if (module_exists('uuid') && $uri[0] == 'uuid' && count($uri) == 3) { $entity_data = uuid_uri_array_to_data($uri); $entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid'])); if (!empty($entities)) { $entity = reset($entities); $internal_uri = entity_uri($entity_data['entity_type'], $entity); $internal_path = $internal_uri['path']; } } $link_paths = array($link['link_path']); if (!empty($internal_path)) { $link['link_path'] = $internal_path; } // Retrieve the mlid if this is an existing item. if ($existing) { $link['mlid'] = $existing['mlid']; Loading @@ -350,7 +471,8 @@ function menu_links_features_rebuild_ordered($menu_links, $reset = FALSE) { /** * Load a menu link by its menu_name_cleantitle:link_path identifier. * Also matches links with unique menu_name:link_path * * Also matches links with unique menu_name:link_path. */ function features_menu_link_load($identifier) { $menu_name = ''; Loading @@ -366,10 +488,43 @@ function features_menu_link_load($identifier) { $clean_title = ''; list($menu_name, $link_path) = explode(':', $identifier, 2); } // Menu item can link either to internal URL or UUID URL. $internal_path = ''; $uri = explode('/', $link_path); if (module_exists('uuid') && $uri[0] == 'uuid' && count($uri) == 3) { $entity_data = uuid_uri_array_to_data($uri); $entities = entity_uuid_load($entity_data['entity_type'], array($entity_data['uuid'])); if (!empty($entities)) { $entity = reset($entities); $internal_uri = entity_uri($entity_data['entity_type'], $entity); $internal_path = $internal_uri['path']; } } $link_paths = array($link_path); if (!empty($internal_path)) { $link_paths = array($internal_path); } $links = db_select('menu_links') ->fields('menu_links', array('menu_name', 'mlid', 'plid', 'link_path', 'router_path', 'link_title', 'options', 'module', 'hidden', 'external', 'has_children', 'expanded', 'weight', 'customized')) ->fields('menu_links', array( 'menu_name', 'mlid', 'plid', 'link_path', 'router_path', 'link_title', 'options', 'module', 'hidden', 'external', 'has_children', 'expanded', 'weight', 'customized', )) ->condition('menu_name', $menu_name) ->condition('link_path', $link_path) ->condition('link_path', $link_paths, 'IN') ->addTag('features_menu_link') ->execute() ->fetchAllAssoc('mlid'); Loading @@ -380,7 +535,6 @@ function features_menu_link_load($identifier) { // Title or previous identifier matches. if ((isset($link->options['identifier']) && strcmp($link->options['identifier'], $identifier) == 0) || (isset($clean_title) && strcmp(features_clean_title($link->link_title), $clean_title) == 0)) { return (array) $link; } } Loading @@ -389,14 +543,29 @@ function features_menu_link_load($identifier) { // -- providing an upgrade possibility for links saved in a feature before the // new identifier-pattern was added. if (count($links) == 1 && empty($clean_title)) { $link = reset($links); // get the first item // Get the first item. $link = reset($links); return (array) $link; } // If link_path was changed on an existing link, we need to find it by // searching for link_title. elseif (isset($clean_title)) { $links = db_select('menu_links') ->fields('menu_links', array('menu_name', 'mlid', 'plid', 'link_path', 'router_path', 'link_title', 'options', 'module', 'hidden', 'external', 'has_children', 'expanded', 'weight')) ->fields('menu_links', array( 'menu_name', 'mlid', 'plid', 'link_path', 'router_path', 'link_title', 'options', 'module', 'hidden', 'external', 'has_children', 'expanded', 'weight', )) ->condition('menu_name', $menu_name) ->execute() ->fetchAllAssoc('mlid'); Loading @@ -419,7 +588,7 @@ function features_menu_link_load($identifier) { } /** * Returns a lowercase clean string with only letters, numbers and dashes * Returns a lowercase clean string with only letters, numbers and dashes. */ function features_clean_title($str) { return strtolower(preg_replace_callback('/(\s)|([^a-zA-Z\-0-9])/i', '_features_clean_title', $str)); Loading