page.inc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  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. else if ($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. $page = page_manager_page_load($subtask_id);
  244. $task = page_manager_get_task($page->task);
  245. $subtask = page_manager_get_task_subtask($task, $subtask_id);
  246. // Turn the contexts into a properly keyed array.
  247. $contexts = array();
  248. $args = array();
  249. foreach (func_get_args() as $count => $arg) {
  250. if (is_object($arg) && get_class($arg) == 'ctools_context') {
  251. $contexts[$arg->id] = $arg;
  252. $args[] = $arg->original_argument;
  253. }
  254. else if ($count) {
  255. $args[] = $arg;
  256. }
  257. }
  258. $count = 0;
  259. $names = page_manager_page_get_named_arguments($page->path);
  260. $bits = explode('/', $page->path);
  261. if ($page->arguments) {
  262. foreach ($page->arguments as $name => $argument) {
  263. // Optional arguments must be converted to contexts too, if they exist.
  264. if ($bits[$names[$name]][0] == '!') {
  265. ctools_include('context');
  266. $argument['keyword'] = $name;
  267. if (isset($args[$count])) {
  268. // Hack: use a special argument config variable to learn if we need
  269. // to use menu_tail style behavior:
  270. if (empty($argument['settings']['use_tail'])) {
  271. $value = $args[$count];
  272. }
  273. else {
  274. $value = implode('/', array_slice($args, $count));
  275. }
  276. $context = ctools_context_get_context_from_argument($argument, $value);
  277. }
  278. else {
  279. // make sure there is a placeholder context for missing optional contexts.
  280. $context = ctools_context_get_context_from_argument($argument, NULL, TRUE);
  281. // Force the title to blank for replacements
  282. }
  283. if ($context) {
  284. $contexts[$context->id] = $context;
  285. }
  286. }
  287. $count++;
  288. }
  289. }
  290. if ($function = ctools_plugin_get_function($task, 'page callback')) {
  291. return call_user_func_array($function, array($page, $contexts, $args));
  292. }
  293. ctools_include('context-task-handler');
  294. $output = ctools_context_handler_render($task, $subtask, $contexts, $args);
  295. if ($output === FALSE) {
  296. return MENU_NOT_FOUND;
  297. }
  298. return $output;
  299. }
  300. // --------------------------------------------------------------------------
  301. // Context type callbacks
  302. /**
  303. * Return a list of arguments used by this task.
  304. */
  305. function page_manager_page_get_arguments($task, $subtask) {
  306. return _page_manager_page_get_arguments($subtask['subtask']);
  307. }
  308. function _page_manager_page_get_arguments($page) {
  309. $arguments = array();
  310. if (!empty($page->arguments)) {
  311. foreach ($page->arguments as $keyword => $argument) {
  312. if (isset($argument['name'])) {
  313. $argument['keyword'] = $keyword;
  314. $arguments[$keyword] = $argument;
  315. }
  316. }
  317. }
  318. return $arguments;
  319. }
  320. /**
  321. * Get a group of context placeholders for the arguments.
  322. */
  323. function page_manager_page_get_contexts($task, $subtask) {
  324. ctools_include('context');
  325. return ctools_context_get_placeholders_from_argument(page_manager_page_get_arguments($task, $subtask));
  326. }
  327. /**
  328. * Return a list of arguments used by this task.
  329. */
  330. function page_manager_page_access_restrictions($task, $subtask, $contexts) {
  331. $page = $subtask['subtask'];
  332. return ctools_access_add_restrictions($page->access, $contexts);
  333. }
  334. // --------------------------------------------------------------------------
  335. // Page task database info.
  336. /**
  337. * Create a new page with defaults appropriately set from schema.
  338. */
  339. function page_manager_page_new() {
  340. ctools_include('export');
  341. return ctools_export_new_object('page_manager_pages');
  342. }
  343. /**
  344. * Load a single page subtask.
  345. */
  346. function page_manager_page_load($name) {
  347. ctools_include('export');
  348. $result = ctools_export_load_object('page_manager_pages', 'names', array($name));
  349. if (isset($result[$name])) {
  350. return $result[$name];
  351. }
  352. }
  353. /**
  354. * Load all page subtasks.
  355. */
  356. function page_manager_page_load_all($task = NULL) {
  357. ctools_include('export');
  358. if (empty($task)) {
  359. return ctools_export_load_object('page_manager_pages');
  360. }
  361. else {
  362. return ctools_export_load_object('page_manager_pages', 'conditions', array('task' => $task));
  363. }
  364. }
  365. /**
  366. * Write a page subtask to the database.
  367. */
  368. function page_manager_page_save(&$page) {
  369. $update = (isset($page->pid)) ? array('pid') : array();
  370. $task = page_manager_get_task($page->task);
  371. if ($function = ctools_plugin_get_function($task, 'save')) {
  372. $function($page, $update);
  373. }
  374. drupal_write_record('page_manager_pages', $page, $update);
  375. // If this was a default page we may need to write default task
  376. // handlers that we provided as well.
  377. if (!$update && isset($page->default_handlers)) {
  378. $handlers = page_manager_load_task_handlers(page_manager_get_task('page'), $page->name);
  379. foreach ($page->default_handlers as $name => $handler) {
  380. if (!isset($handlers[$name]) || !($handlers[$name]->export_type & EXPORT_IN_DATABASE)) {
  381. // Make sure this is right, as exports can wander a bit.
  382. $handler->subtask = $page->name;
  383. page_manager_save_task_handler($handler);
  384. }
  385. }
  386. }
  387. return $page;
  388. }
  389. /**
  390. * Remove a page subtask.
  391. */
  392. function page_manager_page_delete($page) {
  393. $task = page_manager_get_task($page->task);
  394. if ($function = ctools_plugin_get_function($task, 'delete')) {
  395. $function($page);
  396. }
  397. if (!empty($task['uses handlers'])) {
  398. $handlers = page_manager_load_task_handlers($task, $page->name);
  399. foreach ($handlers as $handler) {
  400. page_manager_delete_task_handler($handler);
  401. }
  402. }
  403. db_delete('page_manager_pages')
  404. ->condition('name', $page->name)
  405. ->execute();
  406. // Make sure that the cache is reset so that the menu rebuild does not
  407. // rebuild this page again.
  408. ctools_include('export');
  409. ctools_export_load_object_reset('page_manager_pages');
  410. menu_rebuild();
  411. }
  412. /**
  413. * Export a page subtask.
  414. */
  415. function page_manager_page_export($page, $with_handlers = FALSE, $indent = '') {
  416. $task = page_manager_get_task($page->task);
  417. $append = '';
  418. if ($function = ctools_plugin_get_function($task, 'export')) {
  419. $append = $function($page, $indent);
  420. }
  421. ctools_include('export');
  422. $output = ctools_export_object('page_manager_pages', $page, $indent);
  423. $output .= $append;
  424. if ($with_handlers) {
  425. if (is_array($with_handlers)) {
  426. $handlers = $with_handlers;
  427. }
  428. else {
  429. $handlers = page_manager_load_task_handlers(page_manager_get_task('page'), $page->name);
  430. }
  431. $output .= $indent . '$page->default_handlers = array();' . "\n";
  432. foreach ($handlers as $handler) {
  433. $output .= page_manager_export_task_handler($handler, $indent);
  434. $output .= $indent . '$page->default_handlers[$handler->name] = $handler;' . "\n";
  435. }
  436. }
  437. return $output;
  438. }
  439. /**
  440. * Get a list of named arguments in a page manager path.
  441. *
  442. * @param $path
  443. * A normal Drupal path.
  444. *
  445. * @return
  446. * An array of % marked variable arguments, keyed by the argument's name.
  447. * The value will be the position of the argument so that it can easily
  448. * be found. Items with a position of -1 have multiple positions.
  449. */
  450. function page_manager_page_get_named_arguments($path) {
  451. $arguments = array();
  452. $bits = explode('/', $path);
  453. foreach ($bits as $position => $bit) {
  454. if ($bit && ($bit[0] == '%' || $bit[0] == '!')) {
  455. // special handling for duplicate path items and substr to remove the %
  456. $arguments[substr($bit, 1)] = isset($arguments[$bit]) ? -1 : $position;
  457. }
  458. }
  459. return $arguments;
  460. }
  461. /**
  462. * Load a context from an argument for a given page task.
  463. *
  464. * Helper function for pm_arg_load(), which is in page_manager.module because
  465. * drupal's menu system does not allow loader functions to reside in separate
  466. * files.
  467. *
  468. * @param $value
  469. * The incoming argument value.
  470. * @param $subtask
  471. * The subtask id.
  472. * @param $argument
  473. * The numeric position of the argument in the path, counting from 0.
  474. *
  475. * @return
  476. * A context item if one is configured, the argument if one is not, or
  477. * FALSE if restricted or invalid.
  478. */
  479. function _pm_arg_load($value, $subtask, $argument) {
  480. $page = page_manager_page_load($subtask);
  481. if (!$page) {
  482. return FALSE;
  483. }
  484. $path = explode('/', $page->path);
  485. if (empty($path[$argument])) {
  486. return FALSE;
  487. }
  488. $keyword = substr($path[$argument], 1);
  489. if (empty($page->arguments[$keyword])) {
  490. return $value;
  491. }
  492. $page->arguments[$keyword]['keyword'] = $keyword;
  493. ctools_include('context');
  494. $context = ctools_context_get_context_from_argument($page->arguments[$keyword], $value);
  495. // convert false equivalents to false.
  496. return $context ? $context : FALSE;
  497. }
  498. /**
  499. * Provide a nice administrative summary of the page so an admin can see at a
  500. * glance what this page does and how it is configured.
  501. */
  502. function page_manager_page_admin_summary($task, $subtask) {
  503. $task_name = page_manager_make_task_name($task['name'], $subtask['name']);
  504. $page = $subtask['subtask'];
  505. $output = '';
  506. $rows = array();
  507. $rows[] = array(
  508. array('class' => array('page-summary-label'), 'data' => t('Storage')),
  509. array('class' => array('page-summary-data'), 'data' => $subtask['storage']),
  510. array('class' => array('page-summary-operation'), 'data' => ''),
  511. );
  512. if (!empty($page->disabled)) {
  513. $link = l(t('Enable'), page_manager_edit_url($task_name, array('handlers', $page->name, 'actions', 'enable')));
  514. $text = t('Disabled');
  515. }
  516. else {
  517. $link = l(t('Disable'), page_manager_edit_url($task_name, array('handlers', $page->name, 'actions', 'disable')));
  518. $text = t('Enabled');
  519. }
  520. $rows[] = array(
  521. array('class' => array('page-summary-label'), 'data' => t('Status')),
  522. array('class' => array('page-summary-data'), 'data' => $text),
  523. array('class' => array('page-summary-operation'), 'data' => $link),
  524. );
  525. $path = array();
  526. foreach (explode('/', $page->path) as $bit) {
  527. if ($bit[0] != '!') {
  528. $path[] = $bit;
  529. }
  530. }
  531. $path = implode('/', $path);
  532. $front = variable_get('site_frontpage', 'node');
  533. $link = l(t('Edit'), page_manager_edit_url($task_name, array('settings', 'basic')));
  534. $message = '';
  535. if ($path == $front) {
  536. $message = t('This is your site home page.');
  537. }
  538. else if (!empty($page->make_frontpage)) {
  539. $message = t('This page is set to become your site home page.');
  540. }
  541. if ($message) {
  542. $rows[] = array(
  543. array('class' => array('page-summary-data'), 'data' => $message, 'colspan' => 2),
  544. array('class' => array('page-summary-operation'), 'data' => $link),
  545. );
  546. }
  547. if (strpos($path, '%') === FALSE) {
  548. $path = l('/' . $page->path, $path);
  549. }
  550. else {
  551. $path = '/' . $page->path;
  552. }
  553. $rows[] = array(
  554. array('class' => array('page-summary-label'), 'data' => t('Path')),
  555. array('class' => array('page-summary-data'), 'data' => $path),
  556. array('class' => array('page-summary-operation'), 'data' => $link),
  557. );
  558. if (empty($access['plugins'])) {
  559. $access['plugins'] = array();
  560. }
  561. $contexts = page_manager_page_get_contexts($task, $subtask);
  562. $access = ctools_access_group_summary($page->access, $contexts);
  563. if ($access) {
  564. $access = t('Accessible only if @conditions.', array('@conditions' => $access));
  565. }
  566. else {
  567. $access = t('This page is publicly accessible.');
  568. }
  569. $link = l(t('Edit'), page_manager_edit_url($task_name, array('settings', 'access')));
  570. $rows[] = array(
  571. array('class' => array('page-summary-label'), 'data' => t('Access')),
  572. array('class' => array('page-summary-data'), 'data' => $access),
  573. array('class' => array('page-summary-operation'), 'data' => $link),
  574. );
  575. $menu_options = array(
  576. 'none' => t('No menu entry.'),
  577. 'normal' => t('Normal menu entry.'),
  578. 'tab' => t('Menu tab.'),
  579. 'default tab' => t('Default menu tab.'),
  580. 'action' => t('Local action'),
  581. );
  582. if (!empty($page->menu)) {
  583. $menu = $menu_options[$page->menu['type']];
  584. if ($page->menu['type'] != 'none') {
  585. $menu .= ' ' . t('Title: %title.', array('%title' => $page->menu['title']));
  586. switch ($page->menu['type']) {
  587. case 'default tab':
  588. $menu .= ' ' . t('Parent title: %title.', array('%title' => $page->menu['parent']['title']));
  589. break;
  590. case 'normal':
  591. if (module_exists('menu')) {
  592. $menus = menu_get_menus();
  593. $menu .= ' ' . t('Menu block: %title.', array('%title' => $menus[$page->menu['name']]));
  594. }
  595. break;
  596. }
  597. }
  598. }
  599. else {
  600. $menu = t('No menu entry');
  601. }
  602. $link = l(t('Edit'), page_manager_edit_url($task_name, array('settings', 'menu')));
  603. $rows[] = array(
  604. array('class' => array('page-summary-label'), 'data' => t('Menu')),
  605. array('class' => array('page-summary-data'), 'data' => $menu),
  606. array('class' => array('page-summary-operation'), 'data' => $link),
  607. );
  608. $output .= theme('table', array('rows' => $rows, 'attributes' => array('id' => 'page-manager-page-summary')));
  609. return $output;
  610. }
  611. /**
  612. * Callback to enable/disable the page from the UI.
  613. */
  614. function page_manager_page_enable(&$cache, $status) {
  615. $page = &$cache->subtask['subtask'];
  616. ctools_include('export');
  617. ctools_export_set_object_status($page, $status);
  618. $page->disabled = FALSE;
  619. }
  620. /**
  621. * Recalculate the arguments when something like the path changes.
  622. */
  623. function page_manager_page_recalculate_arguments(&$page) {
  624. // Ensure $page->arguments contains only real arguments:
  625. $arguments = page_manager_page_get_named_arguments($page->path);
  626. $args = array();
  627. foreach ($arguments as $keyword => $position) {
  628. if (isset($page->arguments[$keyword])) {
  629. $args[$keyword] = $page->arguments[$keyword];
  630. }
  631. else {
  632. $args[$keyword] = array(
  633. 'id' => '',
  634. 'identifier' => '',
  635. 'argument' => '',
  636. 'settings' => array(),
  637. );
  638. }
  639. }
  640. $page->arguments = $args;
  641. }
  642. /**
  643. * When adding or cloning a new page, this creates a new page cache
  644. * and adds our page to it.
  645. *
  646. * This does not check to see if the existing cache is already locked.
  647. * This must be done beforehand.
  648. *
  649. * @param &$page
  650. * The page to create.
  651. * @param &$cache
  652. * The cache to use. If the cache has any existing task handlers,
  653. * they will be marked for deletion. This may be a blank object.
  654. */
  655. function page_manager_page_new_page_cache(&$page, &$cache) {
  656. // Does a page already exist? If so, we are overwriting it so
  657. // take its pid.
  658. if (!empty($cache->subtask) && !empty($cache->subtask['subtask']) && !empty($cache->subtask['subtask']->pid)) {
  659. $page->pid = $cache->subtask['subtask']->pid;
  660. }
  661. else {
  662. $cache->new = TRUE;
  663. }
  664. $cache->task_name = page_manager_make_task_name('page', $page->name);
  665. $cache->task_id = 'page';
  666. $cache->task = page_manager_get_task('page');
  667. $cache->subtask_id = $page->name;
  668. $page->export_type = EXPORT_IN_DATABASE;
  669. $page->type = t('Normal');
  670. $cache->subtask = page_manager_page_build_subtask($cache->task, $page);
  671. if (isset($cache->handlers)) {
  672. foreach($cache->handlers as $id => $handler) {
  673. $cache->handler_info[$id]['changed'] = PAGE_MANAGER_CHANGED_DELETED;
  674. }
  675. }
  676. else {
  677. $cache->handlers = array();
  678. $cache->handler_info = array();
  679. }
  680. if (!empty($page->default_handlers)) {
  681. foreach ($page->default_handlers as $id => $handler) {
  682. page_manager_handler_add_to_page($cache, $handler);
  683. }
  684. }
  685. $cache->locked = FALSE;
  686. $cache->changed = TRUE;
  687. }
  688. /**
  689. * Callback to determine if a page is accessible.
  690. *
  691. * @param $task
  692. * The task plugin.
  693. * @param $subtask_id
  694. * The subtask id
  695. * @param $contexts
  696. * The contexts loaded for the task.
  697. * @return
  698. * TRUE if the current user can access the page.
  699. */
  700. function page_manager_page_access_check($task, $subtask_id, $contexts) {
  701. $page = page_manager_page_load($subtask_id);
  702. return ctools_access($page->access, $contexts);
  703. }