uc_ajax_admin.module 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. /**
  3. * @file
  4. * Configures Ajax behaviours on the Ubercart checkout page.
  5. */
  6. /**
  7. * Implements hook_help().
  8. */
  9. function uc_ajax_admin_help($path, $arg) {
  10. if ($path == 'admin/store/settings/checkout/ajax') {
  11. $output = '<p>' . t('Use this page to configure Ajax behaviors on the form. The table below associates triggering form input elements with panes. The contents of each associated pane will be refreshed whenever the customer clicks on or changes the triggering form element. For example, you can cause the available payment methods to be refreshed when the customer changes their billing zone.') . '</p>';
  12. $output .= '<p>' . t("Note that the triggering elements you can choose are listed based on the form as it would be displayed to you right now. For example, if none of your shipping methods apply to the current cart contents, you won't see the shipping quote selection element. If you don't see the form element you wish to use as a trigger, try adding some products to the shopping cart or otherwise simulating the customer experience, and verify that those elements are present on the form itself.") . '</p>';
  13. return $output;
  14. }
  15. }
  16. /**
  17. * Implements hook_menu().
  18. */
  19. function uc_ajax_admin_menu() {
  20. $items = array();
  21. $items['admin/store/settings/checkout/ajax'] = array(
  22. 'title' => 'Ajax',
  23. 'description' => 'Administer ajax updates on checkout form.',
  24. 'page callback' => 'drupal_get_form',
  25. 'page arguments' => array('uc_ajax_admin_form', 'checkout'),
  26. 'access arguments' => array('administer store'),
  27. 'type' => MENU_LOCAL_TASK,
  28. 'weight' => 3,
  29. );
  30. return $items;
  31. }
  32. /**
  33. * Administration form for uc_ajax.
  34. *
  35. * @param $target_form
  36. * The form for which ajax behaviors are to be administered. Currently only
  37. * 'checkout' is supported.
  38. */
  39. function uc_ajax_admin_form($form, &$form_state, $target_form = 'checkout') {
  40. module_load_include('inc', 'uc_store', 'includes/uc_ajax_attach');
  41. switch ($target_form) {
  42. case 'checkout':
  43. $triggers = _uc_ajax_admin_checkout_trigger_options(_uc_ajax_admin_build_checkout_form());
  44. $panes = _uc_checkout_pane_list();
  45. $wrappers = array();
  46. foreach ($panes as $id => $pane) {
  47. $wrappers["$id-pane"] = _uc_checkout_pane_data($id, 'title');
  48. }
  49. break;
  50. default:
  51. drupal_not_found();
  52. }
  53. $form['#uc_ajax_target'] = $target_form;
  54. $form['#uc_ajax_config'] = variable_get('uc_ajax_' . $target_form, _uc_ajax_defaults($target_form));
  55. $form['table'] = tapir_get_table('uc_ajax_admin_table', $triggers, $wrappers, $form['#uc_ajax_config']);
  56. $form['actions'] = array(
  57. '#type' => 'actions',
  58. 'submit' => array(
  59. '#type' => 'submit',
  60. '#value' => t('Submit'),
  61. ),
  62. );
  63. return $form;
  64. }
  65. /**
  66. * Submit handler for the uc_ajax_admin form.
  67. */
  68. function uc_ajax_admin_form_submit($form, &$form_state) {
  69. $config = $form['#uc_ajax_config'];
  70. foreach ($form_state['values']['table'] as $index => $entry) {
  71. $key = $entry['key'];
  72. if ($index === '_new') {
  73. if (!empty($key) && !empty($entry['panes'])) {
  74. $config[$key] = $entry['panes'];
  75. }
  76. }
  77. elseif ($entry['remove'] || empty($entry['panes'])) {
  78. unset($config[$key]);
  79. }
  80. else {
  81. $config[$key] = $entry['panes'];
  82. }
  83. }
  84. variable_set('uc_ajax_' . $form['#uc_ajax_target'], $config);
  85. drupal_set_message(t('Your changes have been saved.'));
  86. }
  87. /**
  88. * TAPIr table callback for the uc_ajax administrative form.
  89. *
  90. * @param $trigger_options
  91. * The select options for triggering elements.
  92. * @param $wrapper_options
  93. * The select options for wrappers.
  94. * @param $config
  95. * The existing configuration.
  96. */
  97. function uc_ajax_admin_table($trigger_options, $wrapper_options, $config) {
  98. $rows = array();
  99. foreach ($config as $key => $panes) {
  100. list(, $pane) = explode('][', $key);
  101. $rows[] = array(
  102. 'key' => array(
  103. '#type' => 'hidden',
  104. '#value' => $key,
  105. '#suffix' => empty($trigger_options[ucfirst($pane)][$key]) ? $key : ucfirst($pane) . ': ' . $trigger_options[ucfirst($pane)][$key],
  106. ),
  107. 'panes' => array(
  108. '#type' => 'select',
  109. '#options' => $wrapper_options,
  110. '#default_value' => $panes,
  111. '#multiple' => TRUE,
  112. ),
  113. 'remove' => array(
  114. '#type' => 'checkbox',
  115. '#default_value' => FALSE,
  116. ),
  117. );
  118. }
  119. $rows['_new'] = array(
  120. 'key' => array(
  121. '#type' => 'select',
  122. '#options' => array(0 => t('--Add a new element--')) + $trigger_options,
  123. ),
  124. 'panes' => array(
  125. '#type' => 'select',
  126. '#options' => $wrapper_options,
  127. '#multiple' => TRUE,
  128. ),
  129. 'remove' => array(
  130. '#type' => 'hidden',
  131. '#value' => 0,
  132. ),
  133. );
  134. $table = array(
  135. '#type' => 'tapir_table',
  136. '#tree' => TRUE,
  137. '#columns' => array(
  138. 'remove' => array(
  139. 'cell' => t('Remove'),
  140. 'weight' => 3,
  141. ),
  142. 'key' => array(
  143. 'cell' => t('Triggering form element'),
  144. 'weight' => 1,
  145. ),
  146. 'panes' => array(
  147. 'cell' => t('Panes to update'),
  148. 'weight' => 2,
  149. ),
  150. ),
  151. ) + $rows;
  152. return $table;
  153. }
  154. /**
  155. * Recursively builds a list of all form elements which are suitable triggers
  156. * for ajax updates.
  157. *
  158. * @param $element
  159. * The element to check.
  160. * @param $list
  161. * The list being built. When complete will be an array of the form
  162. * 'element_name' => 'Element title'
  163. * where 'element_name' is the name of the element as would be specified for
  164. * form_set_error(), and 'Element title' is a best guess at the human readable
  165. * name of the element.
  166. */
  167. function _uc_ajax_admin_list_triggers($element, &$list) {
  168. if (!empty($element['#input']) && !in_array($element['#type'], array('hidden', 'uc_address'))) {
  169. $key = implode('][', $element['#array_parents']);
  170. switch ($element['#type']) {
  171. case 'button': case 'submit':
  172. $title = empty($element['#value']) ? $key : $element['#value'];
  173. break;
  174. default:
  175. $title = empty($element['#title']) ? $key : $element['#title'];
  176. }
  177. $list[$key] = $title;
  178. }
  179. if (empty($element['#type']) || !in_array($element['#type'], array('radios', 'checkboxes'))) {
  180. foreach (element_children($element) as $child) {
  181. _uc_ajax_admin_list_triggers($element[$child], $list);
  182. }
  183. }
  184. }
  185. /**
  186. * Builds a hierarchical list of possible ajax triggers for the checkout form.
  187. *
  188. * @param $form
  189. * The fully processed checkout form to search for triggers.
  190. *
  191. * @return
  192. * An hierarchical array of select options, categorized by pane.
  193. */
  194. function _uc_ajax_admin_checkout_trigger_options($form) {
  195. $list = array();
  196. foreach (element_children($form['panes']) as $name) {
  197. $group = ucfirst($name);
  198. $list[$group] = array();
  199. _uc_ajax_admin_list_triggers($form['panes'][$name], $list[$group]);
  200. if (empty($list[$group])) {
  201. unset($list[$group]);
  202. }
  203. }
  204. return $list;
  205. }
  206. /**
  207. * Builds the checkout form, using the cart order if it exists, or a default
  208. * shippable order if not.
  209. */
  210. function _uc_ajax_admin_build_checkout_form() {
  211. module_load_include('inc', 'uc_cart', 'uc_cart.pages');
  212. $order = empty($_SESSION['cart_order']) ? FALSE : uc_order_load($_SESSION['cart_order']);
  213. if (!$order) {
  214. $order = new UcOrder();
  215. $order->products = array((object) array(
  216. 'cart_item_id' => 0,
  217. 'title' => 'fake',
  218. 'nid' => 0,
  219. 'qty' => 1,
  220. 'price' => 1,
  221. 'data' => array('shippable' => TRUE),
  222. 'model' => 0,
  223. 'weight' => 0,
  224. ));
  225. }
  226. return drupal_get_form('uc_cart_checkout_form', $order);
  227. }