| 1 |
<?php |
<?php |
| 2 |
// $Id: hs_menu.module,v 1.8 2008/11/19 23:58:31 wimleers Exp $ |
// $Id: hs_menu.module,v 1.9 2008/11/29 22:57:22 wimleers Exp $ |
| 3 |
|
|
| 4 |
/** |
/** |
| 5 |
* @file |
* @file |
| 32 |
/** |
/** |
| 33 |
* Implementation of hook_form_alter(). |
* Implementation of hook_form_alter(). |
| 34 |
*/ |
*/ |
| 35 |
function hs_menu_form_alter($form_id, &$form) { |
function hs_menu_form_alter(&$form, &$form_state, $form_id) { |
| 36 |
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) { |
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) { |
| 37 |
// Content authoring form settings: "Restrict parent items to" setting. |
unset($form['menu']['parent']['#options']); |
| 38 |
$parent_mid = variable_get('menu_parent_items', 0); |
$form['menu']['parent']['#type'] = 'hierarchical_select'; |
| 39 |
|
_hs_menu_apply_config($form['menu']['parent'], NULL); |
|
_hs_menu_apply($form['menu']['pid'], NULL, $parent_mid); |
|
| 40 |
} |
} |
| 41 |
|
|
| 42 |
if ($form_id == 'menu_edit_item_form') { |
if ($form_id == 'menu_edit_item') { |
| 43 |
$mid = (isset($form['mid'])) ? $form['mid']['#value'] : NULL; |
unset($form['menu']['parent']['#options']); |
| 44 |
_hs_menu_apply($form['pid'], $mid, NULL); |
$form['menu']['parent']['#type'] = 'hierarchical_select'; |
| 45 |
|
_hs_menu_apply_config($form['menu']['parent'], array($form['menu']['#item']['menu_name'], $form['menu']['#item']['mlid'])); |
| 46 |
} |
} |
| 47 |
} |
} |
| 48 |
|
|
| 80 |
*/ |
*/ |
| 81 |
function hs_menu_hierarchical_select_params() { |
function hs_menu_hierarchical_select_params() { |
| 82 |
$params = array( |
$params = array( |
| 83 |
'mid', // The mid of the given item. This item and its children will be excluded from the hierarchy. |
'exclude', // The menu_name and mlid (in an array) of a menu link that should be excluded from the hierarchy. |
| 84 |
'parent_mid', // The parent mid, if any. 0 for the entire hierarchy. |
); |
|
); |
|
| 85 |
return $params; |
return $params; |
| 86 |
} |
} |
| 87 |
|
|
| 89 |
* Implementation of hook_hierarchical_select_root_level(). |
* Implementation of hook_hierarchical_select_root_level(). |
| 90 |
*/ |
*/ |
| 91 |
function hs_menu_hierarchical_select_root_level($params) { |
function hs_menu_hierarchical_select_root_level($params) { |
| 92 |
return hs_menu_hierarchical_select_children(0, $params); |
$menus = array(); |
| 93 |
|
|
| 94 |
|
$result = db_query("SELECT menu_name, title FROM {menu_custom} ORDER BY title"); |
| 95 |
|
while ($menu = db_fetch_object($result)) { |
| 96 |
|
$menus[$menu->menu_name . ':0'] = $menu->title; |
| 97 |
|
} |
| 98 |
|
|
| 99 |
|
return $menus; |
| 100 |
} |
} |
| 101 |
|
|
| 102 |
/** |
/** |
| 104 |
*/ |
*/ |
| 105 |
function hs_menu_hierarchical_select_children($parent, $params) { |
function hs_menu_hierarchical_select_children($parent, $params) { |
| 106 |
$children = array(); |
$children = array(); |
| 107 |
$mid = $params['mid']; |
list($menu_name, $plid) = explode(':', $parent); |
| 108 |
$pid = $parent; |
$tree = menu_tree_all_data($menu_name, NULL); |
| 109 |
$parent_mid = $params['parent_mid']; |
return _hs_menu_children($tree, $menu_name, $plid, $params['exclude']); |
|
|
|
|
if (!($parent_item = menu_get_item($pid))) { |
|
|
return $children; |
|
|
} |
|
|
// Stop processing if there aren't any children. |
|
|
else if (!isset($parent_item['children'])) { |
|
|
return $children; |
|
|
} |
|
|
|
|
|
foreach ($parent_item['children'] as $child_mid) { |
|
|
// Don't include the given item in the hierarchy! |
|
|
if ($child_mid == $params['mid']) { |
|
|
continue; |
|
|
} |
|
|
|
|
|
$child = menu_get_item($child_mid); |
|
|
if ($child['type'] & (MENU_MODIFIABLE_BY_ADMIN | MENU_IS_ROOT)) { |
|
|
$title = $child['title']; |
|
|
if (!($child['type'] & MENU_VISIBLE_IN_TREE)) { |
|
|
$title .= ' ('. t('disabled') .')'; |
|
|
} |
|
|
$children[$child_mid] = $title; |
|
|
} |
|
|
} |
|
|
|
|
|
// If this is the root level, it might contain the menu to which menu |
|
|
// items are restricted. If it does contain it, remove all other menus. |
|
|
if (isset($children[$parent_mid])) { |
|
|
foreach ($children as $child_mid => $child) { |
|
|
if ($child_mid != $parent_mid) { |
|
|
unset($children[$child_mid]); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
return $children; |
|
| 110 |
} |
} |
| 111 |
|
|
| 112 |
/** |
/** |
| 115 |
function hs_menu_hierarchical_select_lineage($item, $params) { |
function hs_menu_hierarchical_select_lineage($item, $params) { |
| 116 |
$lineage = array($item); |
$lineage = array($item); |
| 117 |
|
|
| 118 |
while (TRUE) { |
list($menu_name, $mlid) = explode(':', $item); |
|
$pid = db_result(db_query("SELECT pid FROM {menu} WHERE mid = %d", $item)); |
|
| 119 |
|
|
| 120 |
// 0 is the root menu item, so if $pid == 0, the lineage is complete! |
// If the initial mlid is zero, then this is the root level, so we don't |
| 121 |
if ($pid == 0) { |
// have to get the lineage. |
| 122 |
break; |
if ($mlid > 0) { |
| 123 |
|
// Prepend each parent mlid (i.e. plid) to the lineage. |
| 124 |
|
do { |
| 125 |
|
$plid = db_result(db_query("SELECT plid FROM {menu_links} WHERE mlid = %d", $mlid)); |
| 126 |
|
array_unshift($lineage, "$menu_name:$plid"); |
| 127 |
|
$mlid = $plid; |
| 128 |
} |
} |
| 129 |
|
while ($plid > 0); |
|
array_unshift($lineage, $pid); |
|
|
$item = $pid; |
|
| 130 |
} |
} |
| 131 |
|
|
| 132 |
return $lineage; |
return $lineage; |
| 136 |
* Implementation of hook_hierarchical_select_valid_item(). |
* Implementation of hook_hierarchical_select_valid_item(). |
| 137 |
*/ |
*/ |
| 138 |
function hs_menu_hierarchical_select_valid_item($item, $params) { |
function hs_menu_hierarchical_select_valid_item($item, $params) { |
| 139 |
if (!is_numeric($item) || $item < 1) { |
$parts = explode(':', $item); |
| 140 |
return FALSE; |
|
| 141 |
|
$valid = TRUE; |
| 142 |
|
for ($i = 1; $i < count($parts); $i++) { |
| 143 |
|
$valid = $valid && is_numeric($parts[$i]); |
| 144 |
} |
} |
| 145 |
|
|
| 146 |
$type = db_result(db_query("SELECT type FROM {menu} WHERE mid = %d", $item)); |
// Ensure that this isn't the excluded menu link. |
| 147 |
|
$valid = $valid && $item != $params['exclude'][0] . $params['exclude'][1]; |
| 148 |
|
|
| 149 |
// mid 1 corresponds to the hardcoded "Navigation" menu. |
return $valid; |
|
return (($item == 1) || ($type & (MENU_MODIFIABLE_BY_ADMIN | MENU_IS_ROOT))); |
|
| 150 |
} |
} |
| 151 |
|
|
| 152 |
/** |
/** |
| 154 |
*/ |
*/ |
| 155 |
function hs_menu_hierarchical_select_item_get_label($item, $params) { |
function hs_menu_hierarchical_select_item_get_label($item, $params) { |
| 156 |
static $labels = array(); |
static $labels = array(); |
| 157 |
|
|
| 158 |
if (!isset($labels[$item])) { |
$parts = explode(':', $item); |
| 159 |
$labels[$item] = t(db_result(db_query("SELECT title FROM {menu} WHERE mid = %d", $item))); |
if (count($parts) == 1) { // Get the menu name. |
| 160 |
|
$menu_name = $parts[0]; |
| 161 |
|
$labels[$item] = t(db_result(db_query("SELECT title FROM {menu_custom} WHERE menu_name = '%s'", $menu_name))); |
| 162 |
|
} |
| 163 |
|
else { // Get the menu link title. |
| 164 |
|
$mlid = end($parts); |
| 165 |
|
$menu_link = menu_link_load($mlid); |
| 166 |
|
$labels[$item] = $menu_link['title']; |
| 167 |
} |
} |
| 168 |
|
|
| 169 |
return $labels[$item]; |
return $labels[$item]; |
| 183 |
//---------------------------------------------------------------------------- |
//---------------------------------------------------------------------------- |
| 184 |
// Private functions. |
// Private functions. |
| 185 |
|
|
| 186 |
function _hs_menu_apply(&$form, $mid, $parent_mid) { |
/** |
| 187 |
unset($form['#options']); |
* Recursive helper function for hs_menu_hierarchical_select_children(). |
| 188 |
$form['#type'] = 'hierarchical_select'; |
*/ |
| 189 |
|
function _hs_menu_children($tree, $menu_name, $plid = 0, $exclude = FALSE) { |
| 190 |
|
global $yar; |
| 191 |
|
$children = array(); |
| 192 |
|
|
| 193 |
|
foreach ($tree as $data) { |
| 194 |
|
if ($data['link']['plid'] == $plid && $data['link']['hidden'] >= 0) { |
| 195 |
|
if ($exclude && $data['link']['menu_name'] === $exclude[0] && $data['link']['mlid'] == $exclude[1]) { |
| 196 |
|
continue; |
| 197 |
|
} |
| 198 |
|
|
| 199 |
|
$title = truncate_utf8($data['link']['title'], 30, TRUE, FALSE); |
| 200 |
|
if ($data['link']['hidden']) { |
| 201 |
|
$title .= ' ('. t('disabled') .')'; |
| 202 |
|
} |
| 203 |
|
$children[$menu_name .':'. $data['link']['mlid']] = $title; |
| 204 |
|
if ($data['below']) { |
| 205 |
|
$children += _hs_menu_children($data['below'], $menu_name, $plid, $exclude); |
| 206 |
|
} |
| 207 |
|
} |
| 208 |
|
elseif ($data['below']) { |
| 209 |
|
$children += _hs_menu_children($data['below'], $menu_name, $plid, $exclude); |
| 210 |
|
} |
| 211 |
|
} |
| 212 |
|
|
| 213 |
|
return $children; |
| 214 |
|
} |
| 215 |
|
|
| 216 |
|
/** |
| 217 |
|
* Helper function to apply the HS config to a form item. |
| 218 |
|
*/ |
| 219 |
|
function _hs_menu_apply_config(&$form, $exclude) { |
| 220 |
$form['#config'] = array( |
$form['#config'] = array( |
| 221 |
'module' => 'hs_menu', |
'module' => 'hs_menu', |
| 222 |
'params' => array( |
'params' => array( |
| 223 |
'mid' => $mid, |
'exclude' => $exclude, |
|
'parent_mid' => $parent_mid, |
|
| 224 |
), |
), |
| 225 |
'save_lineage' => 0, |
'save_lineage' => 0, |
| 226 |
'enforce_deepest' => 0, |
'enforce_deepest' => 0, |