outline_designer_menu.module in Outline Designer 6.2
Menu intgration with Outline Designer
File
modules/outline_designer_menu/outline_designer_menu.moduleView source
<?php
/**
* @file
* Menu intgration with Outline Designer
*/
/**
* Implementation of hook_init().
*/
function outline_designer_menu_init() {
if (arg(0) == 'admin' && arg(1) == 'build' && arg(2) == 'menu-customize') {
drupal_add_css(drupal_get_path('module', 'outline_designer') . '/css/outline_designer.css');
}
}
// helper function to get a list of unavailable items
function _outline_designer_menu_get_unavailable($mlid, $ajax_path) {
global $user;
$types_ary = _outline_designer_menu_get_types();
// Make sure default is allowed by this user.
if (node_access('create', variable_get('menu_child_type', 'page'))) {
$default_type = variable_get('menu_child_type', 'page');
}
else {
foreach ($types_ary as $current_type) {
if (node_access('create', $current_type)) {
$default_type = $current_type;
}
}
}
// create the array of menu items unavailable to the user by combining
// the unavailable menu items in common in all of the user's roles
$unchecked_menu_items = array();
$view_all = FALSE;
if ($user->uid == 1) {
// user1 should always see all menu items
$view_all = TRUE;
}
else {
$saved_unchecked_items = variable_get('outline_designer_context_menu_exclusion_matrix', array());
// collect only the items unchecked in all of the user's roles
foreach (array_keys($user->roles) as $rid) {
if ($saved_unchecked_items[$rid] != NULL) {
$unchecked_menu_items = array_keys($saved_unchecked_items[$rid]);
if (isset($tmp)) {
$unchecked_menu_items = array_intersect($tmp, $unchecked_menu_items);
}
$tmp = $unchecked_menu_items;
}
else {
// role not found, they can see everything
$view_all = TRUE;
}
}
}
// the permission check found that this user should have access to view everything so ignore the unchecked metric
if ($view_all) {
$unchecked_menu_items = array();
}
return array_values($unchecked_menu_items);
}
/**
* Implementation of hook_form_alter().
*/
function outline_designer_menu_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'menu_overview_form' && (arg(0) == "admin" || arg(0) == 'outline_designer' && arg(1) == 'ajax')) {
_outline_designer_menu_admin_form_alter($form, $form_state, $form_id, 'outline_designer/ajax/');
}
}
/**
* Helper to allow other sub-sub projects to implement this
*/
function _outline_designer_menu_admin_form_alter(&$form, $form_state, $form_id, $ajax_path) {
_outline_designer_setup($ajax_path);
$icon_path = base_path() . drupal_get_path('module', 'outline_designer') . '/images/';
$unavailableContextMenuItems = _outline_designer_menu_get_unavailable($form['#menu']['menu_name'], $ajax_path);
$form['ahah'] = array(
'#type' => 'submit',
'#id' => 'reload_table',
'#value' => t('AHAH submit'),
'#weight' => 1,
'#submit' => array(),
'#ahah' => array(
'event' => 'change',
'path' => $ajax_path . drupal_get_token() . '/menu/reload_table/' . $form['#menu']['menu_name'],
'wrapper' => 'od-menu-edit',
'method' => 'replace',
'effect' => 'none',
'progress' => array(
'type' => 'throbber',
'message' => t('Loading..'),
),
),
);
$od_path = drupal_get_path('module', 'outline_designer');
// unset things so that the form renders with everything stripped off
// helps OD work in browsers that respect <enter> button for submitting the whole page/form
$form["#submit"] = '';
$form["#action"] = $ajax_path . drupal_get_token() . '/menu/reload_table/' . $form['#menu']['menu_name'];
$form["#method"] = 'POST';
$form["save"] = '';
$rendered_items = module_invoke_all('outline_designer_form_overlay');
$render = implode('', $rendered_items);
$form["#suffix"] = theme('outline_designer_overlay_suffix', $render);
$base_path = base_path();
$count = 0;
foreach ($form as $key => $row) {
$count++;
if (strpos($key, 'mlid:') !== FALSE) {
$tmpmlid = $row['mlid']['#value'];
$type = db_result(db_query("SELECT type FROM {node} WHERE nid=%d", $tmpmlid));
$form[$key]['title']['#prefix'] = theme('outline_designer_menu_prefix', $type, $tmpmlid, $icon_path);
// if this has kids then give it a drop down
if ($form[$key]['#item']['has_children'] == 1) {
$form[$key]['title']['#suffix'] = theme('outline_designer_suffix', $tmpmlid, $icon_path);
}
}
}
// this is to trap for a goofy Drupal js error that's core
if ($count == 2) {
$types_ary = _outline_designer_menu_get_types();
// make sure default is allowed by this user
if (node_access('create', variable_get('menu_child_type', 'page'))) {
$default_type = variable_get('menu_child_type', 'page');
}
else {
foreach ($types_ary as $current_type) {
if (node_access('create', $current_type)) {
$default_type = $current_type;
}
}
}
drupal_set_message(t('Menus need to have at least one piece of content in them in order to work correctly with the outline designer'), 'error');
drupal_goto($_GET['q'] . '/add', 'destination=' . $_GET['q']);
}
// check for quick add ability from context options
if (array_search('add_content', $unavailableContextMenuItems) === FALSE) {
$can_add = TRUE;
}
else {
$can_add = FALSE;
}
$form['#prefix'] = theme('outline_designer_ui_prefix', $form['#menu']['menu_name'], $icon_path, $can_add);
}
/**
* Implementation of hook_menu().
*/
function outline_designer_menu_menu() {
$items = array();
$items['admin/build/menu/outline_designer'] = array(
'title' => 'Outline designer',
'description' => 'The Outline Designer settings allow you to associate icons to content types for use in structuring menu items.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'_outline_designer_menu_settings',
),
'type' => MENU_LOCAL_TASK,
'weight' => 9,
'access arguments' => array(
'administer site configuration',
),
);
return $items;
}
/**
* Implementation of hook_settings().
*/
function _outline_designer_menu_settings($form_state) {
// build out a list of the packaged icons
$icons = array(
'add_content',
'change_type',
'close',
'delete',
'duplicate',
'edit',
'folder',
'link',
'node',
'page',
'rename',
'save',
'settings',
'story',
'view',
);
$packaged_icons = '<label>' . t('Default Icon set') . ':</label>';
foreach ($icons as $title) {
$packaged_icons .= '<img src="' . base_path() . drupal_get_path('module', 'outline_designer') . '/images/' . $title . '.png" title="' . $title . '" alt="' . $title . '" hspace="2px" />';
}
// add in archived icon set on a separate row
$packaged_icons .= '<br/><label>' . t('Additional icon') . ':</label>';
foreach ($icons as $title) {
$packaged_icons .= '<img src="' . base_path() . drupal_get_path('module', 'outline_designer') . '/images/additional_icons/' . $title . '.png" title="' . $title . '" alt="' . $title . '" hspace="2px" />';
}
// create it just incase and make sure it's writable
$dir = file_create_path(file_directory_path() . '/outline_designer');
file_check_directory($dir, 1);
// make sure it can be opened
if ($handle = opendir('./' . file_directory_path() . '/outline_designer')) {
while (FALSE !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
$uploaded_icons .= '<img src="' . base_path() . file_directory_path() . '/outline_designer/' . $file . '" title="' . $file . '" alt="' . $file . '" hspace="2px" />';
}
}
closedir($handle);
}
// context menu settings
$form["context_menu"] = array(
'#type' => 'fieldset',
'#title' => t('Context menu'),
'#collapsed' => FALSE,
'#collapsible' => TRUE,
'#description' => 'The selected items will appear in the Outline Designer context menu, depending on the user\'s roles. Users with several roles will cumulate the roles settings.',
'#theme' => 'outline_designer_context_menu_items_matrix',
);
$roles = user_roles(TRUE);
// build list of operations
$ops = _outline_designer_get_operations('menu');
$saved_unchecked_items = variable_get('outline_designer_context_menu_exclusion_matrix', array());
// create a checkbox for each menu item for each role
foreach ($ops as $key => $op) {
foreach ($roles as $rid => $role) {
// if the checkbox is present in the 'outline_designer_context_menu_exclusion_matrix' variable,
// then we need to uncheck it (e.g. assign FALSE to #default_value)
$default_value = isset($saved_unchecked_items[$rid][$key]['unchecked']) ? FALSE : TRUE;
$form["context_menu"]["checkboxes"][$key]["outline_designer_context_menu_" . $key . "_" . $rid] = array(
'#name' => 'outline_designer_context_menu_' . $key . '_' . $rid,
'#type' => 'checkbox',
'#title' => $op['title'],
'#default_value' => $default_value,
'#return_value' => array(
'operation' => $key,
'rid' => $rid,
),
);
}
}
// icons
$form["packaged_icons"] = array(
'#type' => 'fieldset',
'#title' => t('Packaged icons'),
'#collapsed' => FALSE,
'#collapsible' => TRUE,
);
$form["packaged_icons"]["packaged"] = array(
'#type' => 'markup',
'#title' => 'packaged',
'#value' => $packaged_icons,
);
$form["uploaded_icons"] = array(
'#type' => 'fieldset',
'#title' => t('Uploaded icons'),
'#collapsed' => FALSE,
'#collapsible' => TRUE,
);
$form["uploaded_icons"]["uploaded"] = array(
'#type' => 'markup',
'#value' => $uploaded_icons,
);
$result = db_query("SELECT type, name FROM {node_type}");
$types_ary = _outline_designer_menu_get_types();
while ($value = db_fetch_array($result)) {
// only show types that are allowed
if (in_array($value['type'], $types_ary)) {
// create a textfield incase they want to enter an icon that way
$img = '<img src="' . base_path() . variable_get("outline_designer_" . $value['type'] . "_icon", drupal_get_path('module', 'outline_designer') . "/images/page.png") . '" style="display:inline !important" /> ';
$form["outline_designer_" . $value['type']] = array(
'#type' => 'fieldset',
'#title' => $img . $value['name'],
'#collapsed' => TRUE,
'#collapsible' => TRUE,
'#description' => t("This icon will be associated to the content type in menu outlines. The icon must be 16x16, unless an <a href=@toolkit>image toolkit</a> is installed, and in jpg, gif or png format.", array(
'@toolkit' => url('admin/settings/image-toolkit'),
)),
);
$form["outline_designer_" . $value['type']]["outline_designer_" . $value['type'] . "_icon_link"] = array(
'#type' => 'textfield',
'#title' => t("Icon path"),
'#default_value' => variable_get("outline_designer_" . $value['type'] . "_icon", drupal_get_path('module', 'outline_designer') . "/images/page.png"),
'#required' => FALSE,
);
// Create a upload field for each content type so icons can be added for them
$form["outline_designer_" . $value['type']]["outline_designer_" . $value['type'] . "_icon"] = array(
'#type' => 'file',
'#size' => '10',
'#title' => t("Upload icon"),
'#required' => FALSE,
);
}
}
$form['#attributes'] = array(
'enctype' => "multipart/form-data",
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
/**
* Implementation of hook_settings_submit().
*/
function _outline_designer_menu_settings_submit($form, &$form_state) {
$checkboxes = array();
$items_unchecked = array();
// store the context menu settings
$form_values = array_filter($form_state['values']);
$menu_items = array_keys($form["context_menu"]["checkboxes"]);
// collect all the ticked checkboxes
foreach ($form_values as $key => $val) {
if (strpos($key, "outline_designer_context_menu_") !== FALSE) {
$checkboxes[] = $key;
}
}
// extrapolate which items have unchecked by comparing the list of
// ticked checkboxes with the list of all the context menu checkboxes
foreach ($menu_items as $item) {
if (drupal_substr($item, 0, 1) != "#") {
$item_checkboxes = $form["context_menu"]["checkboxes"][$item];
foreach ($item_checkboxes as $cb_name => $cb_properties) {
if ($cb_properties['#type'] == 'checkbox' && !in_array($cb_name, $checkboxes)) {
$items_unchecked[$cb_properties['#return_value']['rid']][$cb_properties['#return_value']['operation']]['unchecked'] = TRUE;
}
}
}
}
variable_set('outline_designer_context_menu_exclusion_matrix', array_filter($items_unchecked));
// store the checkbox value
variable_set('outline_designer_collapse_toggle', $form_state['values']["outline_designer_collapse_toggle"]);
// store theme selected
variable_set('outline_designer_theme', $form_state['values']["outline_designer_theme"]);
// take into account outline child pages
if (function_exists('outline_child_pages_menu')) {
variable_set('outline_child_pages_type', $form_state['values']["outline_child_pages_type"]);
}
// the rest is for files
$dir = file_create_path(file_directory_path() . '/outline_designer');
$is_writable = file_check_directory($dir, 1);
if ($is_writable) {
$validators = array(
'file_validate_is_image' => array(),
'_outline_designer_menu_validate_image_resolution' => array(
'16x16',
),
'file_validate_size' => array(
30 * 1024,
),
);
$result = db_query("SELECT type, name FROM {node_type}");
while ($value = db_fetch_array($result)) {
if ($file = file_save_upload("outline_designer_" . $value['type'] . "_icon", $validators, $dir)) {
drupal_set_message(t('New @title icon saved.', array(
'@title' => $value['name'],
)));
variable_set("outline_designer_" . $value['type'] . "_icon", $file->filepath);
}
else {
// this is the case when there is no image uploaded to associate the textfield icon to the icon page to use, this will allow for references to icons already used
$icon = check_plain($form_state['values']["outline_designer_" . $value['type'] . "_icon_link"]);
$base_path = base_path();
// pull off the site name if it was included
if ($base_path != '/' && $base_path != '') {
if (strpos(' ' . $icon, $base_path) != 0) {
$pos = strpos($icon, $base_path) + drupal_strlen($base_path);
$icon = drupal_substr($icon, $pos);
}
}
// clean up the string incase those other two didn't do the trick
$icon = drupal_substr($icon, strpos($icon, drupal_get_path('module', 'outline_designer')));
$icon = drupal_substr($icon, strpos($icon, file_directory_path()));
// potentially this isn't a valid icon path on our server...need to still check this
variable_set("outline_designer_" . $value['type'] . "_icon", $icon);
}
}
}
drupal_set_message(t('Settings saved'));
}
// used in validating that an icon upload is the correct size
function _outline_designer_menu_validate_image_resolution(&$file, $dimensions) {
$errors = array();
// Check first that the file is an image.
if ($info = image_get_info($file->filepath)) {
// Check if the icon matches the given dimensions.
list($width, $height) = explode('x', $dimensions);
if ($info['width'] != $width || $info['height'] != $height) {
// Try to resize the image to fit the dimensions if it doesn't.
if (image_get_toolkit() && image_scale_and_crop($file->filepath, $file->filepath, $width, $height)) {
drupal_set_message(t('The image was resized to the allowed dimensions of %dimensions pixels.', array(
'%dimensions' => $dimensions,
)));
// Clear the cached filesize and refresh the image information.
clearstatcache();
$info = image_get_info($file->filepath);
$file->filesize = $info['file_size'];
}
else {
$errors[] = t('Image dimensions need to be %dimensions pixels.', array(
'%dimensions' => $maximum_dimensions,
));
}
}
}
return $errors;
}
/**
* Helper function to return valid node types for menus.
*/
function _outline_designer_menu_get_types() {
$types_ary = array();
foreach (node_get_types() as $type_data) {
$types_ary[] = $type_data->type;
}
return $types_ary;
}
/**
* Implementation of hook_outline_designer_form_overlay().
*/
function outline_designer_menu_outline_designer_form_overlay() {
$types_ary = _outline_designer_menu_get_types();
// make sure the user can submit these types via permissions
$result = db_query("SELECT type,name FROM {node_type} ORDER BY name");
$typeoutput = '<table><tr>';
$count = 0;
while ($value = db_fetch_array($result)) {
// ensure there is no permission escalation in type switching
if (array_search($value['type'], $types_ary) === FALSE) {
}
elseif (node_access('create', $value['type'])) {
$count++;
$typeoutput .= '<td><input type="radio" class="type_radio" name="content_type[]" value="' . $value['type'] . '"/> <img src="' . base_path() . variable_get("outline_designer_" . $value['type'] . "_icon", drupal_get_path('module', 'outline_designer') . "/images/page.png") . '" />' . $value['name'] . '</td>';
if ($count % 3 == 0) {
$typeoutput .= '</tr><tr>';
}
}
}
$typeoutput .= '</tr></table>';
$duplicate_form['od_duplicate_number'] = array(
'#title' => t('How many copies would you like?'),
'#type' => 'select',
'#id' => 'od_duplicate_number',
'#description' => t('Duplicates will be performed one at a time to avoid load issues'),
'#options' => array(
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
),
'#required' => TRUE,
'#default_value' => 1,
'#weight' => 0,
);
$duplicate_form['od_duplicate_multiple'] = array(
'#title' => t('Duplicate hierarchy'),
'#id' => 'od_duplicate_multiple',
'#type' => 'checkbox',
'#attributes' => array(
'checked' => 'checked',
),
'#description' => t('If checked, the current content and all child pages will be duplicated'),
'#weight' => 1,
);
$duplicate_form['od_duplicate_title'] = array(
'#title' => t('Title format'),
'#id' => 'od_duplicate_title',
'#type' => 'textfield',
'#required' => TRUE,
'#size' => 20,
'#description' => t('Tokens: @title = content title; @i = duplicate number'),
'#weight' => 2,
);
// delete form
$delete_form['od_delete_multiple'] = array(
'#title' => t('Delete hierarchy'),
'#id' => 'od_delete_multiple',
'#type' => 'checkbox',
'#description' => t('Warning: This action cannot be undone.'),
'#weight' => 0,
);
// add form
$add_form['od_add_content_title'] = array(
'#title' => t('Title'),
'#id' => 'od_add_content_title',
'#type' => 'textfield',
'#required' => TRUE,
'#size' => 20,
'#description' => t('Make sure you edit content after creation if it has "required fields"
'),
'#weight' => 0,
'#suffix' => $typeoutput,
);
$output = '<div id="od_duplicate" class="od_uiscreen">
' . drupal_render($duplicate_form) . '
</div>
<div id="od_delete" class="od_uiscreen">
' . drupal_render($delete_form) . '
</div>
<div id="od_add_content" class="od_uiscreen">
' . drupal_render($add_form) . '
</div>';
return $output;
}
/**
* Implementation of hook_outline_designer_operations().
*/
function outline_designer_menu_outline_designer_operations($type) {
// core API invoking functionality
switch ($type) {
case 'menu':
$ops = array(
'drag_drop' => array(
'title' => '<<OUTLINE_DESIGNER_API_ONLY>>',
'callback' => 'outline_designer_menu_process_drag_drop',
),
'reweight' => array(
'title' => '<<OUTLINE_DESIGNER_API_ONLY>>',
'callback' => 'outline_designer_menu_process_reweight',
),
'reload_table' => array(
'title' => '<<OUTLINE_DESIGNER_API_ONLY>>',
'callback' => 'outline_designer_menu_process_reload_table',
),
);
break;
}
return $ops;
}
/**
* Implementation of hook_outline_designer_operations_alter().
*/
function outline_designer_menu_outline_designer_operations_alter(&$ops, $type) {
// seems silly but this way other hooked in actions are last
switch ($type) {
case 'menu':
$icon_path = drupal_get_path('module', 'outline_designer') . '/images/';
$od_menu_core = array(
'mlid' => array(
'title' => t('Menu id'),
'icon' => $icon_path . 'node.png',
),
'add_content' => array(
'title' => t('Add item'),
'icon' => $icon_path . 'add_content.png',
'callback' => 'outline_designer_menu_process_add_content',
),
'rename' => array(
'title' => t('Rename'),
'icon' => $icon_path . 'rename.png',
'callback' => 'outline_designer_menu_process_rename',
),
'edit' => array(
'title' => t('Edit'),
'icon' => $icon_path . 'edit.png',
),
'view' => array(
'title' => t('View'),
'icon' => $icon_path . 'view.png',
),
'delete' => array(
'title' => t('Delete'),
'icon' => $icon_path . 'delete.png',
'callback' => 'outline_designer_menu_process_delete',
),
'duplicate' => array(
'title' => t('Duplicate'),
'icon' => $icon_path . 'duplicate.png',
'callback' => 'outline_designer_menu_process_duplicate',
),
);
$ops = array_merge($od_menu_core, $ops);
break;
}
}
/**
* Implementation of hook_outline_designer_ops_js().
*/
function outline_designer_menu_outline_designer_ops_js() {
drupal_add_js(drupal_get_path('module', 'outline_designer_menu') . '/js/overrides.js', 'header');
drupal_add_js(drupal_get_path('module', 'outline_designer_menu') . '/js/outline_designer_menu.js', 'footer');
global $user;
$types_ary = _outline_designer_menu_get_types();
// Make sure default is allowed by this user.
if (node_access('create', variable_get('menu_child_type', 'page'))) {
$default_type = variable_get('menu_child_type', 'page');
}
else {
foreach ($types_ary as $current_type) {
if (node_access('create', $current_type)) {
$default_type = $current_type;
}
}
}
// create the array of menu items unavailable to the user by combining
// the unavailable menu items in common in all of the user's roles
$unchecked_menu_items = array();
$view_all = FALSE;
if ($user->uid == 1) {
// user1 should always see all menu items
$view_all = TRUE;
}
else {
$saved_unchecked_items = variable_get('outline_designer_context_menu_exclusion_matrix', array());
// collect only the items unchecked in all of the user's roles
foreach (array_keys($user->roles) as $rid) {
if ($saved_unchecked_items[$rid] != NULL) {
$unchecked_menu_items = array_keys($saved_unchecked_items[$rid]);
if (isset($tmp)) {
$unchecked_menu_items = array_intersect($tmp, $unchecked_menu_items);
}
$tmp = $unchecked_menu_items;
}
else {
// role not found, they can see everything
$view_all = TRUE;
}
}
}
// the permission check found that this user should have access to view everything so ignore the unchecked metric
if ($view_all) {
$unchecked_menu_items = array();
}
// pass variables to js
$js_variables = array(
'outline_designer' => array(
'types' => array(),
'unavailableContextMenuItems' => array_values($unchecked_menu_items),
'operations' => _outline_designer_get_operations('menu'),
'activeNid' => '',
'type' => 'menu',
'rootMenu' => '',
'defaultType' => $default_type,
'activeType' => $default_type,
),
);
$result = db_query("SELECT type, name FROM {node_type} ORDER BY name");
while ($value = db_fetch_array($result)) {
// ensure there is no permission escalation
if (array_search($value['type'], $types_ary) === FALSE) {
}
elseif (node_access('create', $value['type'])) {
$js_variables['outline_designer_menu']['types'][$value['type']] = array(
$value['name'],
variable_get("outline_designer_" . $value['type'] . "_icon", drupal_get_path('module', 'outline_designer') . "/images/page.png"),
);
}
}
drupal_add_js($js_variables, "setting");
return 1;
}
/**
* Callback for add_content ajax call from outline designer.
*/
function outline_designer_menu_process_add_content($title, $type, $parent_mlid) {
global $user;
// need to account for the 3 weird characters in URLs
$title = str_replace("@2@F@", '/', $title);
$title = str_replace("@2@3@", '#', $title);
$title = str_replace("@2@B@", '+', $title);
$title = str_replace("@2@6@", '&', $title);
// set the node
$item = array();
$item['title'] = $title;
// load up the parent of this new item and then copy over the menu structure stuff
$parent = menu_link_load($parent_mlid);
$item['weight'] = -15;
$item['plid'] = $parent['mlid'];
$item['menu_name'] = $parent['menu_name'];
$item['module'] = $parent['module'];
// Allow other modules to alter the new menu item specific to outline designer.
drupal_alter('new_menu_object', $item);
if (menu_link_save($item)) {
watchdog('content', 'Menu item: added %title.', array(
'%title' => $item['title'],
));
return $parent['mlid'] . ';msg:' . t('Menu item added (mlid: %mlid)', array(
'%mlid' => $item['mlid'],
));
}
else {
return 0;
}
}
/**
* Callback for rename ajax call from outline designer.
*/
function outline_designer_menu_process_rename($nid, $newtitle, $var3) {
// need to account for the 3 weird characters in URLs
$newtitle = str_replace("@2@F@", '/', $newtitle);
$newtitle = str_replace("@2@3@", '#', $newtitle);
$newtitle = str_replace("@2@B@", '+', $newtitle);
$newtitle = str_replace("@2@6@", '&', $newtitle);
$node = node_load($nid);
if (node_access('update', $node)) {
$node->log = t("Outline Designer -- node renamed from %title to %newtitle", array(
'%title' => $node->title,
'%newtitle' => $newtitle,
));
$msg = t("Outline Designer -- node %nid renamed from %title to %newtitle", array(
'%nid' => $nid,
'%title' => $node->title,
'%newtitle' => $newtitle,
));
watchdog('content', $msg);
$oldtitle = $node->title;
$node->title = $newtitle;
$node->revision = 1;
node_save($node);
return t("Content renamed from %title to %newtitle", array(
'%title' => $oldtitle,
'%newtitle' => $newtitle,
));
}
else {
return t("You don't have permissions to rename this content");
}
}
/**
* Callback for duplicate ajax call from outline designer.
*/
function outline_designer_menu_process_duplicate($nid, $multiple, $dup_title) {
// need to account for the 3 weird characters in URLs
$dup_title = str_replace("@2@F@", '/', $dup_title);
$dup_title = str_replace("@2@3@", '#', $dup_title);
$dup_title = str_replace("@2@B@", '+', $dup_title);
// only duplicate 1 item
if ($multiple == 0) {
$node = node_load($nid);
$orig_node = $node;
$node->nid = NULL;
$node->created = NULL;
$node->book['mlid'] = NULL;
$node->book['has_children'] = 0;
$node->uid = $user->uid;
// swap out the title
$new_title = str_replace('@title', $node->title, $dup_title);
$node->title = $new_title;
if (node_access('create', $node) && node_access('view', $orig_node)) {
node_save($node);
$msg = t('%type: duplicated %title from node %nid.', array(
'%type' => $node->type,
'%title' => $node->title,
'%nid' => $nid,
));
watchdog('content', $msg);
return t('Content duplicated from %title (%nid).', array(
'%title' => $node->title,
'%nid' => $nid,
));
}
else {
return 0;
}
}
else {
// snag the whole branch if multiple == 1
$permission_fail = FALSE;
$nids = $nid;
$map = array();
$node = node_load($nid);
// pull only the nodes that have the original node as a parent
$mlid = $node->book['mlid'];
// ensure this is a real value
if ($mlid != 0 && $mlid != '') {
$result = db_query("\n SELECT link_path\n FROM {menu_links}\n WHERE p2=%d OR p3=%d OR p4=%d OR p5=%d OR p6=%d OR p7=%d OR p8=%d OR p9=%d\n ORDER BY depth ASC", $mlid, $mlid, $mlid, $mlid, $mlid, $mlid, $mlid, $mlid);
while ($value = db_fetch_array($result)) {
$dup_node = node_load(str_replace('node/', '', $value['link_path']));
$orig_node = $dup_node;
$current_nid = $dup_node->nid;
$old_nid = $dup_node->nid;
$dup_node->nid = NULL;
$dup_node->created = NULL;
$dup_node->path = NULL;
$dup_node->uid = $user->uid;
$dup_node->revision = 1;
// swap out the title
$dup_node->title = str_replace('@title', $dup_node->title, $dup_title);
$old_mlid = $dup_node->book['mlid'];
$dup_node->book['mlid'] = NULL;
$dup_node->log = t("Outline Designer -- Duplicate of old node nid:%old_nid", array(
'%old_nid' => $old_nid,
));
if (isset($map[$dup_node->book['plid']])) {
$dup_node->book['plid'] = $map[$dup_node->book['plid']];
}
if (node_access('create', $dup_node) && node_access('view', $orig_node)) {
node_save($dup_node);
$map[$old_mlid] = $dup_node->book['mlid'];
watchdog('content', '%type: duplicated %title from node %current_nid.', array(
'%type' => $dup_node->type,
'%title' => $dup_node->title,
'%current_nid' => $current_nid,
));
$nids .= ', ' . $old_nid;
}
else {
$permission_fail = TRUE;
}
}
}
else {
$permission_fail = TRUE;
}
// perm failure, blocked from happening
if ($permission_fail) {
return 0;
}
else {
return t('Content duplicated (nids:%nids)', array(
'%nids' => $nids,
));
}
}
}
/**
* Callback for delete ajax call from outline designer.
*/
function outline_designer_menu_process_delete($nid, $multiple, $var3) {
// load node
$node = node_load($nid);
// check for multiple or single delete
if ($multiple == 0) {
// verify access for delete condition
if (node_access('delete', $node)) {
node_delete($nid);
return t('Content deleted (nid:%nid)', array(
'%nid' => $nid,
));
}
else {
return 0;
}
}
else {
// pull only the nodes that have this node as a parent
$mlid = $node->book['mlid'];
// make sure this isn't used to delete non book nodes
$del_count = 0;
$count = 0;
// verify this is in a menu, this is an additional form of protection
if ($mlid != 0 && $mlid != '') {
// select everything that has this mlid as a parent
// the verification previous to this ensures massive chaos isn't invoked
$result = db_query("SELECT link_path FROM {menu_links} WHERE module='book' AND (p1=%d OR p2=%d OR p3=%d OR p4=%d OR p5=%d OR p6=%d OR p7=%d OR p8=%d OR p9=%d)", $mlid, $mlid, $mlid, $mlid, $mlid, $mlid, $mlid, $mlid, $mlid);
// loop through deletes
while ($value = db_fetch_array($result)) {
$count++;
$node = node_load(str_replace('node/', '', $value['link_path']));
// ensure access even though this is largly an admin only routine
if (node_access('delete', $node)) {
$del_count++;
node_delete($node->nid);
}
}
}
// we didn't delete anything, return nothing
if ($del_count == 0) {
return 0;
}
elseif ($count != $del_count) {
return t("A multiple delete was commited but you didn't have the permissions to delete all content so some remain.");
}
else {
return t("All content deleted successfully.");
}
}
}
/**
* Callback for change_type ajax call from outline designer.
*/
function outline_designer_menu_process_change_type($nid, $new_type, $var3) {
// load the node id we were passed
$node = node_load($nid);
// need update rights or do nothing
if (node_access('update', $node)) {
// make message, we put this a lot of places as type change is abnormal
$msg = t('Outline Designer -- Content Type changed from %type to %new_type', array(
'%type' => $node->type,
'%new_type' => $new_type,
));
// add it to the log
$node->log = $msg;
$node->type = $new_type;
// write to the watch dog
watchdog('content', $msg);
node_save($node);
// return to the screen
return $msg;
}
else {
return 0;
}
}
/**
* Callback for drag_drop ajax call from outline designer.
*/
function outline_designer_menu_process_drag_drop($mlid, $parent_mlid, $weight) {
$item = menu_link_load($mlid);
// make sure they can update this node
$item['plid'] = $parent_mlid;
$item['weight'] = $weight;
if (menu_link_save($item)) {
return t("Position has been updated (mlid:%mlid)", array(
'%mlid' => $mlid,
));
}
else {
return t("Position has not been updated due to invalid permissions!");
}
}
/**
* Callback for reweight ajax call from outline designer.
*/
function outline_designer_menu_process_reweight($mlid, $weight, $var3) {
$item = menu_link_load($mlid);
// make sure they can update this node
$item['weight'] = $weight;
if (menu_link_save($item)) {
return t("Position has been updated (mlid:%mlid)", array(
'%mlid' => $mlid,
));
}
else {
return t("Position has not been updated due to invalid permissions!");
}
}
/**
* Callback for reload_table ajax call from outline designer.
*/
function outline_designer_menu_process_reload_table($menu_name, $var2, $var3) {
module_load_include('inc', 'menu', 'menu.admin');
// set a fake form state
$form_state = array(
'storage' => NULL,
'submitted' => FALSE,
'post' => array(),
);
// load menu
$menu = menu_load($menu_name);
// load the form for rendering the table
$form = menu_overview_form($form_state, $menu);
// render the table
$output = theme('menu_overview_form', $form);
// encode table for submission back to the screen
drupal_json(array(
'status' => TRUE,
'data' => $output,
));
return '';
}
/**
* Implements hook_theme().
*/
function outline_designer_menu_theme() {
$theme = array(
'outline_designer_menu_prefix' => array(
'arguments' => array(
'type' => NULL,
'mlid' => NULL,
'icon_path' => NULL,
),
),
);
return $theme;
}
/**
* Theme Callback: Outline Designer menu page prefix
*/
function theme_outline_designer_menu_prefix($type, $mlid, $icon_path) {
return '<img alt="' . $type . '" id="mlid-' . $mlid . '-icon" src="' . base_path() . variable_get("outline_designer_" . $type . "_icon", drupal_get_path('module', 'outline_designer') . "/images/page.png") . '" alt="mlid: ' . $mlid . '" title="mlid: ' . $mlid . '" style="float:left; margin:2px;" /><img src="' . $icon_path . 'settings.png" alt="' . t('Content operations') . '" title="' . t('Content operations') . '" id="mlid-' . $mlid . '" class="outline_designer_edit_button" />';
}
Functions
Name![]() |
Description |
---|---|
outline_designer_menu_form_alter | Implementation of hook_form_alter(). |
outline_designer_menu_init | Implementation of hook_init(). |
outline_designer_menu_menu | Implementation of hook_menu(). |
outline_designer_menu_outline_designer_form_overlay | Implementation of hook_outline_designer_form_overlay(). |
outline_designer_menu_outline_designer_operations | Implementation of hook_outline_designer_operations(). |
outline_designer_menu_outline_designer_operations_alter | Implementation of hook_outline_designer_operations_alter(). |
outline_designer_menu_outline_designer_ops_js | Implementation of hook_outline_designer_ops_js(). |
outline_designer_menu_process_add_content | Callback for add_content ajax call from outline designer. |
outline_designer_menu_process_change_type | Callback for change_type ajax call from outline designer. |
outline_designer_menu_process_delete | Callback for delete ajax call from outline designer. |
outline_designer_menu_process_drag_drop | Callback for drag_drop ajax call from outline designer. |
outline_designer_menu_process_duplicate | Callback for duplicate ajax call from outline designer. |
outline_designer_menu_process_reload_table | Callback for reload_table ajax call from outline designer. |
outline_designer_menu_process_rename | Callback for rename ajax call from outline designer. |
outline_designer_menu_process_reweight | Callback for reweight ajax call from outline designer. |
outline_designer_menu_theme | Implements hook_theme(). |
theme_outline_designer_menu_prefix | Theme Callback: Outline Designer menu page prefix |
_outline_designer_menu_admin_form_alter | Helper to allow other sub-sub projects to implement this |
_outline_designer_menu_get_types | Helper function to return valid node types for menus. |
_outline_designer_menu_get_unavailable | |
_outline_designer_menu_settings | Implementation of hook_settings(). |
_outline_designer_menu_settings_submit | Implementation of hook_settings_submit(). |
_outline_designer_menu_validate_image_resolution |