ctools.module

  1. cis7 sites/all/modules/ulmus/ctools/ctools.module
  2. cle7 sites/all/modules/ulmus/ctools/ctools.module
  3. ecd7 sites/all/modules/ulmus/ctools/ctools.module
  4. elmsmedia7 sites/all/modules/ulmus/ctools/ctools.module
  5. harmony7 sites/all/modules/ulmus/ctools/ctools.module
  6. icor7 sites/all/modules/ulmus/ctools/ctools.module
  7. meedjum_blog7 sites/all/modules/ulmus/ctools/ctools.module
  8. mooc7 sites/all/modules/ulmus/ctools/ctools.module

CTools primary module file.

Most of the CTools tools are in their own .inc files. This contains nothing more than a few convenience functions and some hooks that must be implemented in the module file.

Functions

Namesort descending Description
ctools_access_menu Determine if the current user has access via a plugin.
ctools_access_multiperm Determine if the current user has access via checks to multiple different permissions.
ctools_add_css Include css files as necessary.
ctools_add_js Include js files as necessary.
ctools_ajax_theme_callback Menu theme callback.
ctools_api_version Test the CTools API version.
ctools_attach_css Format a css file name for use with $form['#attached']['css'].
ctools_attach_js Format a javascript file name for use with $form['#attached']['js'].
ctools_block_list_alter Implement hook_block_list_alter() to potentially remove blocks.
ctools_break_phrase
ctools_class_add Add an array of classes to the body.
ctools_class_remove Remove an array of classes from the body.
ctools_cron Implementation of hook_cron. Clean up old caches.
ctools_ctools_entity_context_alter Implements hook_ctools_entity_context_alter().
ctools_ctools_plugin_directory Implementation of hook_ctools_plugin_directory() to let the system know where all our own plugins are.
ctools_ctools_plugin_type Implements hook_ctools_plugin_type().
ctools_element_info_alter Implements hook_element_info_alter().
ctools_export_ui_ctools_access_get Callback for access control ajax form on behalf of export ui.
ctools_export_ui_ctools_access_set Callback for access control ajax form on behalf of export ui
ctools_export_ui_load Menu _load hook.
ctools_export_ui_task_access Menu access callback for various tasks of export-ui.
ctools_file_download Implementation of hook_file_download()
ctools_flush_caches Ensure the CTools CSS cache is flushed whenever hook_flush_caches is invoked.
ctools_form_include Include .inc files in a form context.
ctools_form_include_file Add an arbitrary path to the $form_state so it can work with form cache.
ctools_get_roles Deprecated Get a list of roles in the system.
ctools_image_path Provide the proper path to an image as necessary.
ctools_include Include .inc files as necessary.
ctools_init Implement hook_init to keep our global CSS at the ready.
ctools_js_load Check to see if the incoming menu item is js capable or not.
ctools_menu Implements hook_menu().
ctools_menu_local_tasks_alter Implements hook_menu_local_tasks_alter().
ctools_modules_enabled Implement hook_modules_enabled to clear static caches for detecting new plugins
ctools_page_alter
ctools_page_token_processing A theme post_render callback to allow content type plugins to use page template variables which are not yet available when the content type is rendered.
ctools_preprocess_node A theme preprocess function to automatically allow panels-based node templates based upon input when the panel was configured.
ctools_process Implements hook_process().
ctools_registry_files_alter Implements hook_registry_files_alter().
ctools_set_callback_token Easily set a token from the page variables.
ctools_set_no_blocks Tell CTools that sidebar blocks should not be rendered.
ctools_set_page_token Set a token/value pair to be replaced later in the request, specifically in ctools_preprocess_page().
ctools_set_variable_token Easily set a token from the page variables.
ctools_shutdown_handler Shutdown handler used during ajax operations to help catch fatal errors.
ctools_theme Implements hook_theme().
ctools_uuid_generate
ctools_uuid_is_valid Check that a string appears to be in the format of a UUID.

Constants

Namesort descending Description
CTOOLS_API_VERSION

File

