ds.registry.inc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. <?php
  2. /**
  3. * @file
  4. * Registry file for Display Suite.
  5. */
  6. /**
  7. * Implements hook_menu().
  8. */
  9. function _ds_menu() {
  10. $items = array();
  11. // Layout overview.
  12. $items['admin/structure/ds'] = array(
  13. 'title' => 'Display Suite',
  14. 'description' => 'Manage layouts for entities and configure fields, view modes etc.',
  15. 'page callback' => 'ds_layout_list',
  16. 'file' => 'includes/ds.displays.inc',
  17. 'access arguments' => array('admin_display_suite'),
  18. );
  19. // Layout overview, primary tab.
  20. $items['admin/structure/ds/list'] = array(
  21. 'title' => 'Displays',
  22. 'weight' => -10,
  23. 'type' => MENU_DEFAULT_LOCAL_TASK,
  24. );
  25. // Layout overview, secondary tab.
  26. $items['admin/structure/ds/list/list'] = array(
  27. 'title' => 'List',
  28. 'weight' => -10,
  29. 'type' => MENU_DEFAULT_LOCAL_TASK,
  30. );
  31. // Emergency page
  32. $items['admin/structure/ds/list/emergency'] = array(
  33. 'title' => 'Emergency',
  34. 'description' => 'In case you have errors via Display Suite, visit this page.',
  35. 'page callback' => 'drupal_get_form',
  36. 'page arguments' => array('ds_emergency'),
  37. 'access arguments' => array('admin_display_suite'),
  38. 'file' => 'includes/ds.displays.inc',
  39. 'type' => MENU_LOCAL_TASK,
  40. 'weight' => 100,
  41. );
  42. // Change layout.
  43. $items['admin/structure/ds/change-layout'] = array(
  44. 'title' => 'Change layout',
  45. 'description' => 'Act on layout change to move fields elsewhere',
  46. 'page callback' => 'drupal_get_form',
  47. 'page arguments' => array('ds_field_ui_layout_change'),
  48. 'access arguments' => array('admin_display_suite'),
  49. 'file' => 'includes/ds.field_ui.inc',
  50. 'type' => MENU_VISIBLE_IN_BREADCRUMB,
  51. );
  52. // Revert layout.
  53. $items['admin/structure/ds/revert-layout'] = array(
  54. 'title' => 'Revert layout',
  55. 'description' => 'Revert layout and field settings.',
  56. 'page callback' => 'drupal_get_form',
  57. 'page arguments' => array('ds_revert_layout_field_settings_form'),
  58. 'file' => 'includes/ds.field_ui.inc',
  59. 'access arguments' => array('admin_display_suite'),
  60. 'type' => MENU_VISIBLE_IN_BREADCRUMB,
  61. );
  62. // Disable layout.
  63. $items['admin/structure/ds/disable'] = array(
  64. 'title' => 'Disable layout',
  65. 'description' => 'Disable layout and field settings',
  66. 'page callback' => 'drupal_get_form',
  67. 'page arguments' => array('ds_disable_layout_field_settings_form'),
  68. 'file' => 'includes/ds.field_ui.inc',
  69. 'access arguments' => array('admin_display_suite'),
  70. 'type' => MENU_VISIBLE_IN_BREADCRUMB,
  71. );
  72. // Enable layout.
  73. $items['admin/structure/ds/enable'] = array(
  74. 'title' => 'Enable layout',
  75. 'description' => 'Enable layout and field settings',
  76. 'page callback' => 'drupal_get_form',
  77. 'page arguments' => array('ds_enable_layout_field_settings_form'),
  78. 'file' => 'includes/ds.field_ui.inc',
  79. 'access arguments' => array('admin_display_suite'),
  80. 'type' => MENU_VISIBLE_IN_BREADCRUMB,
  81. );
  82. // CTools content.
  83. $items['admin/structure/ds/fields/manage_ctools/content'] = array(
  84. 'title' => 'Ctools field content',
  85. 'page callback' => 'ds_ctools_content',
  86. 'file' => 'includes/ds.field_ui.inc',
  87. 'access arguments' => array('admin_display_suite'),
  88. 'type' => MENU_CALLBACK,
  89. );
  90. // Contextual links.
  91. if (module_exists('contextual') && module_exists('field_ui')) {
  92. $items['node/%node/display'] = array(
  93. 'title' => 'Manage display',
  94. 'description' => 'Manage display of this content.',
  95. 'page callback' => 'ds_contextual_page_tab',
  96. 'page arguments' => array(1, 'node'),
  97. 'file' => 'includes/ds.contextual.inc',
  98. 'access arguments' => array('administer content types'),
  99. 'type' => MENU_LOCAL_TASK,
  100. );
  101. $items['user/%user/display'] = array(
  102. 'title' => 'Manage display',
  103. 'description' => 'Manage display of this user profile.',
  104. 'page callback' => 'ds_contextual_page_tab',
  105. 'page arguments' => array(1, 'user'),
  106. 'file' => 'includes/ds.contextual.inc',
  107. 'access arguments' => array('administer users'),
  108. 'type' => MENU_LOCAL_TASK,
  109. );
  110. if (module_exists('taxonomy')) {
  111. $items['taxonomy/term/%taxonomy_term/display'] = array(
  112. 'title' => 'Manage display',
  113. 'description' => 'Manage display of this term.',
  114. 'page callback' => 'ds_contextual_page_tab',
  115. 'page arguments' => array(2, 'taxonomy_term'),
  116. 'access arguments' => array('administer taxonomy'),
  117. 'type' => MENU_LOCAL_TASK,
  118. 'weight' => 11,
  119. 'file' => 'includes/ds.contextual.inc',
  120. );
  121. }
  122. }
  123. return $items;
  124. }
  125. /**
  126. * Implements hook_theme().
  127. */
  128. function _ds_theme() {
  129. $theme_functions = array();
  130. // Layouts
  131. $layouts = ds_get_layout_info();
  132. foreach ($layouts as $key => $layout) {
  133. // We don't need panel layouts to be registered.
  134. if (isset($layout['module']) && $layout['module'] == 'panels') {
  135. continue;
  136. }
  137. $theme_functions[$key] = array(
  138. 'render element' => 'elements',
  139. 'template' => strtr($key, '_', '-'),
  140. 'path' => $layout['path'],
  141. );
  142. }
  143. // Field templates
  144. $field_functions = module_invoke_all('ds_field_theme_functions_info');
  145. foreach ($field_functions as $key => $label) {
  146. $theme_functions[$key] = array(
  147. 'render element' => 'element',
  148. 'function' => $key,
  149. );
  150. }
  151. return $theme_functions;
  152. }
  153. /**
  154. * Implements hook_features_api().
  155. */
  156. function _ds_features_api() {
  157. static $api = FALSE;
  158. if (!$api) {
  159. module_load_include('inc', 'features', 'includes/features.ctools');
  160. $api = ctools_component_features_api('ds');
  161. foreach ($api as $key => $value) {
  162. switch ($key) {
  163. case 'ds_field_settings':
  164. $api[$key]['name'] = 'Display Suite field settings';
  165. break;
  166. case 'ds_layout_settings':
  167. $api[$key]['name'] = 'Display Suite layout settings';
  168. break;
  169. case 'ds_view_modes':
  170. $api[$key]['name'] = 'Display Suite view modes';
  171. break;
  172. case 'ds_fields':
  173. $api[$key]['name'] = 'Display Suite fields';
  174. break;
  175. }
  176. }
  177. }
  178. return $api;
  179. }
  180. /**
  181. * Remove or rename layout & field settings on entity machine name update.
  182. *
  183. * @param $entity_type
  184. * The name of the entity type.
  185. * @param $info
  186. * The entity info.
  187. * @param $action
  188. * The action, either update or delete.
  189. */
  190. function _ds_entity_type_update($entity_type, $info, $action) {
  191. // Delete settings.
  192. if ($action == 'delete') {
  193. db_delete('ds_layout_settings')
  194. ->condition('entity_type', $entity_type)
  195. ->condition('bundle', $info->type)
  196. ->execute();
  197. db_delete('ds_field_settings')
  198. ->condition('entity_type', $entity_type)
  199. ->condition('bundle', $info->type)
  200. ->execute();
  201. }
  202. // Update settings.
  203. if ($action == 'update') {
  204. $records = db_query('SELECT * FROM {ds_layout_settings} WHERE entity_type = :entity_type AND bundle = :bundle', array(':entity_type' => $entity_type, ':bundle' => $info->old_type));
  205. foreach ($records as $record) {
  206. $old_id = $entity_type . '|' . $info->old_type . '|' . $record->view_mode;
  207. $new_id = $entity_type . '|' . $info->type . '|' . $record->view_mode;
  208. db_update('ds_layout_settings')
  209. ->fields(array(
  210. 'id' => $new_id,
  211. 'bundle' => $info->type)
  212. )
  213. ->condition('id', $old_id)
  214. ->execute();
  215. }
  216. $records = db_query('SELECT * FROM {ds_field_settings} WHERE entity_type = :entity_type AND bundle = :bundle', array(':entity_type' => $entity_type, ':bundle' => $info->old_type));
  217. foreach ($records as $record) {
  218. $old_id = $entity_type . '|' . $info->old_type . '|' . $record->view_mode;
  219. $new_id = $entity_type . '|' . $info->type . '|' . $record->view_mode;
  220. db_update('ds_field_settings')
  221. ->fields(array(
  222. 'id' => $new_id,
  223. 'bundle' => $info->type)
  224. )
  225. ->condition('id', $old_id)
  226. ->execute();
  227. }
  228. }
  229. // Clear cache.
  230. cache_clear_all('ds_fields:', 'cache', TRUE);
  231. cache_clear_all('ds_field_settings', 'cache');
  232. field_info_cache_clear();
  233. }
  234. /**
  235. * Implements hook_theme_registry_alter().
  236. */
  237. function _ds_theme_registry_alter(&$theme_registry) {
  238. // Inject ds_entity_variables in all entity theming functions.
  239. $entity_info = entity_get_info();
  240. foreach ($entity_info as $entity => $info) {
  241. if (isset($entity_info[$entity]['fieldable']) && $entity_info[$entity]['fieldable']) {
  242. // User uses user_profile for theming.
  243. if ($entity == 'user') $entity = 'user_profile';
  244. // Only add preprocess functions if entity exposes theme function.
  245. if (isset($theme_registry[$entity])) {
  246. $theme_registry[$entity]['preprocess functions'][] = 'ds_entity_variables';
  247. }
  248. }
  249. }
  250. // Support for File Entity.
  251. if (isset($theme_registry['file_entity'])) {
  252. $theme_registry['file_entity']['preprocess functions'][] = 'ds_entity_variables';
  253. }
  254. // Support for Entity API.
  255. if (isset($theme_registry['entity'])) {
  256. $theme_registry['entity']['preprocess functions'][] = 'ds_entity_variables';
  257. }
  258. }
  259. /**
  260. * Implements hook_entity_info_alter().
  261. */
  262. function _ds_entity_info_alter(&$entity_info) {
  263. // Make sure ds_view_modes table exists.
  264. if (!db_table_exists('ds_view_modes')) {
  265. return;
  266. }
  267. ctools_include('export');
  268. // Add custom view modes to entities.
  269. $custom_view_modes = ctools_export_crud_load_all('ds_view_modes');
  270. foreach ($custom_view_modes as $view_mode_key => $view_mode_value) {
  271. $view_mode = array(
  272. 'label' => check_plain($view_mode_value->label),
  273. 'custom settings' => FALSE,
  274. );
  275. foreach ($view_mode_value->entities as $entity_type) {
  276. if (isset($entity_info[$entity_type])) {
  277. $entity_info[$entity_type]['view modes'][$view_mode_key] = $view_mode;
  278. }
  279. }
  280. }
  281. // Add layout if applicable.
  282. $ds_layouts = ds_get_layout_info();
  283. $ds_layout_settings = ctools_export_crud_load_all('ds_layout_settings');
  284. foreach ($ds_layout_settings as $row) {
  285. // Don't store any configuration if the layout is disabled.
  286. if (!empty($row->disabled)) {
  287. continue;
  288. }
  289. // Don't store any configuration with layouts that don't exist anymore.
  290. if (!isset($ds_layouts[$row->layout])) {
  291. continue;
  292. }
  293. // Don't store any configuration if the entity type is not defined.
  294. if (!isset($entity_info[$row->entity_type])) {
  295. continue;
  296. }
  297. // Don't store any configuration if the bundle doesn't exist.
  298. if (!isset($entity_info[$row->entity_type]['bundles'][$row->bundle])) {
  299. continue;
  300. }
  301. $layout = $ds_layouts[$row->layout];
  302. $layout['layout'] = $row->layout;
  303. $layout['settings'] = $row->settings;
  304. $entity_info[$row->entity_type]['bundles'][$row->bundle]['layouts'][$row->view_mode] = $layout;
  305. }
  306. $revision = array(
  307. 'label' => 'Revision',
  308. 'custom settings' => FALSE,
  309. );
  310. $entity_info['node']['view modes']['revision'] = $revision;
  311. }
  312. /**
  313. * Implements hook_ds_layout_info().
  314. */
  315. function _ds_ds_layout_info() {
  316. $path = drupal_get_path('module', 'ds');
  317. $layouts = array(
  318. 'ds_1col' => array(
  319. 'label' => t('One column'),
  320. 'path' => $path . '/layouts/ds_1col',
  321. 'regions' => array(
  322. 'ds_content' => t('Content'),
  323. ),
  324. 'image' => TRUE,
  325. ),
  326. 'ds_1col_wrapper' => array(
  327. 'label' => t('One column + wrapper'),
  328. 'path' => $path . '/layouts/ds_1col_wrapper',
  329. 'regions' => array(
  330. 'ds_content' => t('Content'),
  331. ),
  332. 'image' => TRUE,
  333. ),
  334. 'ds_2col' => array(
  335. 'label' => t('Two column'),
  336. 'path' => $path . '/layouts/ds_2col',
  337. 'regions' => array(
  338. 'left' => t('Left'),
  339. 'right' => t('Right')
  340. ),
  341. 'css' => TRUE,
  342. 'image' => TRUE,
  343. ),
  344. 'ds_2col_fluid' => array(
  345. 'label' => t('Fluid two column'),
  346. 'path' => $path . '/layouts/ds_2col_fluid',
  347. 'regions' => array(
  348. 'left' => t('Left'),
  349. 'right' => t('Right')
  350. ),
  351. 'css' => TRUE,
  352. 'image' => TRUE,
  353. ),
  354. 'ds_2col_stacked' => array(
  355. 'label' => t('Two column stacked'),
  356. 'path' => $path . '/layouts/ds_2col_stacked',
  357. 'regions' => array(
  358. 'header' => t('Header'),
  359. 'left' => t('Left'),
  360. 'right' => t('Right'),
  361. 'footer' => t('Footer'),
  362. ),
  363. 'css' => TRUE,
  364. 'image' => TRUE,
  365. ),
  366. 'ds_2col_stacked_fluid' => array(
  367. 'label' => t('Fluid two column stacked'),
  368. 'path' => $path . '/layouts/ds_2col_stacked_fluid',
  369. 'regions' => array(
  370. 'header' => t('Header'),
  371. 'left' => t('Left'),
  372. 'right' => t('Right'),
  373. 'footer' => t('Footer'),
  374. ),
  375. 'css' => TRUE,
  376. 'image' => TRUE,
  377. ),
  378. 'ds_3col' => array(
  379. 'label' => t('Three column - 25/50/25'),
  380. 'path' => $path . '/layouts/ds_3col',
  381. 'regions' => array(
  382. 'left' => t('Left'),
  383. 'middle' => t('Middle'),
  384. 'right' => t('Right'),
  385. ),
  386. 'css' => TRUE,
  387. 'image' => TRUE,
  388. ),
  389. 'ds_3col_equal_width' => array(
  390. 'label' => t('Three column - equal width'),
  391. 'path' => $path . '/layouts/ds_3col_equal_width',
  392. 'regions' => array(
  393. 'left' => t('Left'),
  394. 'middle' => t('Middle'),
  395. 'right' => t('Right'),
  396. ),
  397. 'css' => TRUE,
  398. 'image' => TRUE,
  399. ),
  400. 'ds_3col_stacked' => array(
  401. 'label' => t('Three column stacked - 25/50/25'),
  402. 'path' => $path . '/layouts/ds_3col_stacked',
  403. 'regions' => array(
  404. 'header' => t('Header'),
  405. 'left' => t('Left'),
  406. 'middle' => t('Middle'),
  407. 'right' => t('Right'),
  408. 'footer' => t('Footer'),
  409. ),
  410. 'css' => TRUE,
  411. 'image' => TRUE,
  412. ),
  413. 'ds_3col_stacked_fluid' => array(
  414. 'label' => t('Fluid three column stacked - 25/50/25'),
  415. 'path' => $path . '/layouts/ds_3col_stacked_fluid',
  416. 'regions' => array(
  417. 'header' => t('Header'),
  418. 'left' => t('Left'),
  419. 'middle' => t('Middle'),
  420. 'right' => t('Right'),
  421. 'footer' => t('Footer'),
  422. ),
  423. 'css' => TRUE,
  424. 'image' => TRUE,
  425. ),
  426. 'ds_3col_stacked_equal_width' => array(
  427. 'label' => t('Three column stacked - equal width'),
  428. 'path' => $path . '/layouts/ds_3col_stacked_equal_width',
  429. 'regions' => array(
  430. 'header' => t('Header'),
  431. 'left' => t('Left'),
  432. 'middle' => t('Middle'),
  433. 'right' => t('Right'),
  434. 'footer' => t('Footer'),
  435. ),
  436. 'css' => TRUE,
  437. 'image' => TRUE,
  438. ),
  439. 'ds_4col' => array(
  440. 'label' => t('Four column - equal width'),
  441. 'path' => $path . '/layouts/ds_4col',
  442. 'regions' => array(
  443. 'first' => t('First'),
  444. 'second' => t('Second'),
  445. 'third' => t('Third'),
  446. 'fourth' => t('Fourth'),
  447. ),
  448. 'css' => TRUE,
  449. 'image' => TRUE,
  450. ),
  451. 'ds_reset' => array(
  452. 'label' => t('Reset'),
  453. 'path' => $path . '/layouts/ds_reset',
  454. 'regions' => array(
  455. 'ds_content' => t('Content'),
  456. ),
  457. 'image' => TRUE,
  458. ),
  459. );
  460. // Support for panels.
  461. if (module_exists('panels')) {
  462. ctools_include('plugins', 'panels');
  463. $panel_layouts = panels_get_layouts();
  464. foreach ($panel_layouts as $key => $layout) {
  465. // The easy ones.
  466. if (isset($layout['regions'])) {
  467. $layouts['panels-' . $key] = array(
  468. 'label' => $layout['title'],
  469. 'path' => $layout['path'],
  470. 'module' => 'panels',
  471. // We need the Panels plugin info array to correctly include the
  472. // layout and its CSS files later on.
  473. 'panels' => $layout,
  474. 'flexible' => FALSE,
  475. 'regions' => $layout['regions'],
  476. );
  477. if (!empty($layout['css'])) {
  478. $layouts['panels-' . $key]['css'] = TRUE;
  479. }
  480. }
  481. // Flexible panel layouts, ignore the default flexible.
  482. else {
  483. if ($layout['name'] != 'flexible') {
  484. $regions = panels_flexible_panels(array(), array(), $layout);
  485. $layouts['panels-' . $key] = array(
  486. 'label' => $layout['title'],
  487. 'path' => $layout['path'],
  488. 'module' => 'panels',
  489. 'panels' => $layout,
  490. 'flexible' => TRUE,
  491. 'regions' => $regions,
  492. );
  493. }
  494. }
  495. }
  496. }
  497. // Get layouts defined in the active theme and base theme (if applicable).
  498. $themes = list_themes();
  499. $theme = variable_get('theme_default', 'bartik');
  500. $base_theme = array();
  501. $ancestor = $theme;
  502. while ($ancestor && isset($themes[$ancestor]->base_theme)) {
  503. $ancestor = $themes[$ancestor]->base_theme;
  504. $base_theme[] = $themes[$ancestor];
  505. }
  506. foreach (array_reverse($base_theme) as $base) {
  507. _ds_layouts_scan_theme($base->name, $layouts);
  508. }
  509. _ds_layouts_scan_theme($theme, $layouts);
  510. return $layouts;
  511. }
  512. function _ds_layouts_scan_theme($theme, &$layouts) {
  513. $theme_layouts = file_scan_directory(drupal_get_path('theme', $theme) . '/ds_layouts', '/inc$/');
  514. foreach ($theme_layouts as $file => $values) {
  515. include_once(DRUPAL_ROOT . '/' . $file);
  516. $function = 'ds_' . $values->name;
  517. $layouts[$values->name] = $function();
  518. $layouts[$values->name]['path'] = str_replace('/' . $values->filename, '', $file);
  519. }
  520. }
  521. /**
  522. * Implements hook_menu_alter().
  523. */
  524. function _ds_menu_alter(&$items) {
  525. // Do not conflict with the revisioning module.
  526. if (module_exists('revisioning')) {
  527. $items['node/%node/revisions/%vid/view']['page callback'] = 'ds_revision_node_show';
  528. $items['node/%node/revisions/%vid/view']['file'] = 'includes/ds.revision.inc';
  529. $items['node/%node/revisions/%vid/view']['file path'] = drupal_get_path('module', 'ds');
  530. }
  531. else {
  532. $items['node/%node/revisions/%/view']['page callback'] = 'ds_revision_node_show';
  533. $items['node/%node/revisions/%/view']['file'] = 'includes/ds.revision.inc';
  534. $items['node/%node/revisions/%/view']['file path'] = drupal_get_path('module', 'ds');
  535. }
  536. }