plugins-admin.inc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. /**
  3. * @file
  4. * Contains generic plugin administration functions.
  5. *
  6. * CTools includes the ability to (relatively) easily provide wizard based
  7. * configuration for plugins, meaning plugins that need configuration can
  8. * automatically allow multi-step forms.
  9. *
  10. * Implementing this
  11. */
  12. /**
  13. * Get a plugin configuration form.
  14. *
  15. * The $form_info and $form_state need to be preconfigured with data you'll need
  16. * such as whether or not you're using ajax, or the modal. $form_info will need
  17. * your next/submit callbacks so that you can cache your data appropriately.
  18. *
  19. * @param array $form_info
  20. * This form_info *must* contain at least the path. next and finish callbacks
  21. * are advisable but not necessary if using wizard's auto caching. Setting
  22. * a cache mechanism is advisable. If not using auto caching, next and finish
  23. * callbacks will be necessary.
  24. *
  25. * Also be sure to set up things such as AJAX settings and any temporary
  26. * data you will need. Simply setting 'modal' => TRUE and
  27. * 'modal return' => TRUE should make this system work well in the modal.
  28. *
  29. * In addition to standard wizard fields, this supports one extra field:
  30. * - 'default form': A callback to a 'wrapper' that will be applied to either
  31. * the first or a marked form. This is useful for adding global features that
  32. * are applicable to all instances of a plugin, such as identifiers, or
  33. * contexts, or the like.
  34. *
  35. * @param array &$form_state
  36. * This is a standard form state array. This system imposes some requirements
  37. * on what will be in the form state:
  38. *
  39. * - 'plugin': The plugin definition being edited.
  40. * - 'conf': The configuration that is being edited, presumed to be an array.
  41. * Ultimately at the end, this is where the modified config will be
  42. * found.
  43. * - 'op': The operation, either 'add' or 'edit'. This is used to derive form
  44. * names and can also be used to derive default values from the plugin.
  45. * - 'step': The current step. May be null if it is the 'first' step, but
  46. * generally needs to be defined in the path.
  47. *
  48. * @param string $default_form
  49. * An optional default form that can be added.
  50. *
  51. * @return
  52. * If this function returns false, no form exists.
  53. */
  54. function ctools_plugin_configure_form($form_info, &$form_state) {
  55. // Turn the forms defined in the plugin into the format the wizard needs.
  56. _ctools_plugin_configure_create_form_info($form_info, $form_state['plugin'], $form_state['op']);
  57. if (empty($form_info['order'])) {
  58. return FALSE;
  59. }
  60. ctools_include('wizard');
  61. return ctools_wizard_multistep_form($form_info, $form_state['step'], $form_state);
  62. }
  63. function _ctools_plugin_configure_create_form_info(&$form_info, $plugin_definition, $op) {
  64. // Provide a few extra defaults.
  65. $form_info += array(
  66. 'id' => 'ctools_plugin_configure_form',
  67. 'show back' => TRUE,
  68. );
  69. $add_form = isset($form_info['add form name']) ? $form_info['add form name'] : 'add form';
  70. $edit_form = isset($form_info['edit form name']) ? $form_info['edit form name'] : 'edit form';
  71. // Figure out what the forms should actually be. Since they can be specified
  72. // in a couple of different ways (in order to support simple declarations for
  73. // the minimal forms but more complex declarations for powerful wizards).
  74. if ($op == 'add') {
  75. if (!empty($plugin_definition[$add_form])) {
  76. $info = $plugin_definition[$add_form];
  77. }
  78. }
  79. if (!isset($info) || $op == 'edit') {
  80. // Use the edit form for the add form if add form was completely left off.
  81. if (!empty($plugin_definition[$edit_form])) {
  82. $info = $plugin_definition[$edit_form];
  83. }
  84. }
  85. // If there is a default form wrapper, but no form is supplied,
  86. // use the wrapper as the form.
  87. if (empty($info) && !empty($form_info['default form'])) {
  88. $info = $form_info['default form'];
  89. }
  90. // @todo we may want to make these titles more settable?
  91. if (is_string($info)) {
  92. if (empty($plugin_definition['title'])) {
  93. $title = t('Configure');
  94. }
  95. else if ($op == 'add') {
  96. $title = t('Configure new !plugin_title', array('!plugin_title' => $plugin_definition['title']));
  97. }
  98. else {
  99. $title = t('Configure !plugin_title', array('!plugin_title' => $plugin_definition['title']));
  100. }
  101. if (empty($form_info['order'])) {
  102. $form_info['order'] = array();
  103. }
  104. $form_info['order']['form'] = $title;
  105. if (empty($form_info['forms'])) {
  106. $form_info['forms'] = array();
  107. }
  108. $form_info['forms']['form'] = array(
  109. 'title' => $title,
  110. 'form id' => $info,
  111. );
  112. // Add the default form if one is specified.
  113. if (!empty($form_info['default form']) && $form_info['forms']['form']['form id'] != $form_info['default form']) {
  114. $form_info['forms']['form']['wrapper'] = $form_info['default form'];
  115. }
  116. // If no submit is supplied, supply the default submit which will do the
  117. // most obvious task.
  118. if (!function_exists($form_info['forms']['form']['form id'] . '_submit')) {
  119. // Store the original wrapper so we can chain it.
  120. if (!empty($form_info['forms']['form']['wrapper'])) {
  121. $form_info['forms']['form']['original wrapper'] = $form_info['forms']['form']['wrapper'];
  122. }
  123. $form_info['forms']['form']['wrapper'] = 'ctools_plugins_default_form_wrapper';
  124. }
  125. }
  126. else if (is_array($info)) {
  127. if (empty($form_info['order'])) {
  128. $form_info['order'] = array();
  129. }
  130. if (empty($form_info['forms'])) {
  131. $form_info['forms'] = array();
  132. }
  133. $count = 0;
  134. $base = 'step';
  135. $wrapper = NULL;
  136. foreach ($info as $form_id => $title) {
  137. $step = $base . ++$count;
  138. if (empty($wrapper)) {
  139. $wrapper = $step;
  140. }
  141. if (is_array($title)) {
  142. if (!empty($title['default'])) {
  143. $wrapper = $step;
  144. }
  145. $title = $title['title'];
  146. }
  147. $form_info['order'][$step] = $title;
  148. $form_info['forms'][$step] = array(
  149. 'title' => $title,
  150. 'form id' => $form_id,
  151. );
  152. }
  153. if ($wrapper && !empty($form_info['default form'])) {
  154. $form_info['forms'][$wrapper]['wrapper'] = $form_info['default form'];
  155. }
  156. }
  157. }
  158. /**
  159. * A wrapper to provide a default submit so that plugins don't have to duplicate
  160. * a whole bunch of code to do what most of them want to do anyway.
  161. */
  162. function ctools_plugins_default_form_wrapper($form, &$form_state) {
  163. $form_info = &$form_state['form_info'];
  164. $info = $form_info['forms'][$form_state['step']];
  165. if (isset($info['original wrapper']) && function_exists($info['original wrapper'])) {
  166. $form = $info['original wrapper']($form, $form_state);
  167. }
  168. if (isset($form['buttons']['next'])) {
  169. if (empty($form['buttons']['next']['#submit'])) {
  170. $form['buttons']['next']['#submit'] = $form['#submit'];
  171. }
  172. $form['buttons']['next']['#submit'][] = 'ctools_plugins_default_form_wrapper_submit';
  173. }
  174. if (isset($form['buttons']['return'])) {
  175. if (empty($form['buttons']['return']['#submit'])) {
  176. $form['buttons']['return']['#submit'] = $form['#submit'];
  177. }
  178. $form['buttons']['return']['#submit'][] = 'ctools_plugins_default_form_wrapper_submit';
  179. }
  180. return $form;
  181. }
  182. /**
  183. * Provide a default storage mechanism.
  184. */
  185. function ctools_plugins_default_form_wrapper_submit(&$form, &$form_state) {
  186. foreach (array_keys($form_state['plugin']['defaults']) as $key) {
  187. if (isset($form_state['values'][$key])) {
  188. $form_state['conf'][$key] = $form_state['values'][$key];
  189. }
  190. }
  191. }