sites/all/modules/ulmus/ctools/ctools.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * CTools primary module file.
  5. *
  6. * Most of the CTools tools are in their own .inc files. This contains
  7. * nothing more than a few convenience functions and some hooks that
  8. * must be implemented in the module file.
  9. */
  10. define('CTOOLS_API_VERSION', '2.0.7');
  11. /**
  12. * Test the CTools API version.
  13. *
  14. * This function can always be used to safely test if CTools has the minimum
  15. * API version that your module can use. It can also try to protect you from
  16. * running if the CTools API version is too new, but if you do that you need
  17. * to be very quick about watching CTools API releases and release new versions
  18. * of your software as soon as the new release is made, or people might end up
  19. * updating CTools and having your module shut down without any recourse.
  20. *
  21. * It is recommended that every hook of your module that might use CTools or
  22. * might lead to a use of CTools be guarded like this:
  23. *
  24. * @code
  25. * if (!module_invoke('ctools', 'api_version', '1.0')) {
  26. * return;
  27. * }
  28. * @endcode
  29. *
  30. * Note that some hooks such as _menu() or _theme() must return an array().
  31. *
  32. * You can use it in your hook_requirements to report this error condition
  33. * like this:
  34. *
  35. * @code
  36. * define('MODULENAME_MINIMUM_CTOOLS_API_VERSION', '1.0');
  37. * define('MODULENAME_MAXIMUM_CTOOLS_API_VERSION', '1.1');
  38. *
  39. * function MODULENAME_requirements($phase) {
  40. * $requirements = array();
  41. * if (!module_invoke('ctools', 'api_version', MODULENAME_MINIMUM_CTOOLS_API_VERSION, MODULENAME_MAXIMUM_CTOOLS_API_VERSION)) {
  42. * $requirements['MODULENAME_ctools'] = array(
  43. * 'title' => $t('MODULENAME required Chaos Tool Suite (CTools) API Version'),
  44. * 'value' => t('Between @a and @b', array('@a' => MODULENAME_MINIMUM_CTOOLS_API_VERSION, '@b' => MODULENAME_MAXIMUM_CTOOLS_API_VERSION)),
  45. * 'severity' => REQUIREMENT_ERROR,
  46. * );
  47. * }
  48. * return $requirements;
  49. * }
  50. * @endcode
  51. *
  52. * Please note that the version is a string, not an floating point number.
  53. * This will matter once CTools reaches version 1.10.
  54. *
  55. * A CTools API changes history will be kept in API.txt. Not every new
  56. * version of CTools will necessarily update the API version.
  57. * @param $minimum
  58. * The minimum version of CTools necessary for your software to run with it.
  59. * @param $maximum
  60. * The maximum version of CTools allowed for your software to run with it.
  61. */
  62. function ctools_api_version($minimum, $maximum = NULL) {
  63. if (version_compare(CTOOLS_API_VERSION, $minimum, '<')) {
  64. return FALSE;
  65. }
  66. if (isset($maximum) && version_compare(CTOOLS_API_VERSION, $maximum, '>')) {
  67. return FALSE;
  68. }
  69. return TRUE;
  70. }
  71. // -----------------------------------------------------------------------
  72. // General utility functions
  73. /**
  74. * Include .inc files as necessary.
  75. *
  76. * This fuction is helpful for including .inc files for your module. The
  77. * general case is including ctools funcitonality like this:
  78. *
  79. * @code
  80. * ctools_include('plugins');
  81. * @endcode
  82. *
  83. * Similar funcitonality can be used for other modules by providing the $module
  84. * and $dir arguments like this:
  85. *
  86. * @code
  87. * // include mymodule/includes/import.inc
  88. * ctools_include('import', 'mymodule');
  89. * // include mymodule/plugins/foobar.inc
  90. * ctools_include('foobar', 'mymodule', 'plugins');
  91. * @endcode
  92. *
  93. * @param $file
  94. * The base file name to be included.
  95. * @param $module
  96. * Optional module containing the include.
  97. * @param $dir
  98. * Optional subdirectory containing the include file.
  99. */
  100. function ctools_include($file, $module = 'ctools', $dir = 'includes') {
  101. static $used = array();
  102. $dir = '/' . ($dir ? $dir . '/' : '');
  103. if (!isset($used[$module][$dir][$file])) {
  104. require_once DRUPAL_ROOT . '/' . drupal_get_path('module', $module) . "$dir$file.inc";
  105. $used[$module][$dir][$file] = TRUE;
  106. }
  107. }
  108. /**
  109. * Include .inc files in a form context.
  110. *
  111. * This is a variant of ctools_include that will save information in the
  112. * the form_state so that cached forms will properly include things.
  113. */
  114. function ctools_form_include(&$form_state, $file, $module = 'ctools', $dir = 'includes') {
  115. if (!isset($form_state['build_info']['args'])) {
  116. $form_state['build_info']['args'] = array();
  117. }
  118. $dir = '/' . ($dir ? $dir . '/' : '');
  119. form_load_include($form_state, 'inc', $module, $dir . $file);
  120. }
  121. /**
  122. * Add an arbitrary path to the $form_state so it can work with form cache.
  123. *
  124. * module_load_include uses an unfortunately annoying syntax to work, making it
  125. * difficult to translate the more simple $path + $file syntax.
  126. */
  127. function ctools_form_include_file(&$form_state, $filename) {
  128. if (!isset($form_state['build_info']['args'])) {
  129. $form_state['build_info']['args'] = array();
  130. }
  131. // Now add this to the build info files so that AJAX requests will know to load it.
  132. $form_state['build_info']['files']["$filename"] = $filename;
  133. require_once DRUPAL_ROOT . '/' . $filename;
  134. }
  135. /**
  136. * Provide the proper path to an image as necessary.
  137. *
  138. * This helper function is used by ctools but can also be used in other
  139. * modules in the same way as explained in the comments of ctools_include.
  140. *
  141. * @param $image
  142. * The base file name (with extension) of the image to be included.
  143. * @param $module
  144. * Optional module containing the include.
  145. * @param $dir
  146. * Optional subdirectory containing the include file.
  147. */
  148. function ctools_image_path($image, $module = 'ctools', $dir = 'images') {
  149. return drupal_get_path('module', $module) . "/$dir/" . $image;
  150. }
  151. /**
  152. * Include css files as necessary.
  153. *
  154. * This helper function is used by ctools but can also be used in other
  155. * modules in the same way as explained in the comments of ctools_include.
  156. *
  157. * @param $file
  158. * The base file name to be included.
  159. * @param $module
  160. * Optional module containing the include.
  161. * @param $dir
  162. * Optional subdirectory containing the include file.
  163. */
  164. function ctools_add_css($file, $module = 'ctools', $dir = 'css') {
  165. drupal_add_css(drupal_get_path('module', $module) . "/$dir/$file.css");
  166. }
  167. /**
  168. * Format a css file name for use with $form['#attached']['css'].
  169. *
  170. * This helper function is used by ctools but can also be used in other
  171. * modules in the same way as explained in the comments of ctools_include.
  172. *
  173. * @code
  174. * $form['#attached']['css'] = array(ctools_attach_css('collapsible-div'));
  175. * $form['#attached']['css'][ctools_attach_css('collapsible-div')] = array('preprocess' => FALSE);
  176. * @endcode
  177. *
  178. * @param $file
  179. * The base file name to be included.
  180. * @param $module
  181. * Optional module containing the include.
  182. * @param $dir
  183. * Optional subdirectory containing the include file.
  184. */
  185. function ctools_attach_css($file, $module = 'ctools', $dir = 'css') {
  186. return drupal_get_path('module', $module) . "/$dir/$file.css";
  187. }
  188. /**
  189. * Include js files as necessary.
  190. *
  191. * This helper function is used by ctools but can also be used in other
  192. * modules in the same way as explained in the comments of ctools_include.
  193. *
  194. * @param $file
  195. * The base file name to be included.
  196. * @param $module
  197. * Optional module containing the include.
  198. * @param $dir
  199. * Optional subdirectory containing the include file.
  200. */
  201. function ctools_add_js($file, $module = 'ctools', $dir = 'js') {
  202. drupal_add_js(drupal_get_path('module', $module) . "/$dir/$file.js");
  203. }
  204. /**
  205. * Format a javascript file name for use with $form['#attached']['js'].
  206. *
  207. * This helper function is used by ctools but can also be used in other
  208. * modules in the same way as explained in the comments of ctools_include.
  209. *
  210. * @code
  211. * $form['#attached']['js'] = array(ctools_attach_js('auto-submit'));
  212. * @endcode
  213. *
  214. * @param $file
  215. * The base file name to be included.
  216. * @param $module
  217. * Optional module containing the include.
  218. * @param $dir
  219. * Optional subdirectory containing the include file.
  220. */
  221. function ctools_attach_js($file, $module = 'ctools', $dir = 'js') {
  222. return drupal_get_path('module', $module) . "/$dir/$file.js";
  223. }
  224. /**
  225. * Get a list of roles in the system.
  226. *
  227. * @return
  228. * An array of role names keyed by role ID.
  229. *
  230. * @deprecated
  231. * user_roles() should be used instead.
  232. */
  233. function ctools_get_roles() {
  234. return user_roles();
  235. }
  236. /*
  237. * Break x,y,z and x+y+z into an array. Numeric only.
  238. *
  239. * @param $str
  240. * The string to parse.
  241. *
  242. * @return $object
  243. * An object containing
  244. * - operator: Either 'and' or 'or'
  245. * - value: An array of numeric values.
  246. */
  247. function ctools_break_phrase($str) {
  248. $object = new stdClass();
  249. if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str)) {
  250. // The '+' character in a query string may be parsed as ' '.
  251. $object->operator = 'or';
  252. $object->value = preg_split('/[+ ]/', $str);
  253. }
  254. else if (preg_match('/^([0-9]+,)*[0-9]+$/', $str)) {
  255. $object->operator = 'and';
  256. $object->value = explode(',', $str);
  257. }
  258. // Keep an 'error' value if invalid strings were given.
  259. if (!empty($str) && (empty($object->value) || !is_array($object->value))) {
  260. $object->value = array(-1);
  261. $object->invalid_input = TRUE;
  262. return $object;
  263. }
  264. if (empty($object->value)) {
  265. $object->value = array();
  266. }
  267. // Doubly ensure that all values are numeric only.
  268. foreach ($object->value as $id => $value) {
  269. $object->value[$id] = intval($value);
  270. }
  271. return $object;
  272. }
  273. /**
  274. * Set a token/value pair to be replaced later in the request, specifically in
  275. * ctools_preprocess_page().
  276. *
  277. * @param $token
  278. * The token to be replaced later, during page rendering. This should
  279. * ideally be a string inside of an HTML comment, so that if there is
  280. * no replacement, the token will not render on the page.
  281. * @param $type
  282. * The type of the token. Can be either 'variable', which will pull data
  283. * directly from the page variables
  284. * @param $argument
  285. * If $type == 'variable' then argument should be the key to fetch from
  286. * the $variables. If $type == 'callback' then it should either be the
  287. * callback, or an array that will be sent to call_user_func_array().
  288. *
  289. * @return
  290. * A array of token/variable names to be replaced.
  291. */
  292. function ctools_set_page_token($token = NULL, $type = NULL, $argument = NULL) {
  293. static $tokens = array();
  294. if (isset($token)) {
  295. $tokens[$token] = array($type, $argument);
  296. }
  297. return $tokens;
  298. }
  299. /**
  300. * Easily set a token from the page variables.
  301. *
  302. * This function can be used like this:
  303. * $token = ctools_set_variable_token('tabs');
  304. *
  305. * $token will then be a simple replacement for the 'tabs' about of the
  306. * variables available in the page template.
  307. */
  308. function ctools_set_variable_token($token) {
  309. $string = '<!-- ctools-page-' . $token . ' -->';
  310. ctools_set_page_token($string, 'variable', $token);
  311. return $string;
  312. }
  313. /**
  314. * Easily set a token from the page variables.
  315. *
  316. * This function can be used like this:
  317. * $token = ctools_set_variable_token('id', 'mymodule_myfunction');
  318. */
  319. function ctools_set_callback_token($token, $callback) {
  320. // If the callback uses arguments they are considered in the token.
  321. if (is_array($callback)) {
  322. $token .= '-' . md5(serialize($callback));
  323. }
  324. $string = '<!-- ctools-page-' . $token . ' -->';
  325. ctools_set_page_token($string, 'callback', $callback);
  326. return $string;
  327. }
  328. /**
  329. * Tell CTools that sidebar blocks should not be rendered.
  330. *
  331. * It is often desirable to not display sidebars when rendering a page,
  332. * particularly when using Panels. This informs CTools to alter out any
  333. * sidebar regions during block render.
  334. */
  335. function ctools_set_no_blocks($blocks = FALSE) {
  336. $status = &drupal_static(__FUNCTION__, TRUE);
  337. $status = $blocks;
  338. }
  339. /**
  340. * Wrapper function to create UUIDs via ctools, falls back on UUID module
  341. * if it is enabled. This code is a copy of uuid.inc from the uuid module.
  342. * @see http://php.net/uniqid#65879
  343. */
  344. function ctools_uuid_generate() {
  345. if (!module_exists('uuid')) {
  346. ctools_include('uuid');
  347. $callback = drupal_static(__FUNCTION__);
  348. if (empty($callback)) {
  349. if (function_exists('uuid_create') && !function_exists('uuid_make')) {
  350. $callback = '_ctools_uuid_generate_pecl';
  351. }
  352. elseif (function_exists('com_create_guid')) {
  353. $callback = '_ctools_uuid_generate_com';
  354. }
  355. else {
  356. $callback = '_ctools_uuid_generate_php';
  357. }
  358. }
  359. return $callback();
  360. }
  361. else {
  362. return uuid_generate();
  363. }
  364. }
  365. /**
  366. * Check that a string appears to be in the format of a UUID.
  367. * @see http://drupal.org/project/uuid
  368. *
  369. * @param $uuid
  370. * The string to test.
  371. *
  372. * @return
  373. * TRUE if the string is well formed.
  374. */
  375. function ctools_uuid_is_valid($uuid = '') {
  376. if (empty($uuid)) {
  377. return FALSE;
  378. }
  379. if (function_exists('uuid_is_valid') || module_exists('uuid')) {
  380. return uuid_is_valid($uuid);
  381. }
  382. else {
  383. ctools_include('uuid');
  384. return uuid_is_valid($uuid);
  385. }
  386. }
  387. /**
  388. * Add an array of classes to the body.
  389. *
  390. * @param mixed $classes
  391. * A string or an array of class strings to add.
  392. * @param string $hook
  393. * The theme hook to add the class to. The default is 'html' which will
  394. * affect the body tag.
  395. */
  396. function ctools_class_add($classes, $hook = 'html') {
  397. if (!is_array($classes)) {
  398. $classes = array($classes);
  399. }
  400. $static = &drupal_static('ctools_process_classes', array());
  401. if (!isset($static[$hook]['add'])) {
  402. $static[$hook]['add'] = array();
  403. }
  404. foreach ($classes as $class) {
  405. $static[$hook]['add'][] = $class;
  406. }
  407. }
  408. /**
  409. * Remove an array of classes from the body.
  410. *
  411. * @param mixed $classes
  412. * A string or an array of class strings to remove.
  413. * @param string $hook
  414. * The theme hook to remove the class from. The default is 'html' which will
  415. * affect the body tag.
  416. */
  417. function ctools_class_remove($classes, $hook = 'html') {
  418. if (!is_array($classes)) {
  419. $classes = array($classes);
  420. }
  421. $static = &drupal_static('ctools_process_classes', array());
  422. if (!isset($static[$hook]['remove'])) {
  423. $static[$hook]['remove'] = array();
  424. }
  425. foreach ($classes as $class) {
  426. $static[$hook]['remove'][] = $class;
  427. }
  428. }
  429. // -----------------------------------------------------------------------
  430. // Drupal core hooks
  431. /**
  432. * Implement hook_init to keep our global CSS at the ready.
  433. */
  434. function ctools_init() {
  435. ctools_add_css('ctools');
  436. // If we are sure that CTools' AJAX is in use, change the error handling.
  437. if (!empty($_REQUEST['ctools_ajax'])) {
  438. ini_set('display_errors', 0);
  439. register_shutdown_function('ctools_shutdown_handler');
  440. }
  441. // Clear plugin cache on the module page submit.
  442. if ($_GET['q'] == 'admin/modules/list/confirm' && !empty($_POST)) {
  443. cache_clear_all('ctools_plugin_files:', 'cache', TRUE);
  444. }
  445. }
  446. /**
  447. * Shutdown handler used during ajax operations to help catch fatal errors.
  448. */
  449. function ctools_shutdown_handler() {
  450. if (function_exists('error_get_last') AND ($error = error_get_last())) {
  451. switch ($error['type']) {
  452. case E_ERROR:
  453. case E_CORE_ERROR:
  454. case E_COMPILE_ERROR:
  455. case E_USER_ERROR:
  456. // Do this manually because including files here is dangerous.
  457. $commands = array(
  458. array(
  459. 'command' => 'alert',
  460. 'title' => t('Error'),
  461. 'text' => t('Unable to complete operation. Fatal error in @file on line @line: @message', array(
  462. '@file' => $error['file'],
  463. '@line' => $error['line'],
  464. '@message' => $error['message'],
  465. )),
  466. ),
  467. );
  468. // Change the status code so that the client will read the AJAX returned.
  469. header('HTTP/1.1 200 OK');
  470. drupal_json($commands);
  471. }
  472. }
  473. }
  474. /**
  475. * Implements hook_theme().
  476. */
  477. function ctools_theme() {
  478. ctools_include('utility');
  479. $items = array();
  480. ctools_passthrough('ctools', 'theme', $items);
  481. return $items;
  482. }
  483. /**
  484. * Implements hook_menu().
  485. */
  486. function ctools_menu() {
  487. ctools_include('utility');
  488. $items = array();
  489. ctools_passthrough('ctools', 'menu', $items);
  490. return $items;
  491. }
  492. /**
  493. * Implementation of hook_cron. Clean up old caches.
  494. */
  495. function ctools_cron() {
  496. ctools_include('utility');
  497. $items = array();
  498. ctools_passthrough('ctools', 'cron', $items);
  499. }
  500. /**
  501. * Ensure the CTools CSS cache is flushed whenever hook_flush_caches is invoked.
  502. */
  503. function ctools_flush_caches() {
  504. // Do not actually flush caches if running on cron. Drupal uses this hook
  505. // in an inconsistent fashion and it does not necessarily mean to *flush*
  506. // caches when running from cron. Instead it's just getting a list of cache
  507. // tables and may not do any flushing.
  508. if (!empty($GLOBALS['locks']['cron'])) {
  509. return;
  510. }
  511. ctools_include('css');
  512. ctools_css_flush_caches();
  513. }
  514. /**
  515. * Implements hook_element_info_alter().
  516. *
  517. */
  518. function ctools_element_info_alter(&$type) {
  519. ctools_include('dependent');
  520. ctools_dependent_element_info_alter($type);
  521. }
  522. /**
  523. * Implementation of hook_file_download()
  524. *
  525. * When using the private file system, we have to let Drupal know it's ok to
  526. * download CSS and image files from our temporary directory.
  527. */
  528. function ctools_file_download($filepath) {
  529. if (strpos($filepath, 'ctools') === 0) {
  530. $mime = file_get_mimetype($filepath);
  531. // For safety's sake, we allow only text and images.
  532. if (strpos($mime, 'text') === 0 || strpos($mime, 'image') === 0) {
  533. return array('Content-type:' . $mime);
  534. }
  535. }
  536. }
  537. /**
  538. * Implements hook_registry_files_alter().
  539. *
  540. * Alter the registry of files to automagically include all classes in
  541. * class-based plugins.
  542. */
  543. function ctools_registry_files_alter(&$files, $indexed_modules) {
  544. ctools_include('registry');
  545. return _ctools_registry_files_alter($files, $indexed_modules);
  546. }
  547. // -----------------------------------------------------------------------
  548. // CTools hook implementations.
  549. /**
  550. * Implementation of hook_ctools_plugin_directory() to let the system know
  551. * where all our own plugins are.
  552. */
  553. function ctools_ctools_plugin_directory($owner, $plugin_type) {
  554. if ($owner == 'ctools') {
  555. return 'plugins/' . $plugin_type;
  556. }
  557. }
  558. /**
  559. * Implements hook_ctools_plugin_type().
  560. */
  561. function ctools_ctools_plugin_type() {
  562. ctools_include('utility');
  563. $items = array();
  564. // Add all the plugins that have their own declaration space elsewhere.
  565. ctools_passthrough('ctools', 'plugin-type', $items);
  566. return $items;
  567. }
  568. // -----------------------------------------------------------------------
  569. // Drupal theme preprocess hooks that must be in the .module file.
  570. /**
  571. * A theme preprocess function to automatically allow panels-based node
  572. * templates based upon input when the panel was configured.
  573. */
  574. function ctools_preprocess_node(&$vars) {
  575. // The 'ctools_template_identifier' attribute of the node is added when the pane is
  576. // rendered.
  577. if (!empty($vars['node']->ctools_template_identifier)) {
  578. $vars['ctools_template_identifier'] = check_plain($vars['node']->ctools_template_identifier);
  579. $vars['theme_hook_suggestions'][] = 'node__panel__' . check_plain($vars['node']->ctools_template_identifier);
  580. }
  581. }
  582. function ctools_page_alter(&$page) {
  583. $page['#post_render'][] = 'ctools_page_token_processing';
  584. }
  585. /**
  586. * A theme post_render callback to allow content type plugins to use page
  587. * template variables which are not yet available when the content type is
  588. * rendered.
  589. */
  590. function ctools_page_token_processing($children, $elements) {
  591. $tokens = ctools_set_page_token();
  592. if (!empty($tokens)) {
  593. foreach ($tokens as $token => $key) {
  594. list($type, $argument) = $key;
  595. switch ($type) {
  596. case 'variable':
  597. $tokens[$token] = isset($variables[$argument]) ? $variables[$argument] : '';
  598. break;
  599. case 'callback':
  600. if (is_string($argument) && function_exists($argument)) {
  601. $tokens[$token] = $argument($variables);
  602. }
  603. if (is_array($argument) && function_exists($argument[0])) {
  604. $function = array_shift($argument);
  605. $argument = array_merge(array(&$variables), $argument);
  606. $tokens[$token] = call_user_func_array($function, $argument);
  607. }
  608. break;
  609. }
  610. }
  611. $children = strtr($children, $tokens);
  612. }
  613. return $children;
  614. }
  615. /**
  616. * Implements hook_process().
  617. *
  618. * Add and remove CSS classes from the variables array. We use process so that
  619. * we alter anything added in the preprocess hooks.
  620. */
  621. function ctools_process(&$variables, $hook) {
  622. if (!isset($variables['classes'])) {
  623. return;
  624. }
  625. $classes = drupal_static('ctools_process_classes', array());
  626. // Process the classses to add.
  627. if (!empty($classes[$hook]['add'])) {
  628. $add_classes = array_map('drupal_clean_css_identifier', $classes[$hook]['add']);
  629. $variables['classes_array'] = array_unique(array_merge($variables['classes_array'], $add_classes));
  630. }
  631. // Process the classes to remove.
  632. if (!empty($classes[$hook]['remove'])) {
  633. $remove_classes = array_map('drupal_clean_css_identifier', $classes[$hook]['remove']);
  634. $variables['classes_array'] = array_diff($variables['classes_array'], $remove_classes);
  635. }
  636. // Since this runs after template_process(), we need to re-implode the
  637. // classes array.
  638. $variables['classes'] = implode(' ', $variables['classes_array']);
  639. }
  640. // -----------------------------------------------------------------------
  641. // Menu callbacks that must be in the .module file.
  642. /**
  643. * Determine if the current user has access via a plugin.
  644. *
  645. * This function is meant to be embedded in the Drupal menu system, and
  646. * therefore is in the .module file since sub files can't be loaded, and
  647. * takes arguments a little bit more haphazardly than ctools_access().
  648. *
  649. * @param $access
  650. * An access control array which contains the following information:
  651. * - 'logic': and or or. Whether all tests must pass or one must pass.
  652. * - 'plugins': An array of access plugins. Each contains:
  653. * - - 'name': The name of the plugin
  654. * - - 'settings': The settings from the plugin UI.
  655. * - - 'context': Which context to use.
  656. * @param ...
  657. * zero or more context arguments generated from argument plugins. These
  658. * contexts must have an 'id' attached to them so that they can be
  659. * properly associated. The argument plugin system should set this, but
  660. * if the context is coming from elsewhere it will need to be set manually.
  661. *
  662. * @return
  663. * TRUE if access is granted, false if otherwise.
  664. */
  665. function ctools_access_menu($access) {
  666. // Short circuit everything if there are no access tests.
  667. if (empty($access['plugins'])) {
  668. return TRUE;
  669. }
  670. $contexts = array();
  671. foreach (func_get_args() as $arg) {
  672. if (is_object($arg) && get_class($arg) == 'ctools_context') {
  673. $contexts[$arg->id] = $arg;
  674. }
  675. }
  676. ctools_include('context');
  677. return ctools_access($access, $contexts);
  678. }
  679. /**
  680. * Determine if the current user has access via checks to multiple different
  681. * permissions.
  682. *
  683. * This function is a thin wrapper around user_access that allows multiple
  684. * permissions to be easily designated for use on, for example, a menu callback.
  685. *
  686. * @param ...
  687. * An indexed array of zero or more permission strings to be checked by
  688. * user_access().
  689. *
  690. * @return
  691. * Iff all checks pass will this function return TRUE. If an invalid argument
  692. * is passed (e.g., not a string), this function errs on the safe said and
  693. * returns FALSE.
  694. */
  695. function ctools_access_multiperm() {
  696. foreach (func_get_args() as $arg) {
  697. if (!is_string($arg) || !user_access($arg)) {
  698. return FALSE;
  699. }
  700. }
  701. return TRUE;
  702. }
  703. /**
  704. * Check to see if the incoming menu item is js capable or not.
  705. *
  706. * This can be used as %ctools_js as part of a path in hook menu. CTools
  707. * ajax functions will automatically change the phrase 'nojs' to 'ajax'
  708. * when it attaches ajax to a link. This can be used to autodetect if
  709. * that happened.
  710. */
  711. function ctools_js_load($js) {
  712. if ($js == 'ajax') {
  713. return TRUE;
  714. }
  715. return 0;
  716. }
  717. /**
  718. * Menu _load hook.
  719. *
  720. * This function will be called to load an object as a replacement for
  721. * %ctools_export_ui in menu paths.
  722. */
  723. function ctools_export_ui_load($item_name, $plugin_name) {
  724. $return = &drupal_static(__FUNCTION__, FALSE);
  725. if (!$return) {
  726. ctools_include('export-ui');
  727. $plugin = ctools_get_export_ui($plugin_name);
  728. $handler = ctools_export_ui_get_handler($plugin);
  729. if ($handler) {
  730. return $handler->load_item($item_name);
  731. }
  732. }
  733. return $return;
  734. }
  735. // -----------------------------------------------------------------------
  736. // Caching callbacks on behalf of export-ui.
  737. /**
  738. * Menu access callback for various tasks of export-ui.
  739. */
  740. function ctools_export_ui_task_access($plugin_name, $op, $item = NULL) {
  741. ctools_include('export-ui');
  742. $plugin = ctools_get_export_ui($plugin_name);
  743. $handler = ctools_export_ui_get_handler($plugin);
  744. if ($handler) {
  745. return $handler->access($op, $item);
  746. }
  747. // Deny access if the handler cannot be found.
  748. return FALSE;
  749. }
  750. /**
  751. * Callback for access control ajax form on behalf of export ui.
  752. *
  753. * Returns the cached access config and contexts used.
  754. * Note that this is assuming that access will be in $item->access -- if it
  755. * is not, an export UI plugin will have to make its own callbacks.
  756. */
  757. function ctools_export_ui_ctools_access_get($argument) {
  758. ctools_include('export-ui');
  759. list($plugin_name, $key) = explode(':', $argument, 2);
  760. $plugin = ctools_get_export_ui($plugin_name);
  761. $handler = ctools_export_ui_get_handler($plugin);
  762. if ($handler) {
  763. ctools_include('context');
  764. $item = $handler->edit_cache_get($key);
  765. if (!$item) {
  766. $item = ctools_export_crud_load($handler->plugin['schema'], $key);
  767. }
  768. $contexts = ctools_context_load_contexts($item);
  769. return array($item->access, $contexts);
  770. }
  771. }
  772. /**
  773. * Callback for access control ajax form on behalf of export ui
  774. *
  775. * Returns the cached access config and contexts used.
  776. * Note that this is assuming that access will be in $item->access -- if it
  777. * is not, an export UI plugin will have to make its own callbacks.
  778. */
  779. function ctools_export_ui_ctools_access_set($argument, $access) {
  780. ctools_include('export-ui');
  781. list($plugin_name, $key) = explode(':', $argument, 2);
  782. $plugin = ctools_get_export_ui($plugin_name);
  783. $handler = ctools_export_ui_get_handler($plugin);
  784. if ($handler) {
  785. ctools_include('context');
  786. $item = $handler->edit_cache_get($key);
  787. if (!$item) {
  788. $item = ctools_export_crud_load($handler->plugin['schema'], $key);
  789. }
  790. $item->access = $access;
  791. return $handler->edit_cache_set_key($item, $key);
  792. }
  793. }
  794. /**
  795. * Implements hook_menu_local_tasks_alter().
  796. */
  797. function ctools_menu_local_tasks_alter(&$data, $router_item, $root_path) {
  798. ctools_include('menu');
  799. _ctools_menu_add_dynamic_items($data, $router_item, $root_path);
  800. }
  801. /**
  802. * Implement hook_block_list_alter() to potentially remove blocks.
  803. *
  804. * This exists in order to replicate Drupal 6's "no blocks" functionality.
  805. */
  806. function ctools_block_list_alter(&$blocks) {
  807. $check = drupal_static('ctools_set_no_blocks', TRUE);
  808. if (!$check) {
  809. foreach ($blocks as $block_id => $block) {
  810. // @todo -- possibly we can set configuration for this so that users can
  811. // specify which blocks will not get rendered.
  812. if (strpos($block->region, 'sidebar') !== FALSE) {
  813. unset($blocks[$block_id]);
  814. }
  815. }
  816. }
  817. }
  818. /**
  819. * Implement hook_modules_enabled to clear static caches for detecting new plugins
  820. */
  821. function ctools_modules_enabled($modules) {
  822. ctools_include('plugins');
  823. ctools_get_plugins_reset();
  824. }
  825. /**
  826. * Menu theme callback.
  827. *
  828. * This simply ensures that Panels ajax calls are rendered in the same
  829. * theme as the original page to prevent .css file confusion.
  830. *
  831. * To use this, set this as the theme callback on AJAX related menu
  832. * items. Since the ajax page state won't be sent during ajax requests,
  833. * it should be safe to use even if ajax isn't invoked.
  834. */
  835. function ctools_ajax_theme_callback() {
  836. if (!empty($_POST['ajax_page_state']['theme'])) {
  837. return $_POST['ajax_page_state']['theme'];
  838. }
  839. }
  840. /**
  841. * Implements hook_ctools_entity_context_alter().
  842. */
  843. function ctools_ctools_entity_context_alter(&$plugin, &$entity, $plugin_id) {
  844. ctools_include('context');
  845. switch ($plugin_id) {
  846. case 'entity_id:taxonomy_term':
  847. $plugin['no ui'] = TRUE;
  848. break;
  849. case 'entity:user':
  850. $plugin = ctools_get_context('user');
  851. unset($plugin['no ui']);
  852. unset($plugin['no required context ui']);
  853. break;
  854. }
  855. // Apply restrictions on taxonomy term reverse relationships whose
  856. // restrictions are in the settings on the field.
  857. if (!empty($plugin['parent']) &&
  858. $plugin['parent'] == 'entity_from_field' &&
  859. !empty($plugin['reverse']) &&
  860. $plugin['to entity'] == 'taxonomy_term') {
  861. $field = field_info_field($plugin['field name']);
  862. if (isset($field['settings']['allowed_values'][0]['vocabulary'])) {
  863. $plugin['required context']->restrictions = array('vocabulary' => array($field['settings']['allowed_values'][0]['vocabulary']));
  864. }
  865. }
  866. }
Error | ELMSLN API

Error

×

Error message

  • Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/elmsln_community/api.elmsln.org/includes/common.inc:2791) in drupal_send_headers() (line 1499 of /var/www/html/elmsln_community/api.elmsln.org/includes/bootstrap.inc).
  • Error: Call to undefined function apc_delete() in DrupalAPCCache->clear() (line 289 of /var/www/html/elmsln_community/api.elmsln.org/sites/all/modules/apc/drupal_apc_cache.inc).
The website encountered an unexpected error. Please try again later.