context_layouts_reaction_block.inc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <?php
  2. class context_layouts_reaction_block extends context_reaction_block {
  3. /**
  4. * Override of is_enabled_region().
  5. * Check that there is an active layout and it supports the given region.
  6. */
  7. protected function is_enabled_region($region) {
  8. $layout = $this->get_active_layout();
  9. if ($layout && isset($layout['regions']) && is_array($layout['regions'])) {
  10. return in_array($region, $layout['regions'], TRUE) && parent::is_enabled_region($region);
  11. }
  12. return parent::is_enabled_region($region);
  13. }
  14. /**
  15. * Retrieve the first layout specified found by any active contexts.
  16. */
  17. function get_active_layout($info = TRUE) {
  18. $contexts = $this->get_contexts();
  19. $layouts = context_layouts_get_layouts();
  20. if (!empty($contexts) && !empty($layouts)) {
  21. foreach ($contexts as $context) {
  22. $values = $this->fetch_from_context($context);
  23. if (isset($values['layout']) && isset($layouts[$values['layout']])) {
  24. return $info ? $layouts[$values['layout']] : $values['layout'];
  25. }
  26. }
  27. }
  28. // Fallback to default layout if provided.
  29. if (isset($layouts['default'])) {
  30. return $info ? $layouts['default'] : 'default';
  31. }
  32. return FALSE;
  33. }
  34. /**
  35. * Add the layout template to page vars.
  36. */
  37. function add_layout_template(&$vars) {
  38. if ($layout = $this->get_active_layout()) {
  39. if (!empty($layout['template'])) {
  40. global $theme;
  41. $vars['theme_hook_suggestion'] = "page__context_layouts_{$theme}_{$layout['layout']}";
  42. }
  43. }
  44. }
  45. /**
  46. * Add the layout stylesheet to the CSS.
  47. */
  48. function add_layout_stylesheet() {
  49. if ($layout = $this->get_active_layout()) {
  50. if (!empty($layout['stylesheet'])) {
  51. drupal_add_css(drupal_get_path('theme', $layout['theme']) . '/' . $layout['stylesheet']);
  52. }
  53. }
  54. }
  55. /**
  56. * Override of editor form.
  57. */
  58. function editor_form($context) {
  59. drupal_add_css(drupal_get_path('module', 'context_layouts') . '/plugins/context_layouts_reaction_block.css');
  60. $form = parent::editor_form($context);
  61. if ($layouts = $this->get_layout_options()) {
  62. $options = $this->fetch_from_context($context);
  63. $form['layout'] = array(
  64. // #tree *must* be true for our values to be nested correctly.
  65. '#tree' => TRUE,
  66. '#prefix' => '<div class="context-editor-block-layouts">',
  67. '#suffix' => '</div>',
  68. '#weight' => -100,
  69. 'layout' => array(
  70. '#title' => t('Layout'),
  71. '#options' => $layouts,
  72. '#type' => 'select',
  73. '#weight' => -100,
  74. '#default_value' => isset($options['layout']) ? $options['layout'] : NULL,
  75. '#required' => FALSE,
  76. '#empty_value' => 0,
  77. '#empty_option' => '- ' . t('Site default') . ' -',
  78. ),
  79. 'update' => array(
  80. '#value' => t('Change layout'),
  81. '#type' => 'submit',
  82. ),
  83. );
  84. }
  85. return $form;
  86. }
  87. /**
  88. * Override of editor form submit.
  89. */
  90. function editor_form_submit(&$context, $values) {
  91. // Someone has changed the layout, assume that the block values are not actually usable here.
  92. if (isset($context->reactions['block']['layout']) && $context->reactions['block']['layout'] != $values['layout']['layout']) {
  93. $options = $context->reactions['block'];
  94. }
  95. else {
  96. $options = parent::editor_form_submit($context, $values);
  97. }
  98. if (!empty($values['layout']['layout'])) {
  99. $options['layout'] = $values['layout']['layout'];
  100. }
  101. else {
  102. unset($options['layout']);
  103. }
  104. return $options;
  105. }
  106. /**
  107. * Override of options form.
  108. */
  109. function options_form($context) {
  110. $form = parent::options_form($context);
  111. $options = $this->fetch_from_context($context);
  112. // Only alter the options form if the theme provides layouts.
  113. $theme_key = variable_get('theme_default', 'garland');
  114. $layouts = $this->get_layout_options();
  115. if (!empty($layouts)) {
  116. $form['layout'] = array(
  117. '#title' => t('Layout'),
  118. '#description' => t('Choose one of the layouts provided by the default theme.'),
  119. '#options' => $layouts,
  120. '#type' => 'select',
  121. '#weight' => -100,
  122. '#default_value' => !empty($options['layout']) ? $options['layout'] : NULL,
  123. '#attributes' => array('class' => array('context-blockform-layout')),
  124. '#required' => FALSE,
  125. '#empty_value' => 0,
  126. '#empty_option' => '- ' . t('Site default') . ' -',
  127. );
  128. // Add js.
  129. // @TODO: Move this to a theme function or somewhere that will get called even
  130. // if the form is using a cached version of itself (e.g. when validate fails).
  131. drupal_add_js(drupal_get_path('module', 'context_layouts') . '/plugins/context_layouts_reaction_block.js');
  132. drupal_add_js(array('contextLayouts' => array('layouts' => $this->get_layout_regions())), 'setting');
  133. }
  134. return $form;
  135. }
  136. /**
  137. * Override of submit handler.
  138. */
  139. function options_form_submit($values) {
  140. $options = parent::options_form_submit($values);
  141. // Only alter the options form if the theme provides layouts.
  142. $theme_key = variable_get('theme_default', 'garland');
  143. $layouts = context_layouts_get_layouts($theme_key);
  144. // Check that this is a valid layout.
  145. if (!empty($values['layout']) && isset($layouts[$values['layout']])) {
  146. $layout = $values['layout'];
  147. $options['layout'] = $layout;
  148. // Remove blocks that don't belong to regions in this layout.
  149. if (isset($layouts[$layout]['regions'])) {
  150. foreach ($options['blocks'] as $bid => $block) {
  151. if (!in_array($block['region'], $layouts[$layout]['regions'])) {
  152. unset($options['blocks'][$bid]);
  153. }
  154. }
  155. }
  156. }
  157. return $options;
  158. }
  159. /**
  160. * Get layout options for the given theme.
  161. */
  162. protected function get_layout_options($theme_key = NULL) {
  163. $theme_key = !isset($theme_key) ? variable_get('theme_default', 'garland') : $theme_key;
  164. $layouts = context_layouts_get_layouts($theme_key);
  165. $layout_options = array();
  166. if (!empty($layouts)) {
  167. foreach ($layouts as $layout => $info) {
  168. $layout_options[$layout] = isset($info['name']) ? $info['name'] : $layout_options;
  169. }
  170. }
  171. return $layout_options;
  172. }
  173. /**
  174. * Get a layout to region map for the given theme.
  175. */
  176. protected function get_layout_regions($theme_key = NULL) {
  177. $theme_key = !isset($theme_key) ? variable_get('theme_default', 'garland') : $theme_key;
  178. $layouts = context_layouts_get_layouts($theme_key);
  179. if (!empty($layouts)) {
  180. $layout_regions = array();
  181. foreach ($layouts as $layout => $info) {
  182. $layout_regions[$layout] = is_array($info['regions']) ? $info['regions'] : array();
  183. }
  184. }
  185. return $layout_regions;
  186. }
  187. }