View source
<?php
function nodesymlinks_item_delete(&$item) {
if (module_exists('path')) {
path_set_alias($item['link_path']);
}
menu_link_delete($item['mlid']);
db_query("DELETE FROM {nodesymlinks_link_storage} WHERE mlid = %d", $item['mlid']);
}
function nodesymlinks_get_items_by_nid($nid) {
$items = array();
$result = db_query("SELECT mlid,link_path FROM {menu_links} WHERE link_path LIKE 'node/%d/mid/%%' AND module = 'nodesymlinks' ", $nid);
while ($item = db_fetch_array($result)) {
$items[$item['mlid']] = $item;
}
return $items;
}
function _nodesymlinks_nodeapi_validate(&$node, $op) {
if (module_exists('path') && isset($node->menu['nodesymlinks']) && !empty($node->menu['nodesymlinks']['items'])) {
$items = (array) $node->menu['nodesymlinks']['items'];
$language = isset($node->language) ? $node->language : '';
$unique_paths = array();
if (variable_get('nodesymlinks_check_menuitem', 1) && empty($node->menu['link_title']) && count($items)) {
form_set_error('menu][link_title', t('You have some nodesymlinks defined but primary node menu item is empty. Please create node menu item first.'));
}
foreach ($items as $i => &$item) {
$item['alias']['path'] = $path = trim($item['alias']['path']);
if (!empty($item['alias']['path'])) {
if (in_array($path, $unique_paths)) {
form_set_error("menu][nodesymlinks][items][{$i}][alias][path", t('The path is already in use.'));
}
else {
$unique_paths[] = $path;
}
if (module_exists('pathauto')) {
if (empty($item['alias']['pathauto']) && empty($item['alias']['path'])) {
form_set_error("menu][nodesymlinks][items][{$i}][alias][path", t('The path is empty.'));
}
else {
$system_path = nodesymlinks_create_item_path($item, $node);
if (db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE dst = '%s' AND src != '%s' AND language = '%s'", $path, $system_path, $language))) {
form_set_error("menu][nodesymlinks][items][{$i}][alias][path", t('The path is already in use.'));
}
}
}
elseif (!empty($item['alias']['path'])) {
$system_path = nodesymlinks_create_item_path($item, $node);
if (db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE dst = '%s' AND src != '%s' AND language = '%s'", $path, $system_path, $language))) {
form_set_error("menu][nodesymlinks][items][{$i}][alias][path", t('The path is already in use.'));
}
}
}
}
}
}
function _nodesymlinks_nodeapi_insert_update(&$node, $op) {
$count_deleted = $count_saved = 0;
$items = isset($node->menu['nodesymlinks']['items']) ? $node->menu['nodesymlinks']['items'] : array();
$saved_items = array();
foreach ($items as &$item) {
nodesymlinks_item_process($item, $node);
if (!$item['is_new']) {
$saved_items[] = $item['mlid'];
}
if ($mlid = nodesymlinks_item_save($item, $node)) {
++$count_saved;
if ($item['is_new']) {
$saved_items[] = $mlid;
}
}
else {
drupal_set_message(t('There was an error when saving the menu link.'), 'error');
}
}
$db_items = nodesymlinks_get_items_by_nid($node->nid);
$items_to_delete = array_diff(array_keys($db_items), $saved_items);
while ($mlid = array_pop($items_to_delete)) {
nodesymlinks_item_delete($db_items[$mlid]);
++$count_deleted;
}
drupal_set_message(format_plural($count_saved, 'Saved 1 nodesymlink.', 'Saved @count nodesymlinks.') . ' ' . format_plural($count_deleted, 'Deleted 1 nodesymlink.', 'Deleted @count nodesymlinks.'));
}
function _nodesymlinks_nodeapi_delete(&$node, $op) {
$result = db_query("SELECT mlid FROM {menu_links} WHERE link_path LIKE 'node/%d/mid/%%' AND module = 'nodesymlinks' ", $node->nid);
while ($m = db_fetch_array($result)) {
menu_link_delete($m['mlid']);
}
db_query("DELETE FROM {url_alias} WHERE src LIKE 'node/%d/mid/%%'", $node->nid);
db_query('DELETE FROM {nodesymlinks_link_storage} WHERE nid=%d', $node->nid);
}
function _nodesymlinks_nodeapi_prepare_presave(&$node, $op) {
$items = array();
if (isset($node->nid)) {
$mlids = db_query("SELECT mlid FROM {menu_links} WHERE module = 'nodesymlinks' AND link_path LIKE 'node/%d/mid/%%' ORDER BY mlid ASC", $node->nid);
if ($mlids) {
while ($row = db_fetch_array($mlids)) {
$items[$row['mlid']] = $item = menu_link_load($row['mlid']);
$items[$row['mlid']]['fragment'] = empty($item['options']['fragment']) ? '' : $item['options']['fragment'];
if (module_exists('path')) {
$items[$row['mlid']]['alias'] = db_fetch_array(db_query("SELECT pid, dst as path FROM {url_alias} WHERE src = '%s' AND language = '%s'", $items[$row['mlid']]['link_path'], $node->language));
}
}
}
}
$node->nodesymlinks['items'] = $items;
}
function _nodesymlinks_form_field($item = NULL, $node) {
if (is_null($item)) {
$item = nodesymlinks_menu_item_defaults();
}
else {
$item += nodesymlinks_menu_item_defaults();
}
$item_form = array();
$item_form['#tree'] = TRUE;
static $item_keys = array(
'mlid',
'module',
'hidden',
'has_children',
'customized',
'options',
'expanded',
);
foreach ($item_keys as $key) {
$item_form[$key] = array(
'#type' => 'value',
'#value' => $item[$key],
);
}
$options = menu_parent_options(menu_get_menus(), $item);
$default = !empty($item['parents']) ? $item['parents'] : $item['menu_name'] . ':' . $item['plid'];
if (!isset($options[$default])) {
$default = array(
'primary-links:0',
);
}
$item_form['parents'] = array(
'#type' => 'select',
'#default_value' => $default,
'#options' => $options,
'#multiple' => FALSE,
'#description' => '',
'#attributes' => array(
'class' => 'menu-title-select',
),
);
$item_form['link_title'] = array(
'#type' => 'textfield',
'#default_value' => $item['link_title'],
'#description' => '',
'#required' => FALSE,
);
if (module_exists('path')) {
$language = isset($node->language) ? $node->language : '';
$item_form['alias'] = array(
'#tree' => TRUE,
);
if (module_exists('pathauto')) {
_nodesymlinks_include('pathauto');
if (nodesymlinks_pathauto_version() == 1) {
$pattern = _nodesymlinks_pathauto_pattern_load_by_entity($node->type, $language);
}
else {
$pattern = pathauto_pattern_load_by_entity('nodesymlinks', $node->type, $language);
}
if ($pattern) {
if (!isset($item['alias']['pathauto'])) {
if (!empty($node->nid) && !empty($item['mlid'])) {
_nodesymlinks_include('pathauto');
$pathauto_alias = nodesymlinks_pathauto_create_alias($item, $node);
$item['alias']['pathauto'] = isset($item['alias']['path']) && $item['alias']['path'] == $pathauto_alias;
}
else {
$item['alias']['pathauto'] = TRUE;
}
}
$item_form['alias']['pathauto'] = array(
'#type' => 'checkbox',
'#default_value' => $item['alias']['pathauto'],
);
}
}
$path = !empty($item['alias']['path']) ? $item['alias']['path'] : $item['alias']['old_path'];
$old_path = !empty($item['alias']['path']) ? $item['alias']['path'] : $item['alias']['old_path'];
$item_form['alias']['path'] = array(
'#type' => 'textfield',
'#default_value' => $path,
'#maxlength' => 128,
'#access' => user_access('create url aliases'),
);
$item_form['alias']['old_path'] = array(
'#type' => 'value',
'#value' => $old_path,
);
if ($path) {
$item_form['alias']['pid'] = array(
'#type' => 'value',
'#value' => db_result(db_query("SELECT pid FROM {url_alias} WHERE dst = '%s' AND language = '%s'", $path, $item['language'])),
);
}
}
$item_form['fragment'] = array(
'#type' => 'textfield',
'#default_value' => isset($item['fragment']) ? $item['fragment'] : '',
'#maxlength' => 128,
'#access' => user_access('create url aliases'),
);
$item_form['weight'] = array(
'#type' => 'weight',
'#delta' => 50,
'#default_value' => $item['weight'],
'#description' => '',
);
$item_form['delete'] = array(
'#type' => 'checkbox',
'#title' => '',
);
return $item_form;
}
function _nodesymlinks_form_alter(&$form, $form_state, $form_id) {
$form['#cache'] = TRUE;
$node = $form['#node'];
if (isset($form_state['values'])) {
$nodesymlinks = !empty($form_state['values']['menu']['nodesymlinks']['items']) ? (array) $form_state['values']['menu']['nodesymlinks']['items'] : array();
}
else {
$nodesymlinks = (array) $node->nodesymlinks['items'];
}
$collapsed = count($nodesymlinks) ? FALSE : TRUE;
$form['menu']['nodesymlinks'] = array(
'#type' => 'fieldset',
'#title' => t('Show in More Locations'),
'#access' => user_access('administer menu') && user_access('administer nodesymlinks'),
'#collapsible' => TRUE,
'#collapsed' => $collapsed,
'#tree' => TRUE,
'#weight' => 1,
'#attributes' => array(
'class' => 'nodesymlinks-items-form',
),
);
if (isset($form['menu']['submenutree'])) {
$form['menu']['submenutree']['#weight'] = 2;
$form['menu']['siblingmenutree']['#weight'] = 2;
}
$form['menu']['nodesymlinks']['items'] = array(
'#tree' => TRUE,
'#theme' => 'nodesymlinks_form_items',
);
drupal_add_js(drupal_get_path('module', 'nodesymlinks') . '/nodesymlinks.js');
$delta = 0;
foreach ($nodesymlinks as $item) {
$form['menu']['nodesymlinks']['items'][$delta++] = _nodesymlinks_form_field($item, $node);
}
if (isset($form_state['item_count']['nodesymlinks'])) {
$new_max_delta = $form_state['item_count']['nodesymlinks'] - 1;
for ($delta; $delta <= $new_max_delta; ++$delta) {
$new_item = array(
'new_item' => TRUE,
'link_title' => $node->title,
);
$form['menu']['nodesymlinks']['items'][$delta] = _nodesymlinks_form_field($new_item, $node);
}
}
$description = t('This module allows you to show this node\'s content within multiple places in your site.<br />');
$description .= '<b>' . t('Parent item') . ':</b> ' . t('The place where this page\'s content will appear. It will use the selected parent\'s breadcrumbs and sidebar. Items in the hierarchy deeper than ' . (MENU_MAX_DEPTH - 1) . ' levels may not appear.', array(
'!maxdepth' => MENU_MAX_DEPTH,
));
$description .= ' <br /><b>' . t('Link title') . ':</b> ' . t('The link text corresponding to this item that should appear in the menu.');
if (user_access('create url aliases')) {
if (module_exists('pathauto')) {
$description .= ' <br /><b>' . t('Pathauto') . ':</b> ' . t('Optional. When checked, path alias will be generated using Pathauto.');
$description .= ' <br /><b>' . t('Path') . ':</b> ' . t('Optional. When Pathauto checkbox is unchecked you can write custom unique path alias here.');
}
elseif (module_exists('path')) {
$description .= ' <br /><b>' . t('Path') . ':</b> ' . t('Optional. You can write custom unique path alias here. If you leave this field empty and node path alias is filled in (URL path settings), default alias will be generated using following pattern: <em><node-path-alias>_<menu-link-id></em>');
}
}
$description .= ' <br /><b>' . t('Weight') . ':</b> ' . t('Optional. In the menu, a higher weight number will sink down and a lower weight will be positioned closer to the top.');
$description .= ' <br /><b>' . t('Delete') . ':</b> ' . t('To delete nodesymlinks, first check the "Delete" checkbox in the desired rows, then click "Delete Location(s)".');
$description .= ' <br /><b>' . t('Saving') . ': ' . t('When you are done editing, you must click "Save" at the very bottom of the page to save your changes.') . '</b>';
$form['menu']['nodesymlinks']['#description'] = $description;
$form['menu']['nodesymlinks']['delete'] = array(
'#type' => 'submit',
'#value' => t('Delete Location(s)'),
'#submit' => array(
'nodesymlinks_node_form_submit_delete',
),
'#ahah' => array(
'path' => 'nodesymlinks/ahah',
'wrapper' => 'nodesymlinks-items-ahah',
'method' => 'replace',
'effect' => 'fade',
),
);
$form['menu']['nodesymlinks']['add'] = array(
'#type' => 'submit',
'#value' => t('Add Location'),
'#submit' => array(
'nodesymlinks_node_form_submit_add',
),
'#ahah' => array(
'path' => 'nodesymlinks/ahah',
'wrapper' => 'nodesymlinks-items-ahah',
'method' => 'replace',
'effect' => 'fade',
),
);
$form['#validate'][] = 'nodesymlinks_node_form_validate';
if (isset($form_state['clicked_button'])) {
$clicked_val = $form_state['clicked_button']['#value'];
if ($clicked_val == t('Add Location') || $clicked_val == t('Delete Location(s)')) {
$form['menu']['#collapsed'] = FALSE;
$form['menu']['nodesymlinks']['#collapsed'] = FALSE;
}
}
}
function nodesymlinks_node_form_submit_add($form, &$form_state) {
node_form_submit_build_node($form, $form_state);
if ($form_state['clicked_button']['#value'] == $form['menu']['nodesymlinks']['add']['#value']) {
$items = element_children($form['menu']['nodesymlinks']['items']);
$form_state['item_count']['nodesymlinks'] = count($items) + 1;
}
}
function nodesymlinks_node_form_submit_delete($form, &$form_state) {
if ($form_state['clicked_button']['#value'] == $form['menu']['nodesymlinks']['delete']['#value']) {
$item_keys = element_children($form['menu']['nodesymlinks']['items']);
$values_items =& $form_state['values']['menu']['nodesymlinks']['items'];
$form_items =& $form['menu']['nodesymlinks']['items'];
foreach ($item_keys as $delta) {
if (!empty($values_items[$delta]['delete']) && $values_items[$delta]['delete']) {
unset($values_items[$delta]);
unset($form_items[$delta]);
}
}
}
node_form_submit_build_node($form, $form_state);
}
function nodesymlinks_ahah_handler() {
module_load_include('inc', 'node', 'node.pages');
$form_state = array(
'storage' => NULL,
'submitted' => FALSE,
);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form['#redirect'] = FALSE;
$form['#post'] = $_POST;
$form['#programmed'] = FALSE;
$form_state['post'] = $_POST;
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
$subform = $form['menu']['nodesymlinks']['items'];
$output = theme('status_messages') . drupal_render($subform);
$GLOBALS['devel_shutdown'] = FALSE;
drupal_json(array(
'status' => TRUE,
'data' => $output,
));
}
function nodesymlinks_create_item_path(&$item, &$node) {
return 'node/' . $node->nid . '/mid/' . $item['mlid'];
}
function nodesymlinks_menu_item_defaults() {
static $item_defaults = array(
'link_title' => '',
'mlid' => 0,
'plid' => 0,
'menu_name' => 'navigation',
'weight' => 0,
'options' => array(),
'module' => 'nodesymlinks',
'expanded' => 0,
'hidden' => 0,
'has_children' => 0,
'customized' => 0,
);
return $item_defaults;
}
function nodesymlinks_item_process(&$item, &$node) {
$item += nodesymlinks_menu_item_defaults();
$item['is_new'] = $item['mlid'] == 0 ? TRUE : FALSE;
if (!empty($item['parents'])) {
list($item['menu_name'], $item['plid']) = explode(':', $item['parents']);
}
if (!$item['customized']) {
$item['options']['attributes']['title'] = trim($node->title);
}
$item['link_title'] = trim($item['link_title']) ? trim($item['link_title']) : $node->title;
$item['link_path'] = nodesymlinks_create_item_path($item, $node);
}
function nodesymlinks_item_save(&$item, &$node) {
$item['options']['fragment'] = empty($item['fragment']) ? '' : $item['fragment'];
if (menu_link_save($item)) {
if ($item['is_new']) {
$item['link_path'] = nodesymlinks_create_item_path($item, $node);
menu_link_save($item);
}
if ($item['is_new']) {
db_query("INSERT INTO {nodesymlinks_link_storage} (\n mlid, nid, item_data) VALUES (\n %d, %d, '%s')", $item['mlid'], $node->nid, serialize($item));
}
else {
db_query("UPDATE {nodesymlinks_link_storage} SET\n nid = %d, item_data = '%s' WHERE\n mlid = %d", $node->nid, serialize($item), $item['mlid']);
}
$item['link_path'] = nodesymlinks_create_item_path($item, $node);
nodesymlinks_item_alias_save($item, $node);
return $item['mlid'];
}
return FALSE;
}
function nodesymlinks_item_alias_save(&$item, &$node) {
if (module_exists('path')) {
$pid = !empty($item['alias']['pid']) ? $item['alias']['pid'] : NULL;
if (module_exists('pathauto')) {
if (!empty($item['alias']['pathauto']) || empty($item['alias']['path'])) {
$op = $item['is_new'] ? 'insert' : 'update';
_nodesymlinks_include('pathauto');
return nodesymlinks_pathauto_create_alias($item, $node, $op);
}
else {
return path_set_alias($item['link_path'], $item['alias']['path'], $pid, $node->language);
}
}
elseif (!empty($item['alias']['path'])) {
return path_set_alias($item['link_path'], trim($item['alias']['path']), $pid, $node->language);
}
else {
$path_alias = empty($node->path) || $node->path == 'node/' . $node->nid ? '' : $node->path . '_' . $item['mlid'];
return path_set_alias($item['link_path'], $path_alias, $pid, $node->language);
}
}
}
function theme_nodesymlinks_form_items($form) {
$output = '';
$output .= '<div id="nodesymlinks-items-ahah">';
$items = element_children($form);
$rows = array();
$path = $pathauto = $fragment = FALSE;
foreach ($items as $delta) {
$row = array();
$row[] = $delta;
$row[] = drupal_render($form[$delta]['delete']);
$row[] = drupal_render($form[$delta]['parents']);
$row[] = drupal_render($form[$delta]['link_title']);
if (isset($form[$delta]['alias']['pathauto'])) {
$row[] = drupal_render($form[$delta]['alias']['pathauto']);
$pathauto = TRUE;
}
if (isset($form[$delta]['alias']['path'])) {
$row[] = drupal_render($form[$delta]['alias']['path']);
$path = TRUE;
}
if (isset($form[$delta]['fragment'])) {
$row[] = drupal_render($form[$delta]['fragment']);
$fragment = TRUE;
}
$row[] = drupal_render($form[$delta]['weight']);
$rows[] = $row;
}
$header = array();
$header[] = '#';
$header[] = t('Delete');
$header[] = t('Parent item');
$header[] = t('Link title');
if ($pathauto) {
$header[] = t('Pathauto');
}
if ($path) {
$header[] = t('Path alias');
}
if ($fragment) {
$header[] = t('Fragment');
}
$header[] = t('Weight');
$output .= theme('table', $header, $rows, array(
'id' => 'nodesymlinks-items',
));
$output .= drupal_render($form);
$output .= '</div>';
return $output;
}