Commit | Line | Data |
---|---|---|
7f254ad8 AE |
1 | <?php |
2 | ||
3 | /** | |
4 | * @file | |
5 | * Views Bulk Operations conditions and actions for Rules. | |
6 | */ | |
7 | ||
8 | /** | |
9 | * Implements hook_rules_condition_info(). | |
10 | */ | |
11 | function views_bulk_operations_rules_condition_info() { | |
12 | $conditions = array(); | |
13 | $conditions['views_bulk_operations_condition_result_count'] = array( | |
14 | 'label' => t('Check number of results returned by a VBO View'), | |
15 | 'parameter' => array( | |
16 | 'view' => array( | |
17 | 'type' => 'text', | |
18 | 'label' => t('View and display'), | |
19 | 'options list' => 'views_bulk_operations_views_list', | |
20 | 'description' => t('Select the VBO view and display you want to check'), | |
21 | 'restriction' => 'input', | |
22 | ), | |
23 | 'args' => array( | |
24 | 'type' => 'text', | |
25 | 'label' => t('Arguments'), | |
26 | 'description' => t('Any arguments to pass to the view, one per line. | |
27 | You may use token replacement patterns.'), | |
28 | 'optional' => TRUE, | |
29 | ), | |
30 | 'minimum' => array( | |
31 | 'type' => 'integer', | |
32 | 'label' => t('Minimum number of results'), | |
33 | 'description' => t('This condition returns TRUE if the view has at | |
34 | least the given number of results.'), | |
35 | ), | |
36 | ), | |
37 | 'group' => t('Views Bulk Operations'), | |
38 | ); | |
39 | ||
40 | return $conditions; | |
41 | } | |
42 | ||
43 | /** | |
44 | * Implements hook_rules_action_info(). | |
45 | */ | |
46 | function views_bulk_operations_rules_action_info() { | |
47 | $actions = array(); | |
48 | $actions['views_bulk_operations_action_load_list'] = array( | |
49 | 'label' => t('Load a list of entity objects from a VBO View.'), | |
50 | 'parameter' => array( | |
51 | 'view' => array( | |
52 | 'type' => 'text', | |
53 | 'label' => t('View and display'), | |
54 | 'options list' => 'views_bulk_operations_views_list', | |
55 | 'description' => t('Select the view and display you want to use to | |
56 | create a list.'), | |
57 | 'restriction' => 'input', | |
58 | ), | |
59 | 'args' => array( | |
60 | 'type' => 'text', | |
61 | 'label' => t('Arguments'), | |
62 | 'description' => t('Any arguments to pass to the view, one per line. | |
63 | You may use token replacement patterns.'), | |
64 | 'optional' => TRUE, | |
65 | ), | |
66 | ), | |
67 | 'provides' => array( | |
68 | 'entity_list' => array( | |
69 | 'type' => 'list<entity>', | |
70 | 'label' => t('A list of entities'), | |
71 | ), | |
72 | ), | |
73 | 'group' => t('Views Bulk Operations'), | |
74 | ); | |
75 | $actions['views_bulk_operations_action_load_id_list'] = array( | |
76 | 'label' => t('Load a list of entity ids from a VBO View.'), | |
77 | 'parameter' => array( | |
78 | 'view' => array( | |
79 | 'type' => 'text', | |
80 | 'label' => t('View and display'), | |
81 | 'options list' => 'views_bulk_operations_views_list', | |
82 | 'description' => t('Select the view and display you want to use to | |
83 | create a list.'), | |
84 | 'restriction' => 'input', | |
85 | ), | |
86 | 'args' => array( | |
87 | 'type' => 'text', | |
88 | 'label' => t('Arguments'), | |
89 | 'description' => t('Any arguments to pass to the view, one per line. | |
90 | You may use token replacement patterns.'), | |
91 | 'optional' => TRUE, | |
92 | ), | |
93 | ), | |
94 | 'provides' => array( | |
95 | 'entity_id_list' => array( | |
96 | 'type' => 'list<integer>', | |
97 | 'label' => t('A list of entity ids'), | |
98 | ), | |
99 | ), | |
100 | 'group' => t('Views Bulk Operations'), | |
101 | ); | |
102 | ||
103 | return $actions; | |
104 | } | |
105 | ||
106 | /** | |
107 | * Lists all available VBO Views and their displays. | |
108 | * Naturally, only the displays that contain a VBO field are listed. | |
109 | * | |
110 | * @return array | |
111 | * An array of all views and their displays on the form 'view|display', | |
112 | * formatted to be used as an select list. | |
113 | */ | |
114 | function views_bulk_operations_views_list() { | |
115 | $selectable_displays = array(); | |
116 | foreach (views_get_enabled_views() as $name => $base_view) { | |
117 | foreach ($base_view->display as $display_name => $display) { | |
118 | $view = $base_view->clone_view(); | |
119 | $view->build($display_name); | |
120 | $vbo = _views_bulk_operations_get_field($view); | |
121 | if ($vbo) { | |
122 | $selectable_displays[$view->name . '|' . $display_name] = check_plain($view->human_name) . ' | ' . check_plain($display->display_title); | |
123 | } | |
124 | } | |
125 | } | |
126 | return $selectable_displays; | |
127 | } | |
128 | ||
129 | /** | |
130 | * The 'views_bulk_operations_condition_result_count' condition. | |
131 | * | |
132 | * @param $view | |
133 | * A string in the format "$view_name|$display_name". | |
134 | * @param $args | |
135 | * Arguments that should be passed to the View. | |
136 | * @param $minimum | |
137 | * An integer representing the minimum number of results that satisfies the | |
138 | * condition. | |
139 | * | |
140 | * @return | |
141 | * TRUE if the view has more than $minimum results, FALSE otherwise. | |
142 | */ | |
143 | function views_bulk_operations_condition_result_count($view, $args, $minimum) { | |
144 | $vbo = _views_bulk_operations_rules_get_field($view, $args); | |
145 | return (count($vbo->view->result) >= $minimum); | |
146 | } | |
147 | ||
148 | /** | |
149 | * The 'views_bulk_operations_action_views_load_list' action. | |
150 | * | |
151 | * @param $view | |
152 | * A string in the format "$view_name|$display_name". | |
153 | * @param $args | |
154 | * Arguments that should be passed to the View. | |
155 | * @return array | |
156 | * Array containing the entity_list, an array of entity objects. | |
157 | * - array('entity_list' => array(...)) | |
158 | */ | |
159 | function views_bulk_operations_action_load_list($view, $args) { | |
160 | $vbo = _views_bulk_operations_rules_get_field($view, $args); | |
161 | ||
162 | // Get all entities, pass ids to the wrapper for lazy loading. | |
163 | $entity_type = $vbo->get_entity_type(); | |
164 | $entities = entity_metadata_wrapper("list<$entity_type>", array()); | |
165 | foreach ($vbo->view->result as $row_index => $result) { | |
166 | $entities[] = entity_metadata_wrapper($entity_type, $vbo->get_value($result)); | |
167 | } | |
168 | ||
169 | return array('entity_list' => $entities); | |
170 | } | |
171 | ||
172 | /** | |
173 | * The 'views_bulk_operations_action_views_load_id_list' action. | |
174 | * | |
175 | * @param $view | |
176 | * A string in the format "$view_name|$display_name". | |
177 | * @param $args | |
178 | * Arguments that should be passed to the View. | |
179 | * @return array | |
180 | * Array containing the entity_id_list, an Array of entity ids as integer | |
181 | * values. | |
182 | * - array('entity_list' => array(...)) | |
183 | */ | |
184 | function views_bulk_operations_action_load_id_list($view, $args) { | |
185 | $vbo = _views_bulk_operations_rules_get_field($view, $args); | |
186 | ||
187 | // Get all entity ids. | |
188 | $ids = array(); | |
189 | foreach ($vbo->view->result as $row_index => $result) { | |
190 | $ids[] = $vbo->get_value($result); | |
191 | } | |
192 | ||
193 | return array('entity_id_list' => $ids); | |
194 | } | |
195 | ||
196 | /** | |
197 | * Info alteration callback for the 'views_bulk_operations_action_views_load_list' action. | |
198 | * | |
199 | * The info hook specifies that the action returns a generic list of entities | |
200 | * (list<entity>). All actions that require entities of specific type can't | |
201 | * use such entities, so this alter hook specifies the exact entity type | |
202 | * after the action has been configured, allowing the view to be loaded | |
203 | * and its entity type extracted. | |
204 | */ | |
205 | function views_bulk_operations_action_load_list_info_alter(&$element_info, RulesAbstractPlugin $element) { | |
206 | // The action hasn't been configured yet, hence no view. Abort. | |
207 | if (empty($element->settings['view'])) { | |
208 | return; | |
209 | } | |
210 | ||
211 | $entity_type = _views_bulk_operations_rules_get_entity_type($element->settings['view']); | |
212 | if ($entity_type) { | |
213 | $element_info['provides']['entity_list']['type'] = "list<$entity_type>"; | |
214 | } | |
215 | } | |
216 | ||
217 | /** | |
218 | * Helper function that loads and builds (but doesn't execute) the specified view, | |
219 | * then determines the entity type on which the VBO field operates. | |
220 | * | |
221 | * @param $view_target | |
222 | * A string in the format "$view_name|$display_name". | |
223 | * | |
224 | * @return | |
225 | * The entity type on which the VBO field operates. | |
226 | */ | |
227 | function _views_bulk_operations_rules_get_entity_type($view_target) { | |
228 | $entity_types = &drupal_static(__FUNCTION__); | |
229 | ||
230 | if (!isset($entity_types[$view_target])) { | |
231 | $views_settings = explode('|', $view_target); | |
232 | if ($view = views_get_view($views_settings[0])) { | |
233 | $view->set_display($views_settings[1]); | |
234 | $view->build(); | |
235 | ||
236 | $vbo = _views_bulk_operations_get_field($view); | |
237 | } | |
238 | $entity_type = !empty($vbo) ? $vbo->get_entity_type() : ''; | |
239 | $entity_types[$view_target] = $entity_type; | |
240 | } | |
241 | ||
242 | return $entity_types[$view_target]; | |
243 | } | |
244 | ||
245 | /** | |
246 | * Helper function that loads, builds and executes the specified view, | |
247 | * then returns its VBO field. | |
248 | * | |
249 | * @param $view_target | |
250 | * A string in the format "$view_name|$display_name". | |
251 | * @param $args | |
252 | * Arguments that should be passed to the View. | |
253 | * | |
254 | * @return | |
255 | * The VBO field. Contains a reference to the View. | |
256 | */ | |
257 | function _views_bulk_operations_rules_get_field($view_target, $args) { | |
258 | $views = &drupal_static(__FUNCTION__); | |
259 | ||
260 | $views_settings = explode('|', $view_target); | |
261 | $view_name = $views_settings[0]; | |
262 | $display_name = $views_settings[1]; | |
263 | // Create an array of arguments. | |
264 | $view_arguments = explode("\n", $args); | |
265 | $view_arguments = array_map('trim', $view_arguments); | |
266 | $view_arguments = array_filter($view_arguments, 'strlen'); | |
267 | // Append the filtered list of arguments to $views_target, so that the correct | |
268 | // View is fetched from cache. | |
269 | if (!empty($view_arguments)) { | |
270 | $view_target .= '|' . implode('&', $view_arguments); | |
271 | } | |
272 | ||
273 | // Don't execute the requested View more than once in a single page request. | |
274 | if (isset($views[$view_target])) { | |
275 | $vbo = _views_bulk_operations_get_field($views[$view_target]); | |
276 | return $vbo; | |
277 | } | |
278 | ||
279 | // Load the view and set the properties. | |
280 | $view = views_get_view($view_name); | |
281 | $view->set_display($display_name); | |
282 | $view->set_arguments($view_arguments); | |
283 | $view->build(); | |
284 | $vbo = _views_bulk_operations_get_field($view); | |
285 | // Unset every field except the VBO one (which holds the entity id). | |
286 | // That way the performance hit becomes much smaller, because there is no | |
287 | // chance of views_handler_field_field::post_execute() firing entity_load(). | |
288 | foreach ($view->field as $field_name => $field) { | |
289 | if ($field_name != $vbo->options['id']) { | |
290 | unset($view->field[$field_name]); | |
291 | } | |
292 | } | |
293 | $view->execute($view->current_display); | |
294 | // Save the view in the static cache. | |
295 | $views[$view_target] = $view; | |
296 | ||
297 | return $vbo; | |
298 | } |