PluginProbe
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI / 6.0.3
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI v6.0.3
6.0.3 6.0.2 6.0.1 6.0.0 5.8.6 5.8.5 5.8.4 5.8.3 5.8.2 5.8.1 5.8.0 5.7.9.2 5.7.9.1 5.7.8 5.7.9 5.7.6 5.7.7 5.7.5 5.7.4 5.7.3 5.7.2 5.7.1 trunk 5.6.0 5.6.1 All 34 releases
← All changes | includes/admin/pages/import-automation.php +402 -0 5.7.2 → 6.0.3 View file →
@@ -1,0 +1,402 @@
1 +<?php
2 +/**
3 + * Import Automation Page
4 + *
5 + * @package AutomatorWP\Admin\Import_Automation
6 + * @author AutomatorWP <[email protected]>, Ruben Garcia <[email protected]>
7 + * @since 1.0.0
8 + */
9 +// Exit if accessed directly
10 +if( !defined( 'ABSPATH' ) ) exit;
11 +
12 +function automatorwp_hide_import_automation_page( $submenu_file ) {
13 +
14 + // Hide the submenu
15 + remove_submenu_page( 'automatorwp', 'automatorwp_import_automation' );
16 +
17 + return $submenu_file;
18 +}
19 +add_filter( 'submenu_file', 'automatorwp_hide_import_automation_page' );
20 +
21 +/**
22 + * Import Automation page
23 + *
24 + * @since 1.0.0
25 + *
26 + * @return void
27 + */
28 +function automatorwp_import_automation_page() {
29 + ?>
30 + <div class="wrap">
31 +
32 + <div class="automatorwp-import-automation-text"><?php _e( 'Importing automation...', 'automatorwp' ); ?></div>
33 + <div class="automatorwp-import-automation-icon">
34 + <img src="<?php echo AUTOMATORWP_URL . 'assets/img/automatorwp-logo.svg'; ?>" class="automatorwp-import-automation-icon-default"/>
35 + <img src="<?php echo AUTOMATORWP_URL . 'assets/img/automatorwp-logo-success.svg'; ?>" class="automatorwp-import-automation-icon-success" style="display: none"/>
36 + <img src="<?php echo AUTOMATORWP_URL . 'assets/img/automatorwp-logo-error.svg'; ?>" class="automatorwp-import-automation-icon-error" style="display: none"/>
37 +
38 + </div>
39 + <div class="automatorwp-import-automation-loader">
40 + <div class="automatorwp-import-automation-loader-background"></div>
41 + <div class="automatorwp-import-automation-loader-icon"></div>
42 + </div>
43 +
44 + </div>
45 + <?php
46 +}
47 +
48 +/**
49 + * Import an automation from URL through ajax
50 + *
51 + * @since 1.0.0
52 + */
53 +function automatorwp_ajax_get_automation_export_url() {
54 + // Security check, forces to die if not security passed
55 + check_ajax_referer( 'automatorwp_admin', 'nonce' );
56 +
57 + // Permissions check
58 + if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
59 + wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
60 + }
61 +
62 + $automation_id = ( isset( $_REQUEST['automation_id'] ) ? absint( $_REQUEST['automation_id'] ) : 0 );
63 +
64 + // Bail if automation ID not provided
65 + if( $automation_id === 0 ) {
66 + wp_send_json_error( __( 'Invalid automation ID.', 'automatorwp' ) );
67 + }
68 +
69 + $url = automatorwp_get_automation_export_url( $automation_id );
70 +
71 + wp_send_json_success( $url );
72 +
73 +}
74 +add_action( 'wp_ajax_automatorwp_get_automation_export_url', 'automatorwp_ajax_get_automation_export_url' );
75 +
76 +/**
77 + * Import an automation from URL through ajax
78 + *
79 + * @since 1.0.0
80 + */
81 +function automatorwp_ajax_import_automation_from_url() {
82 +
83 + global $wpdb;
84 +
85 + // Security check, forces to die if not security passed
86 + check_ajax_referer( 'automatorwp_admin', 'nonce' );
87 +
88 + // Permissions check
89 + if( ! current_user_can( automatorwp_get_manager_capability() ) ) {
90 + wp_send_json_error( __( 'You\'re not allowed to perform this action.', 'automatorwp' ) );
91 + }
92 +
93 + $request = array();
94 +
95 + // Parse the given request
96 + parse_str( $_REQUEST['request'] , $request );
97 +
98 + // Get automation args
99 + $title = ( isset( $request['ti'] ) ? sanitize_text_field( $request['ti'] ) : '' );
100 + $type = ( isset( $request['ty'] ) ? sanitize_text_field( $request['ty'] ) : 'user' );
101 + $sequential = ( isset( $request['s'] ) ? absint( $request['s'] ) : 0 );
102 + $times_per_user = ( isset( $request['tu'] ) ? absint( $request['tu'] ) : 1 );
103 + $times = ( isset( $request['tim'] ) ? absint( $request['tim'] ) : 0 );
104 +
105 + // Get triggers and actions
106 + $received_triggers = automatorwp_get_array_from_export_url( $request, 't' );
107 + $received_actions = automatorwp_get_array_from_export_url( $request, 'a' );
108 +
109 + // Bail if no triggers and actions received
110 + if( empty( $received_triggers ) && empty( $received_actions ) ) {
111 + wp_send_json_error( __( 'No triggers and actions found from this URL.', 'automatorwp' ) );
112 + }
113 +
114 + $triggers = array();
115 + $actions = array();
116 +
117 + // Check if all received triggers are correct
118 + foreach ( $received_triggers as $trigger ) {
119 + // The unique required parameter is the trigger type
120 + if( ! isset( $trigger['t'] ) ) {
121 + continue;
122 + }
123 +
124 + $triggers[] = $trigger;
125 + }
126 +
127 + // Check if all received actions are correct
128 + foreach ( $received_actions as $action ) {
129 + // The unique required parameter is the action type
130 + if( ! isset( $action['t'] ) ) {
131 + continue;
132 + }
133 +
134 + $actions[] = $action;
135 + }
136 +
137 + // Bail if no triggers and actions found
138 + if( empty( $triggers ) && empty( $actions ) ) {
139 + wp_send_json_error( __( 'No triggers and actions found from this URL.', 'automatorwp' ) );
140 + }
141 +
142 + // All done!
143 +
144 + ct_setup_table( 'automatorwp_automations' );
145 +
146 + // Create the new automation
147 + $automation = array(
148 + 'title' => $title . ( ! empty( $title ) ? ' ' : '' ) . __( '(Imported)', 'automatorwp' ),
149 + 'type' => $type,
150 + 'sequential' => $sequential,
151 + 'times_per_user' => $times_per_user,
152 + 'times' => $times,
153 + 'status' => 'inactive',
154 + 'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
155 + );
156 +
157 + $new_automation_id = ct_insert_object( $automation );
158 +
159 + ct_reset_setup_table();
160 +
161 + // Bail if could not create the automation
162 + if( ! $new_automation_id ) {
163 + wp_send_json_error( __( 'Could not create the automation from this URL.', 'automatorwp' ) );
164 + }
165 +
166 + $automation['id'] = $new_automation_id;
167 +
168 + // Lets insert the triggers and actions
169 + $item_types = array( 'trigger', 'action' );
170 + $ids = array();
171 + $replacements = array();
172 + $new_triggers = array();
173 + $new_actions = array();
174 +
175 + // Loop items to insert them
176 + foreach( $item_types as $item_type ) {
177 +
178 + if( $item_type === 'trigger' ) {
179 + $items = $triggers;
180 + } else {
181 + $items = $actions;
182 + }
183 +
184 + ct_setup_table( "automatorwp_{$item_type}s" );
185 +
186 + foreach( $items as $i => $item ) {
187 +
188 + // Create the new trigger or action
189 + $new_item = array(
190 + 'automation_id' => $new_automation_id,
191 + 'title' => '',
192 + 'type' => sanitize_text_field( $item['t'] ),
193 + 'status' => 'active',
194 + 'position' => absint( $i ),
195 + 'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
196 + );
197 +
198 + $new_item_id = ct_insert_object( $new_item );
199 +
200 + if( $new_item_id ) {
201 +
202 + if( isset( $item['i'] ) && absint( $item['i'] ) !== 0 ) {
203 + // Update old ids and replacements to be used on metas
204 + $ids[absint( $item['i'] )] = $new_item_id;
205 + $replacements['{' . absint( $item['i'] ) . ':'] = '{' . $new_item_id . ':';
206 + } else {
207 + // Ensure item ID
208 + $items[$i]['i'] = $new_item_id;
209 + $ids[$new_item_id] = $new_item_id;
210 + }
211 +
212 + $new_item['id'] = $new_item_id;
213 + $item_id = absint( $items[$i]['i'] );
214 +
215 + if( $item_type === 'trigger' ) {
216 + $new_triggers[$item_id] = $new_item;
217 + } else {
218 + $new_actions[$item_id] = $new_item;
219 + }
220 +
221 + }
222 +
223 + }
224 +
225 + ct_reset_setup_table();
226 +
227 + }
228 +
229 + $tags = array_keys( $replacements );
230 +
231 + // Loop items again to update their metas
232 + foreach( $item_types as $item_type ) {
233 +
234 + if( $item_type === 'trigger' ) {
235 + $items = $triggers;
236 + } else {
237 + $items = $actions;
238 + }
239 +
240 + $ct_table = ct_setup_table( "automatorwp_{$item_type}s" );
241 + $metas = array();
242 +
243 + foreach( $items as $i => $item ) {
244 +
245 + // Skip items without metas
246 + if( ! isset( $item['o'] ) ) {
247 + continue;
248 + }
249 +
250 + if( ! is_array( $item['o'] ) ) {
251 + continue;
252 + }
253 +
254 + $item_id = absint( $item['i'] );
255 +
256 + // Skip items without an ID
257 + if( ! isset( $ids[$item_id] ) ) {
258 + continue;
259 + }
260 +
261 + $type = sanitize_text_field( $item['t'] );
262 +
263 + if( $item_type === 'trigger' ) {
264 + $object = automatorwp_get_trigger( $type );
265 + } else {
266 + $object = automatorwp_get_action( $type );
267 + }
268 +
269 + $fields = array();
270 +
271 + // Merge all object fields to check them later
272 + if( isset( $object['options'] ) ) {
273 + foreach( $object['options'] as $option => $option_args ) {
274 + if( isset( $option_args['fields'] ) ) {
275 + $fields = array_merge( $option_args['fields'], $fields );
276 + }
277 + }
278 +
279 + }
280 +
281 + foreach ( $item['o'] as $meta_key => $meta_value ) {
282 +
283 + /**
284 + * Filter to exclude a meta on export this item through URL
285 + * $item_type: trigger | action
286 + * $type: The trigger or action type
287 + * $meta_key: The meta key
288 + *
289 + * @since 1.0.0
290 + *
291 + * @param bool $exclude
292 + *
293 + * @return bool
294 + */
295 + $exclude = apply_filters( "automatorwp_export_url_{$item_type}_{$type}_meta_{$meta_key}_excluded", false );
296 +
297 + // Skip if meta gets excluded on export through URL
298 + if( $exclude ) {
299 + continue;
300 + }
301 +
302 + // KEY
303 + $meta_key = sanitize_key( $meta_key );
304 + $meta_key = wp_unslash( $meta_key );
305 +
306 + // Skip if this meta key is not an object field
307 + if( ! isset( $fields[$meta_key] ) ) {
308 + continue;
309 + }
310 +
311 + $field_type = ( isset( $fields[$meta_key]['type'] ) ? $fields[$meta_key]['type'] : 'text' );
312 +
313 + // VALUE
314 + $meta_value = urldecode( $meta_value );
315 +
316 + // Only apply json decode if can be parsed correctly
317 + $json = json_decode( $meta_value );
318 + if( is_object( $json ) ) {
319 + $meta_value = $json;
320 + }
321 +
322 + // Sanitize value based on its type
323 + if( in_array( $field_type, array( 'textarea', 'textarea_small', 'textarea_code', 'wysiwyg' ) ) ) {
324 + // HTML fields
325 + $meta_value = wp_kses_post( $meta_value );
326 + } else {
327 + // The rest of field types
328 + $meta_value = sanitize_text_field( $meta_value );
329 + }
330 +
331 + $meta_value = maybe_unserialize( $meta_value );
332 + $meta_value = wp_unslash( $meta_value );
333 + $meta_value = esc_sql( $meta_value );
334 + $meta_value = sanitize_meta( $meta_key, $meta_value, $ct_table->name );
335 + $meta_value = maybe_serialize( $meta_value );
336 +
337 + // Replace metas with old IDs with the new ones
338 + $meta_value = str_replace( $tags, $replacements, $meta_value );
339 +
340 + // Prepare for the upcoming insert
341 + $metas[] = $wpdb->prepare( '%d, %s, %s', array( $ids[$item_id], $meta_key, $meta_value ) );
342 + }
343 +
344 + }
345 +
346 + if( count( $metas ) ) {
347 + $metas = implode( '), (', $metas );
348 +
349 + // Run a single query to insert all metas instead of insert them one-by-one
350 + $wpdb->query( "INSERT INTO {$ct_table->meta->db->table_name} (id, meta_key, meta_value) VALUES ({$metas})" );
351 + }
352 +
353 + ct_reset_setup_table();
354 +
355 + }
356 +
357 + // Loop items again to update their titles
358 + foreach( $item_types as $item_type ) {
359 +
360 + if( $item_type === 'trigger' ) {
361 + $items = $triggers;
362 + } else {
363 + $items = $actions;
364 + }
365 +
366 + ct_setup_table( "automatorwp_{$item_type}s" );
367 +
368 + foreach( $items as $i => $item ) {
369 +
370 + $item_id = absint( $item['i'] );
371 +
372 + // Skip items without an ID
373 + if( ! isset( $ids[$item_id] ) ) {
374 + continue;
375 + }
376 +
377 + if( $item_type === 'trigger' ) {
378 + $object = (object) $new_triggers[$item_id];
379 + } else {
380 + $object = (object) $new_actions[$item_id];
381 + }
382 +
383 + // Update the item title
384 + ct_update_object( array(
385 + 'id' => $ids[$item_id],
386 + 'title' => automatorwp_parse_automation_item_edit_label( $object, $item_type, 'view' )
387 + ) );
388 +
389 + }
390 +
391 + ct_reset_setup_table();
392 +
393 + }
394 +
395 + wp_send_json_success( array(
396 + 'message' => __( 'Automation imported successfully! Redirecting...', 'automatorwp' ),
397 + 'redirect_url' => ct_get_edit_link( 'automatorwp_automations', $new_automation_id ),
398 + ) );
399 +
400 +}
401 +add_action( 'wp_ajax_automatorwp_import_automation_from_url', 'automatorwp_ajax_import_automation_from_url' );
402 +