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 | assets/js/automatorwp-admin-functions.js +1007 -0 5.7.2 → 6.0.3 View file →
@@ -1,0 +1,1007 @@
1 +/**
2 + * Helper function to initialize select2 on fields
3 + *
4 + * @since 1.0.0
5 + *
6 + * @param {Object} $this
7 + */
8 +function automatorwp_selector( $this ) {
9 +
10 + // Prevent load select2 on widgets lists
11 + if( $this.closest('#available-widgets').length ) {
12 + return;
13 + }
14 +
15 + var select2_args = {
16 + theme: 'default automatorwp-select2',
17 + placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : automatorwp_admin_functions.selector_placeholder ),
18 + allowClear: true,
19 + multiple: ( $this[0].hasAttribute('multiple') ),
20 + matcher: automatorwp_select2_words_matcher,
21 + };
22 +
23 + $this.automatorwp_select2( select2_args );
24 +
25 +}
26 +
27 +/**
28 + * Helper function to initialize select2 post selector on fields
29 + *
30 + * @since 1.0.0
31 + *
32 + * @param {Object} $this
33 + */
34 +function automatorwp_post_selector( $this ) {
35 +
36 + // Prevent load select2 on widgets lists
37 + if( $this.closest('#available-widgets').length ) {
38 + return;
39 + }
40 +
41 + var post_types = $this.data('post-type').split(',');
42 +
43 + var select2_args = {
44 + ajax: {
45 + url: ajaxurl,
46 + dataType: 'json',
47 + delay: 250,
48 + type: 'POST',
49 + data: function( params ) {
50 + return {
51 + q: params.term,
52 + page: params.page || 1,
53 + action: 'automatorwp_get_posts',
54 + nonce: automatorwp_admin_functions.nonce,
55 + post_type: post_types,
56 + post_type_cb: $this.data('post-type-cb'),
57 + option_none: $this.data('option-none'),
58 + option_none_value: $this.data('option-none-value'),
59 + option_none_label: $this.data('option-none-label'),
60 + option_custom: $this.data('option-custom'),
61 + option_custom_value: $this.data('option-custom-value'),
62 + option_custom_label: $this.data('option-custom-label'),
63 + };
64 + },
65 + processResults: automatorwp_select2_posts_process_results
66 + },
67 + escapeMarkup: function ( markup ) { return markup; },
68 + templateResult: ( post_types.length === 1 ? automatorwp_select2_posts_template_result : automatorwp_select2_post_types_template_result ),
69 + theme: 'default automatorwp-select2',
70 + placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : automatorwp_admin_functions.post_selector_placeholder ),
71 + allowClear: true,
72 + multiple: ( $this[0].hasAttribute('multiple') ),
73 + matcher: automatorwp_select2_words_matcher,
74 + };
75 +
76 + $this.automatorwp_select2( select2_args );
77 +
78 +}
79 +
80 +/**
81 + * Helper function to initialize select2 term selector on fields
82 + *
83 + * @since 1.0.0
84 + *
85 + * @param {Object} $this
86 + */
87 +function automatorwp_term_selector( $this ) {
88 +
89 + // Prevent load select2 on widgets lists
90 + if( $this.closest('#available-widgets').length ) {
91 + return;
92 + }
93 +
94 + var select2_args = {
95 + ajax: {
96 + url: ajaxurl,
97 + dataType: 'json',
98 + delay: 250,
99 + type: 'POST',
100 + data: function( params ) {
101 + return {
102 + q: params.term,
103 + page: params.page || 1,
104 + action: 'automatorwp_get_terms',
105 + nonce: automatorwp_admin_functions.nonce,
106 + taxonomy: $this.data('taxonomy'),
107 + option_none: $this.data('option-none'),
108 + option_none_value: $this.data('option-none-value'),
109 + option_none_label: $this.data('option-none-label'),
110 + option_custom: $this.data('option-custom'),
111 + option_custom_value: $this.data('option-custom-value'),
112 + option_custom_label: $this.data('option-custom-label'),
113 + };
114 + },
115 + processResults: automatorwp_select2_terms_process_results
116 + },
117 + escapeMarkup: function ( markup ) { return markup; },
118 + templateResult: automatorwp_select2_terms_template_result,
119 + theme: 'default automatorwp-select2',
120 + placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : automatorwp_admin_functions.term_selector_placeholder ),
121 + allowClear: true,
122 + multiple: ( $this[0].hasAttribute('multiple') ),
123 + matcher: automatorwp_select2_words_matcher,
124 + };
125 +
126 + $this.automatorwp_select2( select2_args );
127 +
128 +}
129 +
130 +/**
131 + * Helper function to initialize select2 user selector on fields
132 + *
133 + * @since 1.0.0
134 + *
135 + * @param {Object} $this
136 + */
137 +function automatorwp_user_selector( $this ) {
138 +
139 + // Prevent load select2 on widgets lists
140 + if( $this.closest('#available-widgets').length ) {
141 + return;
142 + }
143 +
144 + var select2_args = {
145 + ajax: {
146 + url: ajaxurl,
147 + dataType: 'json',
148 + delay: 250,
149 + type: 'POST',
150 + data: function( params ) {
151 + return {
152 + q: params.term,
153 + page: params.page || 1,
154 + action: 'automatorwp_get_users',
155 + nonce: automatorwp_admin_functions.nonce,
156 + };
157 + },
158 + processResults: automatorwp_select2_users_process_results
159 + },
160 + escapeMarkup: function ( markup ) { return markup; },
161 + templateResult: automatorwp_select2_users_template_result,
162 + theme: 'default automatorwp-select2',
163 + placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : automatorwp_admin_functions.user_selector_placeholder ),
164 + allowClear: true,
165 + multiple: ( $this[0].hasAttribute('multiple') ),
166 + matcher: automatorwp_select2_words_matcher,
167 + };
168 +
169 + $this.automatorwp_select2( select2_args );
170 +
171 +}
172 +
173 +/**
174 + * Helper function to initialize select2 object selector on fields
175 + *
176 + * @since 1.0.0
177 + *
178 + * @param {Object} $this
179 + */
180 +function automatorwp_object_selector( $this ) {
181 +
182 + // Prevent load select2 on widgets lists
183 + if( $this.closest('#available-widgets').length ) {
184 + return;
185 + }
186 +
187 + var select2_args = {
188 + ajax: {
189 + url: ajaxurl,
190 + dataType: 'json',
191 + delay: 250,
192 + type: 'POST',
193 + data: function( params ) {
194 + return {
195 + q: params.term,
196 + page: params.page || 1,
197 + action: 'automatorwp_get_objects',
198 + nonce: automatorwp_admin_functions.nonce,
199 + table: $this.data('table'),
200 + option_none: $this.data('option-none'),
201 + option_none_value: $this.data('option-none-value'),
202 + option_none_label: $this.data('option-none-label'),
203 + option_custom: $this.data('option-custom'),
204 + option_custom_value: $this.data('option-custom-value'),
205 + option_custom_label: $this.data('option-custom-label'),
206 + };
207 + },
208 + processResults: automatorwp_select2_objects_process_results
209 + },
210 + escapeMarkup: function ( markup ) { return markup; },
211 + templateResult: automatorwp_select2_objects_template_result,
212 + theme: 'default automatorwp-select2',
213 + placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : automatorwp_admin_functions.object_selector_placeholder ),
214 + allowClear: true,
215 + multiple: ( $this[0].hasAttribute('multiple') ),
216 + matcher: automatorwp_select2_words_matcher,
217 + };
218 +
219 + $this.automatorwp_select2( select2_args );
220 +
221 +}
222 +
223 +/**
224 + * Helper function to initialize select2 ajax selector on fields
225 + *
226 + * @since 1.0.0
227 + *
228 + * @param {Object} $this
229 + */
230 +function automatorwp_ajax_selector( $this ) {
231 +
232 + // Prevent load select2 on widgets lists
233 + if( $this.closest('#available-widgets').length ) {
234 + return;
235 + }
236 +
237 + var select2_args = {
238 + ajax: {
239 + url: ajaxurl,
240 + dataType: 'json',
241 + delay: 250,
242 + type: 'POST',
243 + data: function( params ) {
244 +
245 + var data = {
246 + q: params.term,
247 + page: params.page || 1,
248 + action: $this.data('action'),
249 + nonce: automatorwp_admin_functions.nonce,
250 + table: $this.data('table'),
251 + option_none: $this.data('option-none'),
252 + option_none_value: $this.data('option-none-value'),
253 + option_none_label: $this.data('option-none-label'),
254 + option_custom: $this.data('option-custom'),
255 + option_custom_value: $this.data('option-custom-value'),
256 + option_custom_label: $this.data('option-custom-label'),
257 + };
258 +
259 + /**
260 + * Allow external functions to add their own data
261 + *
262 + * @since 1.0.0
263 + *
264 + * @param Object data
265 + * @param Node element
266 + */
267 + $this.trigger( 'automatorwp_ajax_selector_data', [ data, $this ] );
268 +
269 + return data;
270 + },
271 + processResults: automatorwp_select2_ajax_process_results
272 + },
273 + escapeMarkup: function ( markup ) { return markup; },
274 + templateResult: automatorwp_select2_ajax_template_result,
275 + theme: 'default automatorwp-select2',
276 + placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : '' ),
277 + allowClear: true,
278 + multiple: ( $this[0].hasAttribute('multiple') ),
279 + matcher: automatorwp_select2_words_matcher,
280 + };
281 +
282 + $this.automatorwp_select2( select2_args );
283 +
284 +}
285 +
286 +/**
287 + * Custom formatting for posts on select2
288 + *
289 + * @since 1.0.0
290 + *
291 + * @param {Object} item
292 + *
293 + * @return {string}
294 + */
295 +function automatorwp_select2_posts_template_result( item ) {
296 +
297 + if( item.post_title !== undefined ) {
298 + return item.post_title + ( ! isNaN( item.ID ) ? '<span class="result-description align-right">ID: ' + item.ID + '</span>': '' );
299 + }
300 +
301 + return item.text + ( ! isNaN( item.id ) ? '<span class="result-description align-right">ID: ' + item.id + '</span>': '' );
302 +
303 +}
304 +
305 +/**
306 + * Custom formatting for posts on select2 with multiples post types
307 + *
308 + * @since 1.0.0
309 + *
310 + * @param {Object} item
311 + *
312 + * @return {string}
313 + */
314 +function automatorwp_select2_post_types_template_result( item ) {
315 +
316 + if( item.post_type !== undefined ) {
317 +
318 + var post_type_label = item.post_type;
319 +
320 + if( automatorwp_post_type_exists( item.post_type ) ) {
321 + post_type_label = automatorwp_get_post_type_label( item.post_type );
322 + }
323 +
324 + return item.post_title
325 + + '<span class="result-description">'
326 + + post_type_label + '<span class="align-right">' + 'ID: ' + item.ID + '</span>'
327 + + '</span>';
328 + }
329 +
330 + // Fallback oon posts template result
331 + return automatorwp_select2_posts_template_result( item );
332 +
333 +}
334 +
335 +/**
336 + * Custom formatting for terms on select2
337 + *
338 + * @since 1.0.0
339 + *
340 + * @param {Object} item
341 + *
342 + * @return {string}
343 + */
344 +function automatorwp_select2_terms_template_result( item ) {
345 +
346 + if( item.name !== undefined ) {
347 + return item.name + ( ! isNaN( item.term_id ) ? '<span class="result-description align-right">ID: ' + item.term_id + '</span>': '' );
348 + }
349 +
350 + return item.text + ( ! isNaN( item.id ) ? '<span class="result-description align-right">ID: ' + item.id + '</span>': '' );
351 +
352 +}
353 +
354 +/**
355 + * Custom results processing for posts on select2
356 + *
357 + * @since 1.0.0
358 + *
359 + * @param {Object} response
360 + * @param {Object} params
361 + *
362 + * @return {string}
363 + */
364 +function automatorwp_select2_posts_process_results( response, params ) {
365 +
366 + if( response === null ) {
367 + return { results: [] };
368 + }
369 +
370 + var formatted_results = [];
371 +
372 + // Paginated responses will come with results and more_results keys
373 + var results = ( response.data.results !== undefined ? response.data.results : response.data );
374 +
375 + results.forEach( function( item ) {
376 +
377 + // Extend select2 keys (id and text) with given keys (ID, post_title and optionally post_type, site_id and site_name)
378 + formatted_results.push( jQuery.extend({
379 + id: item.ID,
380 + //text: item.post_title + ' (ID: ' + item.ID + ')',
381 + text: item.post_title,
382 + }, item ) );
383 +
384 + } );
385 +
386 + return {
387 + results: formatted_results,
388 + pagination: {
389 + more: ( response.data.more_results !== undefined ? response.data.more_results : false )
390 + }
391 + };
392 +
393 +}
394 +
395 +/**
396 + * Custom results processing for terms on select2
397 + *
398 + * @since 1.0.0
399 + *
400 + * @param {Object} response
401 + * @param {Object} params
402 + *
403 + * @return {string}
404 + */
405 +function automatorwp_select2_terms_process_results( response, params ) {
406 +
407 + if( response === null ) {
408 + return { results: [] };
409 + }
410 +
411 + var formatted_results = [];
412 +
413 + // Paginated responses will come with results and more_results keys
414 + var results = ( response.data.results !== undefined ? response.data.results : response.data );
415 +
416 + results.forEach( function( item ) {
417 +
418 + // Extend select2 keys (id and text) with given keys (ID, post_title and optionally post_type, site_id and site_name)
419 + formatted_results.push( jQuery.extend({
420 + id: item.term_id,
421 + //text: item.post_title + ' (ID: ' + item.ID + ')',
422 + text: item.name,
423 + }, item ) );
424 +
425 + } );
426 +
427 + return {
428 + results: formatted_results,
429 + pagination: {
430 + more: ( response.data.more_results !== undefined ? response.data.more_results : false )
431 + }
432 + };
433 +
434 +}
435 +
436 +/**
437 + * Custom formatting for users on select2
438 + *
439 + * @since 1.0.0
440 + *
441 + * @param {Object} item
442 + *
443 + * @return {string}
444 + */
445 +function automatorwp_select2_users_template_result( item ) {
446 +
447 + if( item.display_name !== undefined ) {
448 +
449 + return item.display_name + ( ! isNaN( item.ID ) ? '<span class="result-description align-right">ID: ' + item.ID + '</span>': '' );
450 +
451 + }
452 +
453 + return item.text + ( ! isNaN( item.id ) ? '<span class="result-description align-right">ID: ' + item.id + '</span>': '' );
454 +
455 +}
456 +
457 +/**
458 + * Custom results processing for users on select2
459 + *
460 + * @since 1.0.0
461 + *
462 + * @param {Object} response
463 + * @param {Object} params
464 + *
465 + * @return {string}
466 + */
467 +function automatorwp_select2_users_process_results( response, params ) {
468 +
469 + if( response === null ) {
470 + return { results: [] };
471 + }
472 +
473 + var formatted_results = [];
474 +
475 + // Paginated responses will come with results and more_results keys
476 + var results = ( response.data.results !== undefined ? response.data.results : response.data );
477 +
478 + results.forEach( function( item ) {
479 +
480 + // Extend select2 keys (id and text) with given keys (ID, post_title and optionally post_type)
481 + formatted_results.push( jQuery.extend({
482 + id: item.ID,
483 + text: item.user_login,
484 + //text: item.user_login + ' (#' + item.ID + ')',
485 + }, item ) );
486 +
487 + } );
488 +
489 + return {
490 + results: formatted_results,
491 + pagination: {
492 + more: ( response.data.more_results !== undefined ? response.data.more_results : false )
493 + }
494 + };
495 +
496 +}
497 +
498 +/**
499 + * Custom formatting for objects on select2
500 + *
501 + * @since 1.0.0
502 + *
503 + * @param {Object} item
504 + *
505 + * @return {string}
506 + */
507 +function automatorwp_select2_objects_template_result( item ) {
508 +
509 + return item.text + ( ! isNaN( item.id ) ? '<span class="result-description align-right">ID: ' + item.id + '</span>': '' );
510 +
511 +}
512 +
513 +/**
514 + * Custom results processing for objects on select2
515 + *
516 + * @since 1.0.0
517 + *
518 + * @param {Object} response
519 + * @param {Object} params
520 + *
521 + * @return {string}
522 + */
523 +function automatorwp_select2_objects_process_results( response, params ) {
524 +
525 + if( response === null ) {
526 + return { results: [] };
527 + }
528 +
529 + var formatted_results = [];
530 +
531 + // Paginated responses will come with results and more_results keys
532 + var results = ( response.data.results !== undefined ? response.data.results : response.data );
533 +
534 + results.forEach( function( item ) {
535 +
536 + // Extend select2 keys (id and text) with given keys (id and text)
537 + formatted_results.push( jQuery.extend({
538 + id: item.id,
539 + text: item.text,
540 + }, item ) );
541 +
542 + } );
543 +
544 + return {
545 + results: formatted_results,
546 + pagination: {
547 + more: ( response.data.more_results !== undefined ? response.data.more_results : false )
548 + }
549 + };
550 +
551 +}
552 +
553 +/**
554 + * Custom formatting for objects on select2
555 + *
556 + * @since 1.0.0
557 + *
558 + * @param {Object} item
559 + *
560 + * @return {string}
561 + */
562 +function automatorwp_select2_ajax_template_result( item ) {
563 +
564 + return item.text + ( ! isNaN( item.id ) ? '<span class="result-description align-right">ID: ' + item.id + '</span>': '' );
565 +
566 +}
567 +
568 +/**
569 + * Custom results processing for objects on select2
570 + *
571 + * @since 1.0.0
572 + *
573 + * @param {Object} response
574 + * @param {Object} params
575 + *
576 + * @return {string}
577 + */
578 +function automatorwp_select2_ajax_process_results( response, params ) {
579 +
580 + if( response === null ) {
581 + return { results: [] };
582 + }
583 +
584 + var formatted_results = [];
585 +
586 + // Paginated responses will come with results and more_results keys
587 + var results = ( response.data.results !== undefined ? response.data.results : response.data );
588 +
589 + results.forEach( function( item ) {
590 +
591 + // Extend select2 keys (id and text) with given keys (id and text)
592 + formatted_results.push( jQuery.extend({
593 + id: item.id,
594 + text: item.text,
595 + }, item ) );
596 +
597 + } );
598 +
599 + return {
600 + results: formatted_results,
601 + pagination: {
602 + more: ( response.data.more_results !== undefined ? response.data.more_results : false )
603 + }
604 + };
605 +
606 +}
607 +
608 +/**
609 + * Helper function to check if text has any word of a term
610 + *
611 + * @since 1.0.0
612 + *
613 + * @param {String} text
614 + * @param {String} term
615 + *
616 + * @return {boolean}
617 + */
618 +function automatorwp_matches_by_word( text, term ) {
619 +
620 + text = text.toUpperCase();
621 + var words = term.toUpperCase().split(" ");
622 + var found = true;
623 +
624 + // Check if the text contains the term (separated in words)
625 + for (var i =0; i < words.length; i++)
626 + found = ( found && text.indexOf( words[i] ) >= 0 );
627 +
628 + return found;
629 +
630 +}
631 +
632 +/**
633 + * Select2 search matcher by word
634 + *
635 + * @since 1.0.0
636 + *
637 + * @param {Object} params
638 + * @param {Object} data
639 + *
640 + * @return {mixed}
641 + */
642 +function automatorwp_select2_words_matcher( params, data ) {
643 +
644 + // Always return the object if there is nothing to compare
645 + if ( params.term === undefined || params.term.trim() === '' ) return data;
646 +
647 + // Return the object if any word matches
648 + if ( automatorwp_matches_by_word( data.text, params.term ) ) return data;
649 +
650 + // If it doesn't contain the term, don't return anything
651 + return null;
652 +
653 +}
654 +
655 +/**
656 + * Custom search matcher for selects with groups on select2
657 + *
658 + * @since 1.0.0
659 + *
660 + * @param {Object} params
661 + * @param {Object} data
662 + *
663 + * @return {mixed}
664 + */
665 +function automatorwp_select2_optgroup_matcher( params, data ) {
666 +
667 + // Initialize required vars
668 + data.parentText = data.parentText || '';
669 +
670 + // Always return the object if there is nothing to compare
671 + if ( params.term === undefined || params.term.trim() === '' ) return data;
672 +
673 + // Do a recursive check for options with children
674 + if ( data.children && data.children.length > 0 ) {
675 +
676 + // Clone the data object if there are children
677 + // This is required as we modify the object to remove any non-matches
678 + var match = jQuery.extend( true, {}, data );
679 +
680 + // Check each child of the option
681 + for ( var c = data.children.length - 1; c >= 0; c-- ) {
682 +
683 + var child = data.children[c];
684 + child.parentText += data.parentText + " " + data.text;
685 +
686 + var matches = automatorwp_select2_optgroup_matcher( params, child );
687 +
688 + // If there wasn't a match, remove the object in the array
689 + if (matches == null) {
690 + match.children.splice( c, 1 );
691 + }
692 +
693 + }
694 +
695 + // If any children matched, return the new object
696 + if ( match.children.length > 0 ) {
697 + return match;
698 + }
699 +
700 + // If there were no matching children, check just the plain object
701 + return automatorwp_select2_optgroup_matcher( params, match );
702 +
703 + }
704 +
705 + // Check if term matches with this text or text from parent
706 + if ( automatorwp_matches_by_word( ( data.parentText + ' ' + data.text ), params.term ) ) return data;
707 +
708 + // If it doesn't contain the term, don't return anything
709 + return null;
710 +}
711 +
712 +/**
713 + * Check if post type has been registered
714 + *
715 + * @since 1.0.0
716 + *
717 + * @param {string} post_type
718 + *
719 + * @return {boolean}
720 + */
721 +function automatorwp_post_type_exists( post_type ) {
722 + return ( automatorwp_admin_functions.post_type_labels[post_type] !== undefined )
723 +}
724 +
725 +/**
726 + * Get the post type label (singular name)
727 + *
728 + * @since 1.0.0
729 + *
730 + * @param {string} post_type
731 + *
732 + * @return {string}
733 + */
734 +function automatorwp_get_post_type_label( post_type ) {
735 +
736 + var label = '';
737 +
738 + if( automatorwp_post_type_exists( post_type ) ) {
739 + label = automatorwp_admin_functions.post_type_labels[post_type];
740 + }
741 +
742 + return label;
743 +}
744 +
745 +/**
746 + * Check if taxonomy has been registered
747 + *
748 + * @since 1.0.0
749 + *
750 + * @param {string} taxonomy
751 + *
752 + * @return {boolean}
753 + */
754 +function automatorwp_taxonomy_exists( taxonomy ) {
755 + return ( automatorwp_admin_functions.taxonomy_labels[taxonomy] !== undefined )
756 +}
757 +
758 +/**
759 + * Get the taxonomy label (singular name)
760 + *
761 + * @since 1.0.0
762 + *
763 + * @param {string} taxonomy
764 + *
765 + * @return {string}
766 + */
767 +function automatorwp_get_taxonomy_label( taxonomy ) {
768 +
769 + var label = '';
770 +
771 + if( automatorwp_taxonomy_exists( taxonomy ) ) {
772 + label = automatorwp_admin_functions.taxonomy_labels[taxonomy];
773 + }
774 +
775 + return label;
776 +}
777 +
778 +/**
779 + * Function to turn an object or a JSON object to a CSV file and force the download (Used on import/export tools)
780 + *
781 + * @since 1.0.0
782 + *
783 + * @param {Object} data
784 + * @param {string} filename
785 + */
786 +function automatorwp_download_csv( data, filename ) {
787 +
788 + // Convert JSON to CSV
789 + var csv = automatorwp_object_to_csv( data );
790 +
791 + automatorwp_download_file( csv, filename, 'csv' );
792 +
793 +}
794 +
795 +/**
796 + * Function to force the download of the given content (Used on import/export tools)
797 + *
798 + * @since 1.0.0
799 + *
800 + * @param {string} content
801 + * @param {string} filename
802 + * @param {string} extension
803 + * @param {string} mime_type
804 + * @param {string} charset
805 + */
806 +function automatorwp_download_file( content, filename, extension, mime_type = '', charset = '' ) {
807 +
808 + if( mime_type === undefined || mime_type === '' )
809 + mime_type = 'text/' + extension;
810 +
811 + if( charset === undefined || charset === '' )
812 + charset = 'utf-8';
813 +
814 + // Setup the file name
815 + var file = ( filename.length ? filename + '.' + extension : 'file.' + extension );
816 +
817 + var blob = new Blob( [content], { type: mime_type + ';charset=' + charset + ';' } );
818 +
819 + if (navigator.msSaveBlob) {
820 +
821 + // IE 10+
822 + navigator.msSaveBlob( blob, file );
823 +
824 + } else {
825 +
826 + var link = document.createElement("a");
827 +
828 + // Hide the link element
829 + link.style.visibility = 'hidden';
830 +
831 + // Check if browser supports HTML5 download attribute
832 + if ( link.download !== undefined ) {
833 +
834 + // Build the URL object
835 + var url = URL.createObjectURL( blob );
836 +
837 + // Update link attributes
838 + link.setAttribute( "href", url );
839 + link.setAttribute( "download", file );
840 +
841 + // Append the link element and trigger the click event
842 + document.body.appendChild( link );
843 +
844 + link.click(); // NOTE: Is not a jQuery element, so is safe to use click()
845 +
846 + // Finally remove the link element
847 + document.body.removeChild( link );
848 +
849 + }
850 + }
851 +
852 +}
853 +
854 +/**
855 + * Format an object into a CSV line
856 + *
857 + * @since 1.0.0
858 + *
859 + * @param {Object} obj
860 + *
861 + * @return {string}
862 + */
863 +function automatorwp_object_to_csv( obj ) {
864 +
865 + // Convert JSON to Object
866 + var array = typeof obj !== 'object' ? JSON.parse( obj ) : obj;
867 + var str = '';
868 +
869 + for ( var i = 0; i < array.length; i++ ) {
870 +
871 + var line = '';
872 +
873 + for ( var index in array[i] ) {
874 +
875 + // Separator
876 + if ( line !== '' ) {
877 + line += ',';
878 + }
879 +
880 + // Build a new line
881 + line += '"' + array[i][index] + '"';
882 + }
883 +
884 + // Append the line break
885 + str += line + '\r\n';
886 +
887 + }
888 +
889 + return str;
890 +
891 +}
892 +
893 +/**
894 + * Insert content at caret position
895 + *
896 + * @since 1.0.0
897 + *
898 + * @param {Object} input
899 + * @param {String} content
900 + */
901 +function automatorwp_insert_at_caret(input, content) {
902 +
903 + input.each(function() {
904 +
905 + if ( document.selection ) {
906 + // Internet Explorer
907 +
908 + this.focus(); // NOTE: Is not a jQuery element, so is safe to use focus()
909 + var sel = document.selection.createRange();
910 + sel.text = content;
911 + this.focus();
912 +
913 + } else if ( this.selectionStart || this.selectionStart == '0' ) {
914 + // Firefox/Chrome/Opera
915 +
916 + var startPos = this.selectionStart;
917 + var endPos = this.selectionEnd;
918 + var scrollTop = this.scrollTop;
919 + this.value = this.value.substring(0, startPos) +
920 + content + this.value.substring(endPos,this.value.length);
921 + this.focus();
922 + this.selectionStart = startPos + content.length;
923 + this.selectionEnd = startPos + content.length;
924 + this.scrollTop = scrollTop;
925 +
926 + } else {
927 + // If can't determine browser, only append at the end
928 +
929 + this.value += content;
930 + this.focus();
931 +
932 + }
933 + });
934 +
935 +}
936 +
937 +/**
938 + * Set caret position at the end of the input content
939 + *
940 + * @since 1.0.0
941 + *
942 + * @param {Object} input
943 + */
944 +function automatorwp_set_caret_at_end( input ) {
945 +
946 + // Get the input node
947 + input = input[0];
948 +
949 + var length = input.value.length;
950 +
951 + // For IE Only
952 + if ( document.selection ) {
953 +
954 + // Set focus
955 + input.focus(); // NOTE: Is not a jQuery element, so is safe to use focus()
956 +
957 + // Use IE Ranges
958 + var oSel = document.selection.createRange();
959 +
960 + // Reset position to 0 & then set at end
961 + oSel.moveStart('character', -length);
962 + oSel.moveStart('character', length);
963 + oSel.moveEnd('character', 0);
964 + oSel.select();
965 +
966 + } else if ( input.selectionStart || input.selectionStart == '0' ) {
967 +
968 + // Firefox/Chrome
969 + input.selectionStart = length;
970 + input.selectionEnd = length;
971 + input.focus(); // NOTE: Is not a jQuery element, so is safe to use focus()
972 + }
973 +
974 +}
975 +
976 +/**
977 + * Helper function to get a parameter from an URL
978 + *
979 + * @since 1.0.0
980 + *
981 + * @param {String} url
982 + * @param {String} param
983 + * @param default_value
984 + *
985 + * @return {String}
986 + */
987 +function automatorwp_get_url_param( url, param, default_value = false ) {
988 +
989 + var results = new RegExp('[\?&]' + param + '=([^&#]*)').exec( url );
990 +
991 + return results[1] || default_value;
992 +
993 +}
994 +
995 +/**
996 + * Helper function to check if given URL is a valid one
997 + *
998 + * @since 1.0.0
999 + *
1000 + * @param {String} url
1001 + *
1002 + * @return {boolean}
1003 + */
1004 +function automatorwp_is_valid_url( url ) {
1005 + var result = url.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,10}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
1006 + return ( result !== null )
1007 +}