entity_menu_links.module in Entity menu links 7
Entity menu link module
File
entity_menu_links.moduleView source
<?php
/**
* @file
* Entity menu link module
*/
/**
* Implements hook_entity_info().
*/
function entity_menu_links_entity_info() {
$info['menu_link'] = array(
'label' => t('Menu link'),
'controller class' => 'EntityMenuLinkController',
'base table' => 'menu_links',
'module' => 'entity_menu_links',
'revision table' => 'menu_links_revision',
'uri callback' => 'entity_menu_links_uri',
'label callback' => 'entity_menu_links_label',
'fieldable' => FALSE,
'entity keys' => array(
'id' => 'mlid',
'revision' => 'vid',
'bundle' => 'menu_name',
'label' => 'title',
'uuid' => 'uuid',
'revision uuid' => 'vuuid',
),
'bundles' => array(),
'view modes' => array(),
'load hook' => NULL,
'uuid' => TRUE,
);
$schema = drupal_get_schema('menu_links');
if (isset($schema['fields']['language'])) {
$info['menu_link']['entity keys']['language'] = 'language';
}
foreach (menu_get_menus() as $type => $name) {
$info['menu_link']['bundles'][$type] = array(
'label' => t('@menu-name menu', array(
'@menu-name' => $name,
)),
'admin' => array(
'path' => 'admin/structure/menu/manage/%menu/edit',
'bundle argument' => 4,
'real path' => 'admin/structure/menu/manage/' . $type . '/edit',
'access arguments' => array(
'administer menus',
),
),
);
}
return $info;
}
/**
* Entity uri callback.
*/
function entity_menu_links_uri($menu_link) {
return array(
'path' => 'admin/structure/menu/item/' . $menu_link->mlid,
);
}
/**
* Entity label callback.
*/
function entity_menu_links_label($menu_link) {
$menu_link = (object) $menu_link;
return $menu_link->title;
}
/**
* Implements hook_menu_link_alter().
*/
function entity_menu_links_menu_link_alter(&$menu_link) {
if (isset($menu_link['module']) && $menu_link['module'] == 'menu') {
// Ensure defaults are set as hook_menu_link_alter() is invoked before the
// defaults are applied.
// @see https://www.drupal.org/node/929176
$menu_link += array(
'menu_name' => 'navigation',
'weight' => 0,
'link_title' => '',
'hidden' => 0,
'has_children' => 0,
'expanded' => 0,
'options' => array(),
'module' => 'menu',
'customized' => 0,
'updated' => 0,
);
$entity = (object) $menu_link;
module_invoke_all('entity_presave', $entity, 'menu_link');
}
}
/**
* Implements hook_menu_link_insert().
*/
function entity_menu_links_menu_link_insert($menu_link) {
if ($menu_link['module'] == 'menu') {
if (empty($menu_link['uuid'])) {
$menu_link['uuid'] = uuid_generate();
}
$menu_link['vid'] = entity_menu_links_insert_revision($menu_link);
if (!empty($menu_link['plid']) && ($parent_link = menu_link_load($menu_link['plid']))) {
entity_menu_links_menu_link_update($parent_link);
}
db_update('menu_links')
->fields(array(
'uuid' => $menu_link['uuid'],
'vid' => $menu_link['vid'],
))
->condition('mlid', $menu_link['mlid'])
->execute();
$entity = (object) $menu_link;
module_invoke_all('entity_insert', $entity, 'menu_link');
}
}
/**
* Implements hook_menu_link_update().
*/
function entity_menu_links_menu_link_update($menu_link) {
if ($menu_link['module'] == 'menu') {
$original = isset($menu_link['original_item']) ? $menu_link['original_item'] : (array) entity_load_unchanged('menu_link', $menu_link['mlid']);
$menu_link['uuid'] = empty($original['uuid']) ? uuid_generate() : $original['uuid'];
$menu_link['vid'] = entity_menu_links_insert_revision($menu_link);
if (!empty($menu_link['plid']) && ($parent_link = menu_link_load($menu_link['plid']))) {
entity_menu_links_menu_link_update($parent_link);
}
db_update('menu_links')
->fields(array(
'uuid' => $menu_link['uuid'],
'vid' => $menu_link['vid'],
))
->condition('mlid', $menu_link['mlid'])
->execute();
$entity = (object) $menu_link;
module_invoke_all('entity_update', $entity, 'menu_link');
}
}
/**
* Implements hook_menu_link_delete().
*/
function entity_menu_links_menu_link_delete($menu_link) {
if ($menu_link['module'] == 'menu') {
db_delete('menu_links_revision')
->condition('mlid', $menu_link['mlid'])
->execute();
$entity = (object) $menu_link;
module_invoke_all('entity_delete', $entity, 'menu_link');
}
}
/**
* Inserts a new revision for the given menu_link.
*/
function entity_menu_links_insert_revision($menu_link) {
$revision = entity_menu_links_create_revision($menu_link);
if (empty($revision['vuuid'])) {
$revision['vuuid'] = uuid_generate();
}
$vid = db_insert('menu_links_revision')
->fields($revision)
->execute();
return $vid;
}
/**
* Creates a new revision row, ready for insertion into the database.
*/
function entity_menu_links_create_revision($menu_link) {
$fields = (array) $menu_link;
$revisions = drupal_get_schema('menu_links_revision');
$rev_fields = $revisions['fields'];
foreach ($fields as $name => $value) {
if (!isset($rev_fields[$name])) {
unset($fields[$name]);
}
elseif (!is_scalar($fields[$name])) {
$fields[$name] = serialize($value);
}
}
unset($fields['vid']);
$fields['timestamp'] = time();
return $fields;
}
/**
* Returns an array of all the parent properties for menu_links
* Eg. array('plid', 'p1', 'p2', 'p3' etc...) based on the MENU_MAX_DEPTH constant defined in menu.inc
*/
function entity_menu_links_parent_properties() {
$i = 0;
$properties = array(
'plid',
);
while ($i++ < MENU_MAX_DEPTH) {
$properties[] = "p{$i}";
}
return $properties;
}
/**
* Returns an array with info about the entity that a menu_link links to based on it's link_path.
*
* @param object $menu_link
* The menu_link entity
* @param bool $universalised
* Whether the menu_link entity is universalised
* @return array | FALSE
* Eg. array('type' => 'node', 'id' => 123) OR
* array('type' => 'node', 'uuid' => <uuid> ) if $universalised = TRUE OR
* FALSE if the menu_link doesn't link to an entity.
*/
function entity_menu_links_linked_entity($menu_link, $universalised = FALSE) {
static $linked_entities = array();
$cid = ($universalised ? 'uuid' : 'id') . $menu_link->mlid;
if (isset($linked_entities[$cid])) {
return $linked_entities[$cid];
}
$linked_entity = FALSE;
drupal_alter('entity_menu_links_linked_entity', $linked_entity, $menu_link, $universalised);
if ($universalised) {
$regexp = '#([^/]+)/(' . UUID_PATTERN . ')$#';
}
else {
$regexp = '#([^/]+)/(\\d+)#';
}
if (empty($linked_entity) && preg_match($regexp, $menu_link->link_path, $matches)) {
$type = $matches[1];
$id = $matches[2];
$info = entity_get_info($type);
if (!empty($info['uuid'])) {
$linked_entity = array(
'type' => $type,
);
if ($universalised) {
$linked_entity['uuid'] = $id;
}
else {
$linked_entity['id'] = $id;
}
}
}
return $linked_entities[$cid] = $linked_entity;
}
/**
* Implements hook_entity_dependencies().
*/
function entity_menu_links_entity_dependencies($entity, $entity_type) {
if ($entity_type == 'menu_link') {
$dependencies = array();
// Eg. array('p1', 'p2', ... 'p9')
$parent_property_names = entity_menu_links_parent_properties();
$plids = array();
foreach ($parent_property_names as $pn) {
$plids[] = (int) $entity->{$pn};
}
$plids = implode(',', $plids);
// Don't add system menu items as dependencies, since they are not
// considered entities by entity_menu_links.
$menu_links = db_query("\n SELECT mlid FROM {menu_links}\n WHERE mlid IN ({$plids})\n AND module = :module", array(
':module' => 'menu',
))
->fetchAllAssoc('mlid');
foreach ($menu_links as $menu_link) {
$dependencies[] = array(
'type' => $entity_type,
'id' => $menu_link->mlid,
);
}
// Add the entity this menu_link links to, if one exists (eg. a node).
$linked_entity = entity_menu_links_linked_entity($entity);
if (!empty($linked_entity)) {
$dependencies[] = $linked_entity;
}
return $dependencies;
}
}
/**
* Implements hook_entity_uuid_load().
*/
function entity_menu_links_entity_uuid_load(&$entities, $entity_type) {
if ($entity_type == 'menu_link') {
$properties = entity_menu_links_parent_properties();
entity_property_id_to_uuid($entities, 'menu_link', $properties);
foreach ($entities as &$entity) {
$linked_entity = entity_menu_links_linked_entity($entity);
if ($linked_entity) {
$uuids = entity_get_uuid_by_id($linked_entity['type'], array(
$linked_entity['id'],
));
$entity->link_path = $linked_entity['type'] . '/' . $uuids[$linked_entity['id']];
}
}
}
}
/**
* Implements hook_entity_uuid_presave().
*/
function entity_menu_links_entity_uuid_presave(&$entity, $entity_type) {
if ($entity_type == 'menu_link') {
$properties = entity_menu_links_parent_properties();
entity_property_uuid_to_id($entity, 'menu_link', $properties);
$linked_entity = entity_menu_links_linked_entity($entity, TRUE);
if ($linked_entity) {
$type = $linked_entity['type'];
$linked_entities = entity_uuid_load($type, array(
$linked_entity['uuid'],
));
$linked_entity = reset($linked_entities);
$uri = entity_uri($type, $linked_entity);
$entity->link_path = $uri['path'];
}
}
}
/**
* Implements hook_theme_registry_alter().
*/
function entity_menu_links_theme_registry_alter(&$theme_registry) {
// Make sure that menu links don't get themed like regular entities.
$hooks = preg_grep('/^menu_link(\\.|__).+$/', array_keys($theme_registry));
foreach ($hooks as $hook) {
$theme_registry[$hook]['render element'] = 'element';
$theme_registry[$hook]['base hook'] = 'menu_link';
}
}
/**
* Implements hook form_alter().
*/
function entity_menu_links_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'menu_edit_item') {
// Check to see if module enabled, make dependency?
if (module_exists('deploy_managed_ui')) {
deploy_managed_ui_form_elements($form, 'entity_menu_links_entity_form_submit');
}
}
}
/**
* Submit handler for edit link forms to add to deployment plan.
*/
function entity_menu_links_entity_form_submit(&$form, &$form_state) {
foreach ($form_state['values']['deploy_managed_ui']['plans'] as $plan => $checked) {
if ($checked) {
$mlid = $form_state['values']['mlid'];
// Reload entity resetting internal cache otherwise it will use original revision.
$menu_link = entity_load('menu_link', array(
$mlid,
), array(), TRUE);
deploy_manager_add_to_plan($plan, 'menu_link', $menu_link[$mlid]);
}
}
}
/**
* Implements hook_modules_installed().
*/
function entity_menu_links_modules_installed($modules) {
if (in_array('i18n_menu', $modules)) {
module_load_install('i18n');
i18n_install_create_fields('menu_links_revision', array(
'language',
'i18n_tsid',
));
}
}
/**
* Implements hook_modules_uninstalled().
*/
function entity_menu_links_modules_uninstalled($modules) {
if (in_array('i18n_menu', $modules)) {
db_drop_field('menu_links_revision', 'language');
db_drop_field('menu_links_revision', 'i18n_tsid');
}
}