content_menu.menu_admin.inc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. <?php
  2. /**
  3. * @file
  4. * Menu Management Workflow improvements.
  5. */
  6. /**
  7. * Callback for altered admin/structure/menu router item.
  8. *
  9. * Only show custom menus to regular sitebuilders/editors (no system menus).
  10. */
  11. function _content_menu_menu_overview_page_extended() {
  12. $result = db_query("SELECT * FROM {menu_custom} ORDER BY title", array(), array('fetch' => PDO::FETCH_ASSOC));
  13. $header = array(t('Title'), array('data' => t('Operations'), 'colspan' => '1'));
  14. $rows = array();
  15. foreach ($result as $menu) {
  16. if (content_menu_is_menu_considered($menu['menu_name']) || user_access('administer system menus')) {
  17. $url = 'admin/structure/menu/manage/' . $menu['menu_name'];
  18. $row = array(theme('menu_admin_overview', array('title' => $menu['title'], 'name' => $menu['menu_name'], 'description' => $menu['description'])));
  19. $row[] = array('data' => l(t('Edit'), $url));
  20. $rows[] = $row;
  21. }
  22. }
  23. return theme('table', array('header' => $header, 'rows' => $rows));
  24. }
  25. /**
  26. * Actual implementation for content_menu_form_menu_overview_form_alter().
  27. *
  28. * Overhaul the menu_overview_form to improve menu authoring experience.
  29. */
  30. function _content_menu_form_menu_overview_form_alter(&$form, &$form_state, $form_id) {
  31. $form['#theme'][0] = 'menu_overview_form_extended';
  32. // Check whether any filtering element should be acitvated.
  33. $filtering_active = TRUE;
  34. // Filtering depends on ctools module.
  35. // @todo Remove ctools dependency as ajax is actually not used.
  36. $filtering_active = $filtering_active && module_exists('ctools');
  37. if ($filtering_active) {
  38. // Add form elements for filters.
  39. // @todo Add configuration interface for filters.
  40. require_once 'filters/content_menu_domain_filter.php';
  41. require_once 'filters/content_menu_language_filter.php';
  42. $filters = array(new content_menu_domain_filter(), new content_menu_language_filter($form['#menu']['menu_name']));
  43. // Add filter widgets to form.
  44. foreach ($filters as $f) {
  45. $f->addFilterWidget($form, $form_state, $form_id);
  46. }
  47. }
  48. // ToDo: Clean up and untangle operations-changing and target_content setting.
  49. $hidden = array();
  50. // Adjust operations for each item.
  51. foreach (element_children($form) as $mlid) {
  52. $el = &$form[$mlid];
  53. if ($filtering_active) {
  54. foreach ($filters as $f) {
  55. if ($f->hideElement($el)) {
  56. unset($form[$mlid]);
  57. $hidden[$el['#item']['mlid']] = $el['#item']['mlid'];
  58. continue;
  59. }
  60. }
  61. }
  62. if (isset($el['#item']['plid']) &&
  63. isset($hidden[$el['#item']['plid']])) {
  64. // Check if a parent has been disabled before.
  65. // If so, the childern will be hidden too.
  66. unset($form[$mlid]);
  67. $hidden[$el['#item']['mlid']] = $el['#item']['mlid'];
  68. continue;
  69. }
  70. $el['#inline_edit_title'] = TRUE;
  71. if (isset($form[$mlid]['operations'])) {
  72. // Invoke hook to let modules provide target operations for new item.
  73. drupal_alter('menu_item_element', $el);
  74. // Make sure that operations are ordered by their weight, then unset it.
  75. uasort($el['operations'], 'drupal_sort_weight');
  76. foreach ($el['operations'] as $el_op_key => $el_op) {
  77. unset($el['operations'][$el_op_key]['weight']);
  78. }
  79. // Wrap link-type operations into CTools dropbutton, if available.
  80. if (module_exists('ctools') && isset($el['operations'])) {
  81. // Split up operation in dropbutton-ops and other ops.
  82. $other_operations = array();
  83. $dropbutton_operations = array();
  84. foreach ($form[$mlid]['operations'] as $op_key => $op_item) {
  85. if (is_array($op_item) && isset($op_item['#type'])) {
  86. if ($op_item['#type'] == 'link') {
  87. $dropbutton_operations[$op_key] = array(
  88. 'title' => $op_item['#title'],
  89. 'href' => $op_item['#href'],
  90. );
  91. if (isset($op_item['#options'])) {
  92. $dropbutton_operations[$op_key] += $op_item['#options'];
  93. }
  94. }
  95. else {
  96. $other_operations[$op_key] = $op_item;
  97. }
  98. }
  99. }
  100. // Compose operation from dropbutton and other ops.
  101. $el['operations'] = array();
  102. $el['operations']['dropbutton_operations'] = array(
  103. '#theme' => 'links__ctools_dropbutton',
  104. '#links' => $dropbutton_operations,
  105. );
  106. $el['operations'] += $other_operations;
  107. }
  108. // Count operations of this item.
  109. $el['#operations_count'] = count($form[$mlid]['operations']);
  110. }
  111. // Add inline-editing for menu item title.
  112. if ($el['#inline_edit_title'] && isset($el['title'])) {
  113. // ToDo: Check title inplace-edit for multilanguage compatibility issues.
  114. $title = $el['#item']['title'];
  115. $el['title'] = array(
  116. '#type' => 'textfield',
  117. '#default_value' => $title,
  118. '#size' => 30,
  119. '#maxlength' => 255,
  120. '#prefix' => '<span class="menu-overview-title-link">' . $el['title']['#markup'] . '</span>',
  121. '#suffix' => '<a href="javascript:void();" title="Click to edit title" class="menu-overview-title-edit-trigger">' . t('edit title') . '</a>',
  122. );
  123. $form['#attached']['js'] = array(drupal_get_path('module', 'content_menu') . '/content_menu.js');
  124. }
  125. }
  126. // Add "add item" item/row/elements.
  127. content_menu_form_menu_overview_form_alter_additem($form);
  128. // Add css as via drupal_add_css and put it after ctools button css files.
  129. drupal_add_css(drupal_get_path('module', 'content_menu') . "/css/content_menu.css", array('weight' => 2));
  130. // Change submit handler function to our own implementation.
  131. $form['#submit'] = array('content_menu_menu_overview_form_submit_extended');
  132. // Prevent 'destination' from hijacking our submit.
  133. unset($_GET['destination']);
  134. if (!isset($form['actions'])) {
  135. $form['actions'] = array('#type' => 'actions');
  136. $form['actions']['submit'] = array(
  137. '#type' => 'submit',
  138. '#value' => t('Save'),
  139. );
  140. }
  141. $form['actions']['submit']['#value'] = t('Save');
  142. }
  143. /**
  144. * Menu item element alterations provided by default by this module.
  145. *
  146. * This helper function is called by this module's hook_menu_item_element_alter
  147. * implementation content_menu_menu_item_element_alter().
  148. *
  149. * @param $el Array The form element of the menu item to alter.
  150. */
  151. function _content_menu_menu_item_element_alter(&$el) {
  152. $el_item = &$el['#item'];
  153. $el_ops = &$el['operations'];
  154. $target_content = '';
  155. $link_path = ($el_item['link_path'] == '<front>') ? variable_get('site_frontpage', 'node') : $el_item['link_path'];
  156. $link_path = (array) explode('/', $link_path);
  157. $link_path = array_pad($link_path, 2, '');
  158. // Change "edit" operation.
  159. if (isset($el_ops['edit']) && ($el_ops['edit']['#type'] == 'link')) {
  160. $el_ops['edit']['weight'] = 1;
  161. // Add "select content" operation.
  162. $selectcontenturl = content_menu_variable_get_add_existing_content_url();
  163. if ($selectcontenturl) {
  164. $el_ops['selectcontent'] = array(
  165. '#type' => 'link',
  166. 'weight' => 2,
  167. '#title' => t('select content'),
  168. '#href' => $selectcontenturl,
  169. '#options' => array(
  170. 'query' => content_menu_assemble_query_string($el_item),
  171. ),
  172. );
  173. }
  174. // Add "new <node-type>" operation to Dummies.
  175. if ($link_path[0] == 'menu-dummy') {
  176. $node_type_count = 0;
  177. foreach (node_type_get_types() as $node_type) {
  178. $type = $node_type->type;
  179. if (user_access('create ' . $type . ' content')) {
  180. $node_menu_options = variable_get('menu_options_' . $type, array('main-menu' => 'main-menu'));
  181. if (in_array($el_item['menu_name'], $node_menu_options)) {
  182. $el_ops['new_' . $type] = array(
  183. '#type' => 'link',
  184. 'weight' => 10 + $node_type_count,
  185. '#title' => t('New @type', array('@type' => t($node_type->name))),
  186. '#href' => 'node/add/' . str_replace("_", "-", $type),
  187. '#options' => array(
  188. 'query' => content_menu_assemble_query_string($el_item),
  189. ),
  190. );
  191. }
  192. }
  193. }
  194. }
  195. // Add "configure" operation by cloning "edit" operation.
  196. $el_ops['configure'] = $el_ops['edit'];
  197. $el_ops['configure']['#title'] = t('configure item');
  198. $el_ops['configure']['weight'] = 3;
  199. // Change "edit" operation to ...
  200. // ... do nothing for menu item dummies.
  201. if ($link_path[0] == 'menu-dummy') {
  202. $target_content = t('Placeholder');
  203. }
  204. // ... lead to node edit form for node-url-items.
  205. elseif (($link_path[0] == 'node') && (is_numeric($link_path[1]))) {
  206. $node = node_load($link_path[1]);
  207. if (is_object($node)) {
  208. if (node_access('update', $node)) {
  209. $el_ops['edit']['#href'] = 'node/' . $link_path[1] . '/edit';
  210. }
  211. $node_type = node_type_get_type($node);
  212. $target_content = t($node_type->name);
  213. // Mark unpublished nodes.
  214. if (!$node->status) {
  215. $target_content = '<span class="menu-item-content-target-unpublished">' . $target_content . '</span>';
  216. }
  217. }
  218. }
  219. // ... lead to panel page edit form for panel paged.
  220. elseif (($el_item['page_callback'] == 'page_manager_page_execute')) {
  221. if (user_access('use page manager')) {
  222. $page_arguments = unserialize($el_item['page_arguments']);
  223. $el_ops['edit']['#href'] = 'admin/structure/pages/edit/page-' . implode('/', $page_arguments);
  224. }
  225. $target_content = t('Panel');
  226. }
  227. // ... lead to view edit form for views.
  228. elseif ($el_item['page_callback'] == 'views_page') {
  229. if (user_access('administer views')) {
  230. $page_arguments = unserialize($el_item['page_arguments']);
  231. $el_ops['edit']['#href'] = 'admin/structure/views/view/' . $page_arguments[0] . '/edit/' . $page_arguments[1];
  232. }
  233. $el_ops['selectcontent']['#href'] = CONTENT_MENU_ADD_EXISTING_VIEW_URL;
  234. $el_ops['selectcontent']['#title'] = t('select view');
  235. $target_content = t('View');
  236. }
  237. // ... menu position rule.
  238. elseif ($link_path[0] == 'menu-position') {
  239. if (!user_access('administer menu positions')) {
  240. $el_ops['configure'] = $el_ops['edit'] = array();
  241. }
  242. $target_content = t('Menu rule');
  243. $el['#inline_edit_title'] = FALSE;
  244. }
  245. else {
  246. // If no other content or target is identifier, assume generic URL.
  247. if (url_is_external($el_item['link_path'])) {
  248. // External.
  249. $target_content = t('URL');
  250. }
  251. else {
  252. // Internal.
  253. $target_content = t('Path');
  254. }
  255. }
  256. // Delete the "edit" operation altogether if its url didn't change.
  257. if (isset($el_ops['edit']['#href'])) {
  258. if ($el_ops['edit']['#href'] == $el_ops['configure']['#href']) {
  259. $el_ops['edit'] = array();
  260. $el_ops['selectcontent']['weight'] = 4;
  261. }
  262. else {
  263. $el_ops['edit']['#title'] = t('edit content');
  264. $el_ops['edit']['#options']['query']['destination'] = current_path();
  265. }
  266. }
  267. }
  268. else {
  269. $el_ops['edit'] = array();
  270. }
  271. // Add "delete" operation for menu_position items.
  272. if (!isset($el_ops['delete']) && ($link_path[0] == 'menu-position') && (is_numeric($link_path[1]) && user_access('administer menu positions'))) {
  273. $el_ops['delete'] = array(
  274. '#type' => 'link',
  275. '#title' => t('delete'),
  276. '#href' => 'admin/structure/menu-position/delete/' . intval($link_path[1]),
  277. '#options' => array('query' => array('destination' => current_path())),
  278. );
  279. }
  280. // Push "delete" operation to end of ops list.
  281. if (isset($el_ops['delete'])) {
  282. $el_ops['delete']['#title'] = t('delete item');
  283. $el_ops['delete']['weight'] = 100;
  284. }
  285. $el['target_content'] = array('#type' => 'markup', '#markup' => $target_content);
  286. }
  287. /**
  288. * Add item/row/elements to menu overview form for "add item" functionality.
  289. */
  290. function content_menu_form_menu_overview_form_alter_additem(&$form) {
  291. // Assemble and add the "Add link" item.
  292. $form['additem'] = array(
  293. '#attributes' => array(
  294. 'class' => array('menu-additem'),
  295. ),
  296. 'hidden' => array(
  297. '#type' => 'checkbox',
  298. '#title' => t('Enable the new menu link'),
  299. '#title_display' => 'invisible',
  300. '#default_value' => TRUE,
  301. ),
  302. 'weight' => array(
  303. '#type' => 'weight',
  304. // '#delta' has to be in sync with:
  305. // a) CONTENT_MENU_ADD_ITEM_WEIGHT.
  306. // b) Delta set in menu_form_node_form_alter().
  307. '#delta' => 50,
  308. // Real weight is set in content_menu_menu_overview_form_submit_extended.
  309. '#default_value' => CONTENT_MENU_ADD_ITEM_WEIGHT,
  310. '#title_display' => 'invisible',
  311. '#title' => 'Weight',
  312. ),
  313. 'mlid' => array(
  314. '#type' => 'hidden',
  315. '#value' => '0',
  316. ),
  317. 'plid' => array(
  318. '#type' => 'hidden',
  319. '#default_value' => '0',
  320. ),
  321. 'operations' => array(),
  322. '#operations_count' => 0,
  323. 'title' => array(
  324. '#type' => 'textfield',
  325. '#title' => t('New menu item'),
  326. '#default_value' => '',
  327. '#size' => 30,
  328. '#maxlength' => 255,
  329. '#required' => FALSE,
  330. ),
  331. );
  332. $target_types = content_menu_get_target_types($form['#menu']['menu_name']);
  333. // Retrieve possible add-"type"-operations for "Add link" item.
  334. foreach ($target_types as $op_key => $op_info) {
  335. $target_types[$op_key] = $op_info['label'];
  336. }
  337. // Build "type" select for "Add link" item.
  338. $form['additem']['target_content'] = array(
  339. '#type' => 'select',
  340. '#title' => '&nbsp;',
  341. '#options' => $target_types,
  342. '#default_value' => variable_get('content_menu_default_add_operation', 'url'),
  343. );
  344. }
  345. /**
  346. * Returns HTML for the menu overview form into a table.
  347. *
  348. * Code taken mainly from original theme_menu_overview_form().
  349. *
  350. * @param $variables
  351. * An associative array containing:
  352. * - form: A render element representing the form.
  353. *
  354. * @ingroup themeable
  355. */
  356. function theme_menu_overview_form_extended($variables) {
  357. $form = $variables['form'];
  358. drupal_add_tabledrag('menu-overview', 'match', 'parent', 'menu-plid', 'menu-plid', 'menu-mlid', TRUE, MENU_MAX_DEPTH - 1);
  359. drupal_add_tabledrag('menu-overview', 'order', 'sibling', 'menu-weight');
  360. // Count max number of operations per item.
  361. $operations_count_max = 1;
  362. foreach (element_children($form) as $mlid) {
  363. if (isset($form[$mlid]['#operations_count'])) {
  364. $operations_count_max = max($operations_count_max, $form[$mlid]['#operations_count']);
  365. }
  366. }
  367. $header = array(
  368. t('Menu link'),
  369. array('data' => t('Enabled'), 'class' => array('checkbox')),
  370. t('Weight'),
  371. t('Target'),
  372. array('data' => t('Operations'), 'colspan' => $operations_count_max),
  373. );
  374. // Build item tables.
  375. $rows = array();
  376. foreach (element_children($form) as $mlid) {
  377. if (isset($form[$mlid]['hidden'])) {
  378. $element = &$form[$mlid];
  379. // Build a list of operations.
  380. $operations = array();
  381. foreach (element_children($element['operations']) as $op) {
  382. $operations[] = array('data' => drupal_render($element['operations'][$op]), 'class' => array('menu-operations'));
  383. }
  384. while (count($operations) < $operations_count_max) {
  385. $operations[] = '';
  386. }
  387. // Add special classes to be used for tabledrag.js.
  388. $element['plid']['#attributes']['class'] = array('menu-plid');
  389. $element['mlid']['#attributes']['class'] = array('menu-mlid');
  390. $element['weight']['#attributes']['class'] = array('menu-weight');
  391. // Change the parent field to a hidden.
  392. // This allows any value but hides the field.
  393. $element['plid']['#type'] = 'hidden';
  394. $depth = isset($element['#item']) ? $element['#item']['depth'] : 1;
  395. $row = array();
  396. $row[] = theme('indentation', array('size' => $depth - 1)) . drupal_render($element['title']);
  397. $row[] = array('data' => drupal_render($element['hidden']), 'class' => array('checkbox', 'menu-enabled'));
  398. $row[] = drupal_render($element['weight']) . drupal_render($element['plid']) . drupal_render($element['mlid']);
  399. $row[] = array('data' => drupal_render($element['target_content']), 'class' => array('menu-target-content'));
  400. $row = array_merge($row, $operations);
  401. $row = array_merge(array('data' => $row), $element['#attributes']);
  402. $row['class'][] = 'draggable';
  403. // Highlight row if menu item has been created within the last minute.
  404. if (isset($element['#item']['mlid']) && isset($_SESSION['content_menu_inserted_links'][$element['#item']['mlid']])) {
  405. if ((time() - $_SESSION['content_menu_inserted_links'][$element['#item']['mlid']]['created']) <= 60) {
  406. $row['class'][] = 'ok';
  407. }
  408. unset($_SESSION['content_menu_inserted_links'][$element['#item']['mlid']]);
  409. }
  410. $rows[] = $row;
  411. }
  412. }
  413. $output = '';
  414. if (empty($rows)) {
  415. $rows[] = array(array('data' => $form['#empty_text'], 'colspan' => '7'));
  416. }
  417. // Render selection filter widgets on top.
  418. if (isset($form['#content_menu_filter_widget'])) {
  419. foreach ($form['#content_menu_filter_widget'] as $widgetname) {
  420. $output .= drupal_render($form[$widgetname]);
  421. }
  422. }
  423. $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'menu-overview')));
  424. $output .= drupal_render_children($form);
  425. return $output;
  426. }
  427. /**
  428. * Submit handler for menu_overview_form extended with item adding handling.
  429. */
  430. function content_menu_menu_overview_form_submit_extended($form, &$form_state) {
  431. // Edit item handling.
  432. $max_weight = 0;
  433. // Step though items.
  434. foreach (element_children($form) as $mlid) {
  435. $el = &$form[$mlid];
  436. // Keep track of maximum weight.
  437. if (isset($el['#item']['weight']) && ($el['#item']['weight'] > $max_weight)) {
  438. $max_weight = $el['#item']['weight'];
  439. }
  440. // If title changed, ...
  441. if (isset($el['#item']) && isset($el['title']['#value'])) {
  442. if ($el['title']['#value'] != $el['title']['#default_value']) {
  443. // Inject item title.
  444. $title = $form_state['input'][$mlid]['title'];
  445. $el['#item']['title'] = $el['#item']['link_title'] = $title;
  446. // Change default value of weight field to trigger
  447. // menu_overview_form_submit() marking the item as updated.
  448. $el['weight']['#default_value'] += 1;
  449. }
  450. }
  451. }
  452. // Do standard menu.module's item processing.
  453. menu_overview_form_submit($form, $form_state);
  454. // Add item handling.
  455. $item = $form_state['input']['additem'];
  456. // If title has been entered for new menu item, prepare add operation.
  457. if (trim($item['title'] != '')) {
  458. // Complete data for new menu item.
  459. $item['link_title'] = $item['title'];
  460. $item['name'] = $form['#menu']['menu_name'];
  461. $item['hidden'] = $item['hidden'] ? 0 : 1;
  462. $item['customized'] = 1;
  463. if ($item['weight'] == CONTENT_MENU_ADD_ITEM_WEIGHT) {
  464. $item['weight'] = $max_weight + 1;
  465. }
  466. // Determine operation details.
  467. $operations = content_menu_get_target_types($item['name']);
  468. $op = $operations[$item['target_content']];
  469. // Prepare arguments for handler callback function.
  470. $args = array('form' => $form, 'form_state' => $form_state, 'item' => $item);
  471. if (isset($op['arguments']) && is_array($op['arguments'])) {
  472. $args += $op['arguments'];
  473. }
  474. // Call handler callback function.
  475. if (function_exists($op['handler'])) {
  476. // Get rid of the 'Your configuration has been saved.' message.
  477. if ($op['clean_menu_save_message']) {
  478. foreach ($_SESSION['messages']['status'] as $msg_key => $msg_text) {
  479. if ($_SESSION['messages']['status'][$msg_key] == t('Your configuration has been saved.')) {
  480. unset($_SESSION['messages']['status'][$msg_key]);
  481. }
  482. }
  483. }
  484. $result = call_user_func_array($op['handler'], $args);
  485. }
  486. }
  487. }
  488. /**
  489. * Menu add item operation handler for a new dummy menu item.
  490. */
  491. function content_menu_menu_form_handler_dummy($form, $form_state, $item) {
  492. drupal_set_message(t('A new menu item has been created.'));
  493. $item['link_path'] = 'menu-dummy';
  494. content_menu_link_save($item);
  495. }
  496. /**
  497. * Menu add item operation handler for a new node menu item.
  498. */
  499. function content_menu_menu_form_handler_node($form, $form_state, $item, $type) {
  500. $types = node_type_get_types();
  501. drupal_set_message(t("You're about to create a new menu item with new %type content.", array('%type' => $types[$type]->name)));
  502. drupal_set_message(t('Complete the process by filling out and saving the form below.'));
  503. $type = str_replace("_", "-", $type);
  504. drupal_goto('node/add/' . $type, array('query' => content_menu_assemble_query_string($item)));
  505. }
  506. /**
  507. * Menu add item operation handler for a new generic menu item.
  508. */
  509. function content_menu_menu_form_handler_url($form, $form_state, $item) {
  510. drupal_set_message(t("You're about to create a new generic menu item linking to a URL path."));
  511. drupal_set_message(t('Complete the process by filling out and saving the form below.'));
  512. drupal_goto('admin/structure/menu/manage/' . $item['name'] . '/add', array('query' => content_menu_assemble_query_string($item)));
  513. }
  514. /**
  515. * Menu add item operation handler for a new generic menu item.
  516. */
  517. function content_menu_menu_form_handler_menu_position_rule($form, $form_state, $item) {
  518. drupal_set_message(t("You're about to create a new generic menu position rule."));
  519. drupal_set_message(t('Complete the process by filling out and saving the form below.'));
  520. drupal_goto('admin/structure/menu-position/add', array('query' => content_menu_assemble_query_string($item)));
  521. }
  522. /**
  523. * Menu add item operation handler for a new menu item to existing content.
  524. */
  525. function content_menu_menu_form_handler_menu_position_existing($form, $form_state, $item) {
  526. $url = content_menu_variable_get_add_existing_content_url();
  527. // If using default view, ensure to only goto view page if views is enabled.
  528. if (empty($url)) {
  529. content_menu_menu_form_handler_url($form, $form_state, $item);
  530. }
  531. else {
  532. drupal_set_message(t("You're about to create a new menu item for an existing content."));
  533. drupal_set_message(t('Complete the process by finding and selecting an existing content to add to the menu.'));
  534. drupal_goto($url, array('query' => content_menu_assemble_query_string($item)));
  535. }
  536. }
  537. /**
  538. * Menu add item operation handler for a new menu item to an existing view.
  539. */
  540. function content_menu_menu_form_handler_existing_view($form, $form_state, $item) {
  541. drupal_set_message(t("You're about to create a new menu item for an existing view."));
  542. drupal_set_message(t('Complete the process by finding and selecting the view to add to the menu.'));
  543. drupal_goto(CONTENT_MENU_ADD_EXISTING_VIEW_URL, array('query' => content_menu_assemble_query_string($item)));
  544. }
  545. /**
  546. * List all views with a page display.
  547. */
  548. function content_menu_add_exiting_view($form, $form_state) {
  549. if (!module_exists('views')) {
  550. return;
  551. }
  552. $form = array();
  553. $item = content_menu_get_menu_item_from_querystring();
  554. $form['#menu_item'] = $item;
  555. $all_views = views_get_all_views();
  556. foreach ($all_views as $view) {
  557. foreach ($view->display as $display) {
  558. if ($display->display_plugin == 'page') {
  559. if ((!property_exists($view, 'disabled') || (property_exists($view, 'disabled') && !$view->disabled))) {
  560. $view_path = $display->display_options['path'];
  561. $view_title = check_plain($view->name . ' - ' . $display->display_title . ' (' . $display->display_options['path'] . ')');
  562. if (drupal_valid_path($view_path)) {
  563. $options[$view_path] = $view_title;
  564. }
  565. }
  566. }
  567. }
  568. }
  569. if (!empty($options)) {
  570. asort($options);
  571. $form['existing_view'] = array(
  572. '#type' => 'radios',
  573. '#title' => t('Link to this view'),
  574. '#default_value' => isset($item['link_path']) ? $item['link_path'] : NULL,
  575. '#required' => TRUE,
  576. '#options' => $options,
  577. );
  578. $form['submit'] = array(
  579. '#type' => 'submit',
  580. '#value' => t('Save'),
  581. '#submit' => array('content_menu_add_exiting_view_submit'),
  582. );
  583. }
  584. else {
  585. $no_views_notice = t('There are no available views.');
  586. if (module_exists('views_ui') && user_access('administer views')) {
  587. $no_views_notice .= ' ' . t('You can create views in the <a href="@url">Views UI</a>', array('@url' => url('admin/structure/views')));
  588. }
  589. $form['view_info'] = array(
  590. '#title' => t('Use these views'),
  591. '#type' => 'item',
  592. '#markup' => $no_views_notice,
  593. );
  594. }
  595. return $form;
  596. }
  597. /**
  598. * Submit handler for the form above.
  599. */
  600. function content_menu_add_exiting_view_submit($form, $form_state) {
  601. $menu_item = $form['#menu_item'];
  602. $menu_item['link_path'] = $form_state['values']['existing_view'];
  603. content_menu_link_save($menu_item);
  604. }
  605. /**
  606. * Assembles a query string with menu item data.
  607. */
  608. function content_menu_assemble_query_string($item) {
  609. if (empty($item['name']) && isset($item['menu_name'])) {
  610. $item['name'] = $item['menu_name'];
  611. }
  612. $query = array(
  613. 'menu_mlid' => isset($item['mlid']) ? $item['mlid'] : NULL,
  614. 'menu_title' => $item['title'],
  615. 'menu_plid' => $item['plid'],
  616. 'menu_name' => $item['name'],
  617. 'menu_hidden' => $item['hidden'],
  618. 'menu_weight' => $item['weight'],
  619. 'menu_link_path' => isset($item['link_path']) ? $item['link_path'] : NULL ,
  620. 'destination' => isset($item['destination']) ? $item['destination'] : ('admin/structure/menu/manage/' . $item['name']),
  621. 'msg_buffer' => isset($item['msg_buffer']) ? $item['msg_buffer'] : NULL,
  622. );
  623. return $query;
  624. }
  625. /**
  626. * Retrieve all supported menu add item operations.
  627. */
  628. function content_menu_get_target_types($menu_name) {
  629. // Invoke hook to let modules provide target operations for new item.
  630. $target_types = array();
  631. $context = array('menu_name' => $menu_name);
  632. drupal_alter('menu_item_target_types', $target_types, $context);
  633. return $target_types;
  634. }
  635. /**
  636. * Actual implementation for content_menu_menu_item_target_types_alter().
  637. *
  638. * Extend the target types for a new menu item provided by default.
  639. * See content_menu.api.php for further documentation.
  640. */
  641. function _content_menu_menu_item_target_types_alter(&$target_types, &$context) {
  642. $target_types['url'] = array(
  643. 'label' => t('URL'),
  644. 'handler' => 'content_menu_menu_form_handler_url',
  645. 'clean_menu_save_message' => TRUE,
  646. );
  647. $target_types['dummy'] = array(
  648. 'label' => t('Placeholder'),
  649. 'handler' => 'content_menu_menu_form_handler_dummy',
  650. 'clean_menu_save_message' => FALSE,
  651. );
  652. foreach (node_type_get_types() as $node_type) {
  653. if (user_access('create ' . $node_type->type . ' content') || user_access('administer nodes')) {
  654. $node_menu_options = variable_get('menu_options_' . $node_type->type, array('main-menu' => 'main-menu'));
  655. if (in_array($context['menu_name'], $node_menu_options)) {
  656. $target_types['node_' . $node_type->type] = array(
  657. 'label' => t('New @type', array('@type' => t($node_type->name))),
  658. 'handler' => 'content_menu_menu_form_handler_node',
  659. 'arguments' => array('type' => $node_type->type),
  660. 'clean_menu_save_message' => TRUE,
  661. );
  662. }
  663. }
  664. }
  665. $target_types['existing'] = array(
  666. 'label' => t('Existing content'),
  667. 'handler' => 'content_menu_menu_form_handler_menu_position_existing',
  668. 'clean_menu_save_message' => TRUE,
  669. );
  670. if (module_exists('views')) {
  671. $target_types['existing_view'] = array(
  672. 'label' => t('Existing view'),
  673. 'handler' => 'content_menu_menu_form_handler_existing_view',
  674. 'clean_menu_save_message' => TRUE,
  675. );
  676. }
  677. if (module_exists('menu_position') && user_access('administer menu positions')) {
  678. $target_types['menu_position_rule'] = array(
  679. 'label' => t('Menu position rule'),
  680. 'handler' => 'content_menu_menu_form_handler_menu_position_rule',
  681. 'clean_menu_save_message' => TRUE,
  682. );
  683. }
  684. }