action.class.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php
  2. /**
  3. * @file
  4. * Defines the class for core actions.
  5. * Belongs to the "action" operation type plugin.
  6. */
  7. class ViewsBulkOperationsAction extends ViewsBulkOperationsBaseOperation {
  8. /**
  9. * Contains the options provided by the user in the configuration form.
  10. *
  11. * @var array
  12. */
  13. public $formOptions = array();
  14. /**
  15. * Returns the access bitmask for the operation, used for entity access checks.
  16. */
  17. public function getAccessMask() {
  18. // Assume edit by default.
  19. if (empty($this->operationInfo['behavior'])) {
  20. $this->operationInfo['behavior'] = array('changes_property');
  21. }
  22. $mask = 0;
  23. if (in_array('views_property', $this->operationInfo['behavior'])) {
  24. $mask |= VBO_ACCESS_OP_VIEW;
  25. }
  26. if (in_array('changes_property', $this->operationInfo['behavior'])) {
  27. $mask |= VBO_ACCESS_OP_UPDATE;
  28. }
  29. if (in_array('creates_property', $this->operationInfo['behavior'])) {
  30. $mask |= VBO_ACCESS_OP_CREATE;
  31. }
  32. if (in_array('deletes_property', $this->operationInfo['behavior'])) {
  33. $mask |= VBO_ACCESS_OP_DELETE;
  34. }
  35. return $mask;
  36. }
  37. /**
  38. * Returns whether the provided account has access to execute the operation.
  39. *
  40. * @param $account
  41. */
  42. public function access($account) {
  43. // Use actions_permissions if enabled.
  44. if (module_exists('actions_permissions')) {
  45. $perm = actions_permissions_get_perm($this->operationInfo['label'], $this->operationInfo['key']);
  46. if (!user_access($perm, $account)) {
  47. return FALSE;
  48. }
  49. }
  50. // Check against additional permissions.
  51. if (!empty($this->operationInfo['permissions'])) {
  52. foreach ($this->operationInfo['permissions'] as $perm) {
  53. if (!user_access($perm, $account)) {
  54. return FALSE;
  55. }
  56. }
  57. }
  58. // Access granted.
  59. return TRUE;
  60. }
  61. /**
  62. * Returns the configuration form for the operation.
  63. * Only called if the operation is declared as configurable.
  64. *
  65. * @param $form
  66. * The views form.
  67. * @param $form_state
  68. * An array containing the current state of the form.
  69. * @param $context
  70. * An array of related data provided by the caller.
  71. */
  72. public function form($form, &$form_state, array $context) {
  73. // Some modules (including this one) place their action callbacks
  74. // into separate files. At this point those files might no longer be
  75. // included due to an #ajax rebuild, so we call actions_list() to trigger
  76. // inclusion. The same thing is done by actions_do() on execute.
  77. actions_list();
  78. $context['settings'] = $this->getAdminOption('settings', array());
  79. $form_callback = $this->operationInfo['callback'] . '_form';
  80. return $form_callback($context, $form_state);
  81. }
  82. /**
  83. * Validates the configuration form.
  84. * Only called if the operation is declared as configurable.
  85. *
  86. * @param $form
  87. * The views form.
  88. * @param $form_state
  89. * An array containing the current state of the form.
  90. */
  91. public function formValidate($form, &$form_state) {
  92. // Some modules (including this one) place their action callbacks
  93. // into separate files. At this point those files might no longer be
  94. // included due to a page reload, so we call actions_list() to trigger
  95. // inclusion. The same thing is done by actions_do() on execute.
  96. actions_list();
  97. $validation_callback = $this->operationInfo['callback'] . '_validate';
  98. if (function_exists($validation_callback)) {
  99. $validation_callback($form, $form_state);
  100. }
  101. }
  102. /**
  103. * Handles the submitted configuration form.
  104. * This is where the operation can transform and store the submitted data.
  105. * Only called if the operation is declared as configurable.
  106. *
  107. * @param $form
  108. * The views form.
  109. * @param $form_state
  110. * An array containing the current state of the form.
  111. */
  112. public function formSubmit($form, &$form_state) {
  113. // Some modules (including this one) place their action callbacks
  114. // into separate files. At this point those files might no longer be
  115. // included due to a page reload, so we call actions_list() to trigger
  116. // inclusion. The same thing is done by actions_do() on execute.
  117. actions_list();
  118. $submit_callback = $this->operationInfo['callback'] . '_submit';
  119. $this->formOptions = $submit_callback($form, $form_state);
  120. }
  121. /**
  122. * Returns the admin options form for the operation.
  123. *
  124. * The admin options form is embedded into the VBO field settings and used
  125. * to configure operation behavior. The options can later be fetched
  126. * through the getAdminOption() method.
  127. *
  128. * @param $dom_id
  129. * The dom path to the level where the admin options form is embedded.
  130. * Needed for #dependency.
  131. * @param $field_handler
  132. * The Views field handler object for the VBO field.
  133. */
  134. public function adminOptionsForm($dom_id, $field_handler) {
  135. $form = parent::adminOptionsForm($dom_id, $field_handler);
  136. $settings_form_callback = $this->operationInfo['callback'] . '_views_bulk_operations_form';
  137. if (function_exists($settings_form_callback)) {
  138. $settings = $this->getAdminOption('settings', array());
  139. $form['settings'] = array(
  140. '#type' => 'fieldset',
  141. '#title' => t('Operation settings'),
  142. '#collapsible' => TRUE,
  143. '#dependency' => array(
  144. $dom_id . '-selected' => array(1),
  145. ),
  146. );
  147. $settings_dom_id = $dom_id . '-settings';
  148. $form['settings'] += $settings_form_callback($settings, $this->entityType, $settings_dom_id);
  149. }
  150. return $form;
  151. }
  152. /**
  153. * Validates the admin options form.
  154. *
  155. * @param $form
  156. * The admin options form.
  157. * @param $form_state
  158. * An array containing the current state of the form. Note that this array
  159. * is constructed by the VBO views field handler, so it's not a real form
  160. * state, it contains only the 'values' key.
  161. * @param $error_element_base
  162. * The base to prepend to field names when using form_set_error().
  163. * Needed because the admin settings form is embedded into a bigger form.
  164. */
  165. public function adminOptionsFormValidate($form, &$form_state, $error_element_base) {
  166. parent::adminOptionsFormValidate($form, $form_state, $error_element_base);
  167. if (!empty($form['settings'])) {
  168. $settings_validation_callback = $this->operationInfo['callback'] . '_views_bulk_operations_form_validate';
  169. if (function_exists($settings_validation_callback)) {
  170. $fake_form = $form['settings'];
  171. $fake_form_state = array('values' => &$form_state['values']['settings']);
  172. $error_element_base .= 'settings][';
  173. $settings_validation_callback($fake_form, $fake_form_state, $error_element_base);
  174. }
  175. }
  176. }
  177. /**
  178. * Handles the submitted admin options form.
  179. * Note that there is no need to handle saving the options, that is done
  180. * by the VBO views field handler, which also injects the options into the
  181. * operation object upon instantiation.
  182. *
  183. * @param $form
  184. * The admin options form.
  185. * @param $form_state
  186. * An array containing the current state of the form. Note that this array
  187. * is constructed by the VBO views field handler, so it's not a real form
  188. * state, it contains only the 'values' key.
  189. */
  190. public function adminOptionsFormSubmit($form, &$form_state) {
  191. parent::adminOptionsFormSubmit($form, $form_state);
  192. if (!empty($form['settings'])) {
  193. $settings_submit_callback = $this->operationInfo['callback'] . '_views_bulk_operations_form_submit';
  194. if (function_exists($settings_submit_callback)) {
  195. $fake_form = $form['settings'];
  196. $fake_form_state = array('values' => &$form_state['values']['settings']);
  197. $settings_submit_callback($form, $form_state);
  198. }
  199. }
  200. }
  201. /**
  202. * Returns whether the operation needs the full selected views rows to be
  203. * passed to execute() as a part of $context.
  204. */
  205. public function needsRows() {
  206. return !empty($this->operationInfo['pass rows']);
  207. }
  208. /**
  209. * Executes the selected operation on the provided data.
  210. *
  211. * @param $data
  212. * The data to to operate on. An entity or an array of entities.
  213. * @param $context
  214. * An array of related data (selected views rows, etc).
  215. */
  216. public function execute($data, array $context) {
  217. $context['entity_type'] = $this->entityType;
  218. $context['settings'] = $this->getAdminOption('settings', array());
  219. $context += $this->formOptions;
  220. $context += $this->operationInfo['parameters'];
  221. // Actions provided by the Drupal system module require the entity to be
  222. // present in $context, keyed by entity type.
  223. if (is_object($data)) {
  224. $context[$this->entityType] = $data;
  225. }
  226. actions_do($this->operationInfo['callback'], $data, $context);
  227. // The action might need to have its entities saved after execution.
  228. if (in_array('changes_property', $this->operationInfo['behavior'])) {
  229. $data = is_array($data) ? $data : array($data);
  230. foreach ($data as $entity) {
  231. entity_save($this->entityType, $entity);
  232. }
  233. }
  234. }
  235. }