page.inc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. <?php
  2. /**
  3. * @file
  4. * Handle the 'page' task, which creates pages with arbitrary tasks and lets
  5. * handlers decide how they will be rendered.
  6. *
  7. * This creates subtasks and stores them in the page_manager_pages table. These
  8. * are exportable objects, too.
  9. *
  10. * The render callback for this task type has $handler, $page, $contexts as
  11. * parameters.
  12. */
  13. /**
  14. * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for
  15. * more information.
  16. */
  17. function page_manager_page_page_manager_tasks() {
  18. return array(
  19. 'title' => t('Custom pages'),
  20. 'description' => t('Administrator created pages that have a URL path, access control and entries in the Drupal menu system.'),
  21. 'non-exportable' => TRUE,
  22. 'subtasks' => TRUE,
  23. 'subtask callback' => 'page_manager_page_subtask',
  24. 'subtasks callback' => 'page_manager_page_subtasks',
  25. 'save subtask callback' => 'page_manager_page_save_subtask',
  26. 'access callback' => 'page_manager_page_access_check',
  27. 'hook menu' => array(
  28. 'file' => 'page.admin.inc',
  29. 'path' => drupal_get_path('module', 'page_manager') . '/plugins/tasks',
  30. 'function' => 'page_manager_page_menu',
  31. ),
  32. 'hook theme' => 'page_manager_page_theme',
  33. // Page only items.
  34. 'task type' => 'page',
  35. 'page operations' => array(
  36. array(
  37. 'title' => ' &raquo; ' . t('Create a new page'),
  38. 'href' => 'admin/structure/pages/add',
  39. 'html' => TRUE,
  40. ),
  41. ),
  42. 'columns' => array(
  43. 'storage' => array(
  44. 'label' => t('Storage'),
  45. 'class' => 'page-manager-page-storage',
  46. ),
  47. ),
  48. 'page type' => 'custom',
  49. // Context only items.
  50. 'handler type' => 'context',
  51. 'get arguments' => array(
  52. 'file' => 'page.admin.inc',
  53. 'path' => drupal_get_path('module', 'page_manager') . '/plugins/tasks',
  54. 'function' => 'page_manager_page_get_arguments',
  55. ),
  56. 'get context placeholders' => 'page_manager_page_get_contexts',
  57. 'access restrictions' => 'page_manager_page_access_restrictions',
  58. 'uses handlers' => TRUE,
  59. );
  60. }
  61. /**
  62. * Task callback to get all subtasks.
  63. *
  64. * Return a list of all subtasks.
  65. */
  66. function page_manager_page_subtasks($task) {
  67. $pages = page_manager_page_load_all($task['name']);
  68. $return = array();
  69. foreach ($pages as $name => $page) {
  70. $return[$name] = page_manager_page_build_subtask($task, $page);
  71. }
  72. return $return;
  73. }
  74. /**
  75. * Callback to return a single subtask.
  76. */
  77. function page_manager_page_subtask($task, $subtask_id) {
  78. $page = page_manager_page_load($subtask_id);
  79. if ($page) {
  80. return page_manager_page_build_subtask($task, $page);
  81. }
  82. }
  83. /**
  84. * Call back from the administrative system to save a page.
  85. *
  86. * We get the $subtask as created by page_manager_page_build_subtask.
  87. */
  88. function page_manager_page_save_subtask($subtask) {
  89. $page = &$subtask['subtask'];
  90. // Ensure $page->arguments contains only real arguments:
  91. $arguments = page_manager_page_get_named_arguments($page->path);
  92. $args = array();
  93. foreach ($arguments as $keyword => $position) {
  94. if (isset($page->arguments[$keyword])) {
  95. $args[$keyword] = $page->arguments[$keyword];
  96. }
  97. else {
  98. $args[$keyword] = array(
  99. 'id' => '',
  100. 'identifier' => '',
  101. 'argument' => '',
  102. 'settings' => array(),
  103. );
  104. }
  105. }
  106. page_manager_page_recalculate_arguments($page);
  107. // Create a real object from the cache.
  108. page_manager_page_save($page);
  109. // Check to see if we should make this the site frontpage.
  110. if (!empty($page->make_frontpage)) {
  111. $path = array();
  112. foreach (explode('/', $page->path) as $bit) {
  113. if ($bit[0] != '!') {
  114. $path[] = $bit;
  115. }
  116. }
  117. $path = implode('/', $path);
  118. $front = variable_get('site_frontpage', 'node');
  119. if ($path != $front) {
  120. variable_set('site_frontpage', $path);
  121. }
  122. }
  123. }
  124. /**
  125. * Build a subtask array for a given page.
  126. */
  127. function page_manager_page_build_subtask($task, $page) {
  128. $operations = array();
  129. $operations['settings'] = array(
  130. 'type' => 'group',
  131. 'class' => array('operations-settings'),
  132. 'title' => t('Settings'),
  133. 'children' => array(),
  134. );
  135. $settings = &$operations['settings']['children'];
  136. $settings['basic'] = array(
  137. 'title' => t('Basic'),
  138. 'description' => t('Edit name, path and other basic settings for the page.'),
  139. 'form' => 'page_manager_page_form_basic',
  140. );
  141. $arguments = page_manager_page_get_named_arguments($page->path);
  142. if ($arguments) {
  143. $settings['argument'] = array(
  144. 'title' => t('Arguments'),
  145. 'description' => t('Set up contexts for the arguments on this page.'),
  146. 'form' => 'page_manager_page_form_argument',
  147. );
  148. }
  149. $settings['access'] = array(
  150. 'title' => t('Access'),
  151. 'description' => t('Control what users can access this page.'),
  152. 'admin description' => t('Access rules are used to test if the page is accessible and any menu items associated with it are visible.'),
  153. 'form' => 'page_manager_page_form_access',
  154. );
  155. $settings['menu'] = array(
  156. 'title' => t('Menu'),
  157. 'description' => t('Provide this page a visible menu or a menu tab.'),
  158. 'form' => 'page_manager_page_form_menu',
  159. );
  160. $operations['actions']['children']['clone'] = array(
  161. 'title' => t('Clone'),
  162. 'description' => t('Make a copy of this page'),
  163. 'form' => 'page_manager_page_form_clone',
  164. );
  165. $operations['actions']['children']['export'] = array(
  166. 'title' => t('Export'),
  167. 'description' => t('Export this page as code that can be imported or embedded into a module.'),
  168. 'form' => 'page_manager_page_form_export',
  169. );
  170. if ($page->export_type == (EXPORT_IN_CODE | EXPORT_IN_DATABASE)) {
  171. $operations['actions']['children']['delete'] = array(
  172. 'title' => t('Revert'),
  173. 'description' => t('Remove all changes to this page and revert to the version in code.'),
  174. 'form' => 'page_manager_page_form_delete',
  175. );
  176. }
  177. elseif ($page->export_type != EXPORT_IN_CODE) {
  178. $operations['actions']['children']['delete'] = array(
  179. 'title' => t('Delete'),
  180. 'description' => t('Remove this page from your system completely.'),
  181. 'form' => 'page_manager_page_form_delete',
  182. );
  183. }
  184. $subtask = array(
  185. 'name' => $page->name,
  186. 'admin title' => check_plain($page->admin_title),
  187. 'admin description' => filter_xss_admin($page->admin_description),
  188. 'admin summary' => 'page_manager_page_admin_summary',
  189. 'admin path' => $page->path,
  190. 'admin type' => t('Custom'),
  191. 'subtask' => $page,
  192. 'operations' => $operations,
  193. 'operations include' => array(
  194. 'file' => 'page.admin.inc',
  195. 'path' => drupal_get_path('module', 'page_manager') . '/plugins/tasks',
  196. ),
  197. 'single task' => empty($page->multiple),
  198. 'row class' => empty($page->disabled) ? 'page-manager-enabled' : 'page-manager-disabled',
  199. 'storage' => $page->type == t('Default') ? t('In code') : $page->type,
  200. 'disabled' => !empty($page->disabled),
  201. // This works for both enable AND disable.
  202. 'enable callback' => 'page_manager_page_enable',
  203. );
  204. // Default handlers may appear from a default subtask.
  205. if (isset($page->default_handlers)) {
  206. $subtask['default handlers'] = $page->default_handlers;
  207. }
  208. return $subtask;
  209. }
  210. /**
  211. * Delegated implementation of hook_theme().
  212. */
  213. function page_manager_page_theme(&$items, $task) {
  214. $base = array(
  215. 'file' => 'page.admin.inc',
  216. 'path' => drupal_get_path('module', 'page_manager') . '/plugins/tasks',
  217. );
  218. $items['page_manager_page_form_argument_table'] = $base + array(
  219. 'render element' => 'form',
  220. );
  221. $items['page_manager_page_lock'] = $base + array(
  222. 'variables' => array('lock' => array(), 'task_name' => NULL),
  223. );
  224. $items['page_manager_page_changed'] = $base + array(
  225. 'variables' => array(),
  226. );
  227. }
  228. // --------------------------------------------------------------------------
  229. // Page execution functions.
  230. /**
  231. * Execute a page task.
  232. *
  233. * This is the callback to entries in the Drupal menu system created by the
  234. * page task.
  235. *
  236. * @param $subtask_id
  237. * The name of the page task used.
  238. * @param ...
  239. * A number of context objects as specified by the user when
  240. * creating named arguments in the path.
  241. */
  242. function page_manager_page_execute($subtask_id) {
  243. $func_args = func_get_args();
  244. $page = page_manager_page_load($subtask_id);
  245. $task = page_manager_get_task($page->task);
  246. $subtask = page_manager_get_task_subtask($task, $subtask_id);
  247. // Turn the contexts into a properly keyed array.
  248. $contexts = array();
  249. $args = array();
  250. foreach ($func_args as $count => $arg) {
  251. if (is_object($arg) && get_class($arg) == 'ctools_context') {
  252. $contexts[$arg->id] = $arg;
  253. $args[] = $arg->original_argument;
  254. }
  255. elseif ($count) {
  256. $args[] = $arg;
  257. }
  258. }
  259. $count = 0;
  260. $names = page_manager_page_get_named_arguments($page->path);
  261. $bits = explode('/', $page->path);
  262. if ($page->arguments) {
  263. foreach ($page->arguments as $name => $argument) {
  264. // Optional arguments must be converted to contexts too, if they exist.
  265. if ($bits[$names[$name]][0] == '!') {
  266. ctools_include('context');
  267. $argument['keyword'] = $name;
  268. if (isset($args[$count])) {
  269. // Hack: use a special argument config variable to learn if we need
  270. // to use menu_tail style behavior:
  271. if (empty($argument['settings']['use_tail'])) {
  272. $value = $args[$count];
  273. }
  274. else {
  275. $value = implode('/', array_slice($args, $count));
  276. }
  277. $context = ctools_context_get_context_from_argument($argument, $value);
  278. }
  279. else {
  280. // Make sure there is a placeholder context for missing optional contexts.
  281. $context = ctools_context_get_context_from_argument($argument, NULL, TRUE);
  282. // Force the title to blank for replacements.
  283. }
  284. if ($context) {
  285. $contexts[$context->id] = $context;
  286. }
  287. }
  288. $count++;
  289. }
  290. }
  291. if ($function = ctools_plugin_get_function($task, 'page callback')) {
  292. return call_user_func_array($function, array($page, $contexts, $args));
  293. }
  294. ctools_include('context-task-handler');
  295. $output = ctools_context_handler_render($task, $subtask, $contexts, $args);
  296. if ($output === FALSE) {
  297. return MENU_NOT_FOUND;
  298. }
  299. return $output;
  300. }
  301. // --------------------------------------------------------------------------
  302. // Context type callbacks.
  303. /**
  304. * Return a list of arguments used by this task.
  305. */
  306. function page_manager_page_get_arguments($task, $subtask) {
  307. return _page_manager_page_get_arguments($subtask['subtask']);
  308. }
  309. function _page_manager_page_get_arguments($page) {
  310. $arguments = array();
  311. if (!empty($page->arguments)) {
  312. foreach ($page->arguments as $keyword => $argument) {
  313. if (isset($argument['name'])) {
  314. $argument['keyword'] = $keyword;
  315. $arguments[$keyword] = $argument;
  316. }
  317. }
  318. }
  319. return $arguments;
  320. }
  321. /**
  322. * Get a group of context placeholders for the arguments.
  323. */
  324. function page_manager_page_get_contexts($task, $subtask) {
  325. ctools_include('context');
  326. return ctools_context_get_placeholders_from_argument(page_manager_page_get_arguments($task, $subtask));
  327. }
  328. /**
  329. * Return a list of arguments used by this task.
  330. */
  331. function page_manager_page_access_restrictions($task, $subtask, $contexts) {
  332. $page = $subtask['subtask'];
  333. return ctools_access_add_restrictions($page->access, $contexts);
  334. }
  335. // --------------------------------------------------------------------------
  336. // Page task database info.
  337. /**
  338. * Create a new page with defaults appropriately set from schema.
  339. */
  340. function page_manager_page_new() {
  341. ctools_include('export');
  342. return ctools_export_new_object('page_manager_pages');
  343. }
  344. /**
  345. * Load a single page subtask.
  346. */
  347. function page_manager_page_load($name) {
  348. ctools_include('export');
  349. $result = ctools_export_load_object('page_manager_pages', 'names', array($name));
  350. if (isset($result[$name])) {
  351. return $result[$name];
  352. }
  353. }
  354. /**
  355. * Load all page subtasks.
  356. */
  357. function page_manager_page_load_all($task = NULL) {
  358. ctools_include('export');
  359. if (empty($task)) {
  360. return ctools_export_load_object('page_manager_pages');
  361. }
  362. else {
  363. return ctools_export_load_object('page_manager_pages', 'conditions', array('task' => $task));
  364. }
  365. }
  366. /**
  367. * Write a page subtask to the database.
  368. */
  369. function page_manager_page_save(&$page) {
  370. $update = (isset($page->pid)) ? array('pid') : array();
  371. $task = page_manager_get_task($page->task);
  372. if ($function = ctools_plugin_get_function($task, 'save')) {
  373. $function($page, $update);
  374. }
  375. drupal_write_record('page_manager_pages', $page, $update);
  376. // If this was a default page we may need to write default task
  377. // handlers that we provided as well.
  378. if (!$update && isset($page->default_handlers)) {
  379. $handlers = page_manager_load_task_handlers(page_manager_get_task('page'), $page->name);
  380. foreach ($page->default_handlers as $name => $handler) {
  381. if (!isset($handlers[$name]) || !($handlers[$name]->export_type & EXPORT_IN_DATABASE)) {
  382. // Make sure this is right, as exports can wander a bit.
  383. $handler->subtask = $page->name;
  384. page_manager_save_task_handler($handler);
  385. }
  386. }
  387. }
  388. return $page;
  389. }
  390. /**
  391. * Remove a page subtask.
  392. */
  393. function page_manager_page_delete($page, $skip_menu_rebuild = FALSE) {
  394. $task = page_manager_get_task($page->task);
  395. if ($function = ctools_plugin_get_function($task, 'delete')) {
  396. $function($page);
  397. }
  398. if (!empty($task['uses handlers'])) {
  399. $handlers = page_manager_load_task_handlers($task, $page->name);
  400. foreach ($handlers as $handler) {
  401. page_manager_delete_task_handler($handler);
  402. }
  403. }
  404. db_delete('page_manager_pages')
  405. ->condition('name', $page->name)
  406. ->execute();
  407. // Make sure that the cache is reset so that the menu rebuild does not
  408. // rebuild this page again.
  409. ctools_include('export');
  410. ctools_export_load_object_reset('page_manager_pages');
  411. // Allow menu rebuild to be skipped when calling code is deleting multiple
  412. // pages.
  413. if (!$skip_menu_rebuild) {
  414. menu_rebuild();
  415. }
  416. }
  417. /**
  418. * Export a page subtask.
  419. */
  420. function page_manager_page_export($page, $with_handlers = FALSE, $indent = '') {
  421. $task = page_manager_get_task($page->task);
  422. $append = '';
  423. if ($function = ctools_plugin_get_function($task, 'export')) {
  424. $append = $function($page, $indent);
  425. }
  426. ctools_include('export');
  427. $output = ctools_export_object('page_manager_pages', $page, $indent);
  428. $output .= $append;
  429. if ($with_handlers) {
  430. if (is_array($with_handlers)) {
  431. $handlers = $with_handlers;
  432. }
  433. else {
  434. $handlers = page_manager_load_task_handlers(page_manager_get_task('page'), $page->name);
  435. }
  436. $output .= $indent . '$page->default_handlers = array();' . "\n";
  437. foreach ($handlers as $handler) {
  438. $output .= page_manager_export_task_handler($handler, $indent);
  439. $output .= $indent . '$page->default_handlers[$handler->name] = $handler;' . "\n";
  440. }
  441. }
  442. return $output;
  443. }
  444. /**
  445. * Get a list of named arguments in a page manager path.
  446. *
  447. * @param $path
  448. * A normal Drupal path.
  449. *
  450. * @return
  451. * An array of % marked variable arguments, keyed by the argument's name.
  452. * The value will be the position of the argument so that it can easily
  453. * be found. Items with a position of -1 have multiple positions.
  454. */
  455. function page_manager_page_get_named_arguments($path) {
  456. $arguments = array();
  457. $bits = explode('/', $path);
  458. foreach ($bits as $position => $bit) {
  459. if ($bit && ($bit[0] == '%' || $bit[0] == '!')) {
  460. // Special handling for duplicate path items and substr to remove the %.
  461. $arguments[substr($bit, 1)] = isset($arguments[$bit]) ? -1 : $position;
  462. }
  463. }
  464. return $arguments;
  465. }
  466. /**
  467. * Load a context from an argument for a given page task.
  468. *
  469. * Helper function for pm_arg_load(), which is in page_manager.module because
  470. * drupal's menu system does not allow loader functions to reside in separate
  471. * files.
  472. *
  473. * @param $value
  474. * The incoming argument value.
  475. * @param $subtask
  476. * The subtask id.
  477. * @param $argument
  478. * The numeric position of the argument in the path, counting from 0.
  479. *
  480. * @return
  481. * A context item if one is configured, the argument if one is not, or
  482. * FALSE if restricted or invalid.
  483. */
  484. function _pm_arg_load($value, $subtask, $argument) {
  485. $page = page_manager_page_load($subtask);
  486. if (!$page) {
  487. return FALSE;
  488. }
  489. $path = explode('/', $page->path);
  490. if (empty($path[$argument])) {
  491. return FALSE;
  492. }
  493. $keyword = substr($path[$argument], 1);
  494. if (empty($page->arguments[$keyword])) {
  495. return $value;
  496. }
  497. $page->arguments[$keyword]['keyword'] = $keyword;
  498. ctools_include('context');
  499. $context = ctools_context_get_context_from_argument($page->arguments[$keyword], $value);
  500. // Convert false equivalents to false.
  501. return $context ? $context : FALSE;
  502. }
  503. /**
  504. * Provide a nice administrative summary of the page so an admin can see at a
  505. * glance what this page does and how it is configured.
  506. */
  507. function page_manager_page_admin_summary($task, $subtask) {
  508. $task_name = page_manager_make_task_name($task['name'], $subtask['name']);
  509. $page = $subtask['subtask'];
  510. $output = '';
  511. $rows = array();
  512. $rows[] = array(
  513. array('class' => array('page-summary-label'), 'data' => t('Storage')),
  514. array('class' => array('page-summary-data'), 'data' => $subtask['storage']),
  515. array('class' => array('page-summary-operation'), 'data' => ''),
  516. );
  517. if (!empty($page->disabled)) {
  518. $link = l(t('Enable'), page_manager_edit_url($task_name, array('handlers', $page->name, 'actions', 'enable')));
  519. $text = t('Disabled');
  520. }
  521. else {
  522. $link = l(t('Disable'), page_manager_edit_url($task_name, array('handlers', $page->name, 'actions', 'disable')));
  523. $text = t('Enabled');
  524. }
  525. $rows[] = array(
  526. array('class' => array('page-summary-label'), 'data' => t('Status')),
  527. array('class' => array('page-summary-data'), 'data' => $text),
  528. array('class' => array('page-summary-operation'), 'data' => $link),
  529. );
  530. $path = array();
  531. foreach (explode('/', $page->path) as $bit) {
  532. if ($bit[0] != '!') {
  533. $path[] = $bit;
  534. }
  535. }
  536. $path = implode('/', $path);
  537. $front = variable_get('site_frontpage', 'node');
  538. $link = l(t('Edit'), page_manager_edit_url($task_name, array('settings', 'basic')));
  539. $message = '';
  540. if ($path == $front) {
  541. $message = t('This is your site home page.');
  542. }
  543. elseif (!empty($page->make_frontpage)) {
  544. $message = t('This page is set to become your site home page.');
  545. }
  546. if ($message) {
  547. $rows[] = array(
  548. array('class' => array('page-summary-data'), 'data' => $message, 'colspan' => 2),
  549. array('class' => array('page-summary-operation'), 'data' => $link),
  550. );
  551. }
  552. if (strpos($path, '%') === FALSE) {
  553. $path = l('/' . $page->path, $path);
  554. }
  555. else {
  556. $path = '/' . $page->path;
  557. }
  558. $rows[] = array(
  559. array('class' => array('page-summary-label'), 'data' => t('Path')),
  560. array('class' => array('page-summary-data'), 'data' => $path),
  561. array('class' => array('page-summary-operation'), 'data' => $link),
  562. );
  563. if (empty($access['plugins'])) {
  564. $access['plugins'] = array();
  565. }
  566. $contexts = page_manager_page_get_contexts($task, $subtask);
  567. $access = ctools_access_group_summary($page->access, $contexts);
  568. if ($access) {
  569. $access = t('Accessible only if @conditions.', array('@conditions' => $access));
  570. }
  571. else {
  572. $access = t('This page is publicly accessible.');
  573. }
  574. $link = l(t('Edit'), page_manager_edit_url($task_name, array('settings', 'access')));
  575. $rows[] = array(
  576. array('class' => array('page-summary-label'), 'data' => t('Access')),
  577. array('class' => array('page-summary-data'), 'data' => $access),
  578. array('class' => array('page-summary-operation'), 'data' => $link),
  579. );
  580. $menu_options = array(
  581. 'none' => t('No menu entry.'),
  582. 'normal' => t('Normal menu entry.'),
  583. 'tab' => t('Menu tab.'),
  584. 'default tab' => t('Default menu tab.'),
  585. 'action' => t('Local action'),
  586. );
  587. if (!empty($page->menu)) {
  588. $menu = $menu_options[$page->menu['type']];
  589. if ($page->menu['type'] != 'none') {
  590. $menu .= ' ' . t('Title: %title.', array('%title' => $page->menu['title']));
  591. switch ($page->menu['type']) {
  592. case 'default tab':
  593. $menu .= ' ' . t('Parent title: %title.', array('%title' => $page->menu['parent']['title']));
  594. break;
  595. case 'normal':
  596. if (module_exists('menu')) {
  597. $menus = menu_get_menus();
  598. $menu .= ' ' . t('Menu block: %title.', array('%title' => $menus[$page->menu['name']]));
  599. }
  600. break;
  601. }
  602. }
  603. }
  604. else {
  605. $menu = t('No menu entry');
  606. }
  607. $link = l(t('Edit'), page_manager_edit_url($task_name, array('settings', 'menu')));
  608. $rows[] = array(
  609. array('class' => array('page-summary-label'), 'data' => t('Menu')),
  610. array('class' => array('page-summary-data'), 'data' => $menu),
  611. array('class' => array('page-summary-operation'), 'data' => $link),
  612. );
  613. $output .= theme('table', array('rows' => $rows, 'attributes' => array('id' => 'page-manager-page-summary')));
  614. return $output;
  615. }
  616. /**
  617. * Callback to enable/disable the page from the UI.
  618. */
  619. function page_manager_page_enable(&$cache, $status) {
  620. $page = &$cache->subtask['subtask'];
  621. ctools_include('export');
  622. ctools_export_set_object_status($page, $status);
  623. $page->disabled = FALSE;
  624. }
  625. /**
  626. * Recalculate the arguments when something like the path changes.
  627. */
  628. function page_manager_page_recalculate_arguments(&$page) {
  629. // Ensure $page->arguments contains only real arguments:
  630. $arguments = page_manager_page_get_named_arguments($page->path);
  631. $args = array();
  632. foreach ($arguments as $keyword => $position) {
  633. if (isset($page->arguments[$keyword])) {
  634. $args[$keyword] = $page->arguments[$keyword];
  635. }
  636. else {
  637. $args[$keyword] = array(
  638. 'id' => '',
  639. 'identifier' => '',
  640. 'argument' => '',
  641. 'settings' => array(),
  642. );
  643. }
  644. }
  645. $page->arguments = $args;
  646. }
  647. /**
  648. * When adding or cloning a new page, this creates a new page cache
  649. * and adds our page to it.
  650. *
  651. * This does not check to see if the existing cache is already locked.
  652. * This must be done beforehand.
  653. *
  654. * @param &$page
  655. * The page to create.
  656. * @param &$cache
  657. * The cache to use. If the cache has any existing task handlers,
  658. * they will be marked for deletion. This may be a blank object.
  659. */
  660. function page_manager_page_new_page_cache(&$page, &$cache) {
  661. // Does a page already exist? If so, we are overwriting it so
  662. // take its pid.
  663. if (!empty($cache->subtask) && !empty($cache->subtask['subtask']) && !empty($cache->subtask['subtask']->pid)) {
  664. $page->pid = $cache->subtask['subtask']->pid;
  665. }
  666. else {
  667. $cache->new = TRUE;
  668. }
  669. $cache->task_name = page_manager_make_task_name('page', $page->name);
  670. $cache->task_id = 'page';
  671. $cache->task = page_manager_get_task('page');
  672. $cache->subtask_id = $page->name;
  673. $page->export_type = EXPORT_IN_DATABASE;
  674. $page->type = t('Normal');
  675. $cache->subtask = page_manager_page_build_subtask($cache->task, $page);
  676. if (isset($cache->handlers)) {
  677. foreach ($cache->handlers as $id => $handler) {
  678. $cache->handler_info[$id]['changed'] = PAGE_MANAGER_CHANGED_DELETED;
  679. }
  680. }
  681. else {
  682. $cache->handlers = array();
  683. $cache->handler_info = array();
  684. }
  685. if (!empty($page->default_handlers)) {
  686. foreach ($page->default_handlers as $id => $handler) {
  687. page_manager_handler_add_to_page($cache, $handler);
  688. }
  689. }
  690. $cache->locked = FALSE;
  691. $cache->changed = TRUE;
  692. }
  693. /**
  694. * Callback to determine if a page is accessible.
  695. *
  696. * @param $task
  697. * The task plugin.
  698. * @param $subtask_id
  699. * The subtask id
  700. * @param $contexts
  701. * The contexts loaded for the task.
  702. *
  703. * @return
  704. * TRUE if the current user can access the page.
  705. */
  706. function page_manager_page_access_check($task, $subtask_id, $contexts) {
  707. $page = page_manager_page_load($subtask_id);
  708. return ctools_access($page->access, $contexts);
  709. }