PluginProbe
Zoho Flow – No-Code Workflow Automation / trunk
Zoho Flow – No-Code Workflow Automation vtrunk
2.14.4 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 All 56 releases
zoho-flow / includes / utils.php

utils.php in Zoho Flow – No-Code Workflow Automation trunk, at includes/utils.php

461 lines 30.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly.
5 }
6
7 function zoho_flow_debug($message) {
8 if(WP_ZOHO_FLOW_DEBUG){
9 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Debug logging configuration, only used when WP_ZOHO_FLOW_DEBUG is enabled.
10 ini_set('log_errors', true);
11 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Debug logging configuration, only used when WP_ZOHO_FLOW_DEBUG is enabled.
12 ini_set('error_log', WP_ZOHO_FLOW_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'errors.log');
13 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log, WordPress.PHP.DevelopmentFunctions.error_log_print_r -- Debug logging, only used when WP_ZOHO_FLOW_DEBUG is enabled.
14 error_log(print_r($message, true));
15 }
16 }
17
18 function zoho_flow_execute_webhook($url, $post_params, $file_params){
19
20 $args = array();
21 if(empty($file_params)){
22 $args['headers'] = array(
23 'content-type' => 'application/json',
24 );
25 $args['body'] = json_encode($post_params);
26
27 }
28 else{
29
30 $mime_map = [
31 'video/3gpp2' => '3g2',
32 'video/3gp' => '3gp',
33 'video/3gpp' => '3gp',
34 'application/x-compressed' => '7zip',
35 'audio/x-acc' => 'aac',
36 'audio/ac3' => 'ac3',
37 'application/postscript' => 'ai',
38 'audio/x-aiff' => 'aif',
39 'audio/aiff' => 'aif',
40 'audio/x-au' => 'au',
41 'video/x-msvideo' => 'avi',
42 'video/msvideo' => 'avi',
43 'video/avi' => 'avi',
44 'application/x-troff-msvideo' => 'avi',
45 'application/macbinary' => 'bin',
46 'application/mac-binary' => 'bin',
47 'application/x-binary' => 'bin',
48 'application/x-macbinary' => 'bin',
49 'image/bmp' => 'bmp',
50 'image/x-bmp' => 'bmp',
51 'image/x-bitmap' => 'bmp',
52 'image/x-xbitmap' => 'bmp',
53 'image/x-win-bitmap' => 'bmp',
54 'image/x-windows-bmp' => 'bmp',
55 'image/ms-bmp' => 'bmp',
56 'image/x-ms-bmp' => 'bmp',
57 'application/bmp' => 'bmp',
58 'application/x-bmp' => 'bmp',
59 'application/x-win-bitmap' => 'bmp',
60 'application/cdr' => 'cdr',
61 'application/coreldraw' => 'cdr',
62 'application/x-cdr' => 'cdr',
63 'application/x-coreldraw' => 'cdr',
64 'image/cdr' => 'cdr',
65 'image/x-cdr' => 'cdr',
66 'zz-application/zz-winassoc-cdr' => 'cdr',
67 'application/mac-compactpro' => 'cpt',
68 'application/pkix-crl' => 'crl',
69 'application/pkcs-crl' => 'crl',
70 'application/x-x509-ca-cert' => 'crt',
71 'application/pkix-cert' => 'crt',
72 'text/css' => 'css',
73 'text/x-comma-separated-values' => 'csv',
74 'text/comma-separated-values' => 'csv',
75 'application/vnd.msexcel' => 'csv',
76 'application/x-director' => 'dcr',
77 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
78 'application/x-dvi' => 'dvi',
79 'message/rfc822' => 'eml',
80 'application/x-msdownload' => 'exe',
81 'video/x-f4v' => 'f4v',
82 'audio/x-flac' => 'flac',
83 'video/x-flv' => 'flv',
84 'image/gif' => 'gif',
85 'application/gpg-keys' => 'gpg',
86 'application/x-gtar' => 'gtar',
87 'application/x-gzip' => 'gzip',
88 'application/mac-binhex40' => 'hqx',
89 'application/mac-binhex' => 'hqx',
90 'application/x-binhex40' => 'hqx',
91 'application/x-mac-binhex40' => 'hqx',
92 'text/html' => 'html',
93 'image/x-icon' => 'ico',
94 'image/x-ico' => 'ico',
95 'image/vnd.microsoft.icon' => 'ico',
96 'text/calendar' => 'ics',
97 'application/java-archive' => 'jar',
98 'application/x-java-application' => 'jar',
99 'application/x-jar' => 'jar',
100 'image/jp2' => 'jp2',
101 'video/mj2' => 'jp2',
102 'image/jpx' => 'jp2',
103 'image/jpm' => 'jp2',
104 'image/jpeg' => 'jpeg',
105 'image/pjpeg' => 'jpeg',
106 'application/x-javascript' => 'js',
107 'application/json' => 'json',
108 'text/json' => 'json',
109 'application/vnd.google-earth.kml+xml' => 'kml',
110 'application/vnd.google-earth.kmz' => 'kmz',
111 'text/x-log' => 'log',
112 'audio/x-m4a' => 'm4a',
113 'audio/mp4' => 'm4a',
114 'application/vnd.mpegurl' => 'm4u',
115 'audio/midi' => 'mid',
116 'application/vnd.mif' => 'mif',
117 'video/quicktime' => 'mov',
118 'video/x-sgi-movie' => 'movie',
119 'audio/mpeg' => 'mp3',
120 'audio/mpg' => 'mp3',
121 'audio/mpeg3' => 'mp3',
122 'audio/mp3' => 'mp3',
123 'video/mp4' => 'mp4',
124 'video/mpeg' => 'mpeg',
125 'application/oda' => 'oda',
126 'audio/ogg' => 'ogg',
127 'video/ogg' => 'ogg',
128 'application/ogg' => 'ogg',
129 'application/x-pkcs10' => 'p10',
130 'application/pkcs10' => 'p10',
131 'application/x-pkcs12' => 'p12',
132 'application/x-pkcs7-signature' => 'p7a',
133 'application/pkcs7-mime' => 'p7c',
134 'application/x-pkcs7-mime' => 'p7c',
135 'application/x-pkcs7-certreqresp' => 'p7r',
136 'application/pkcs7-signature' => 'p7s',
137 'application/pdf' => 'pdf',
138 'application/octet-stream' => 'pdf',
139 'application/x-x509-user-cert' => 'pem',
140 'application/x-pem-file' => 'pem',
141 'application/pgp' => 'pgp',
142 'application/x-httpd-php' => 'php',
143 'application/php' => 'php',
144 'application/x-php' => 'php',
145 'text/php' => 'php',
146 'text/x-php' => 'php',
147 'application/x-httpd-php-source' => 'php',
148 'image/png' => 'png',
149 'image/x-png' => 'png',
150 'application/powerpoint' => 'ppt',
151 'application/vnd.ms-powerpoint' => 'ppt',
152 'application/vnd.ms-office' => 'ppt',
153 'application/msword' => 'ppt',
154 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
155 'application/x-photoshop' => 'psd',
156 'image/vnd.adobe.photoshop' => 'psd',
157 'audio/x-realaudio' => 'ra',
158 'audio/x-pn-realaudio' => 'ram',
159 'application/x-rar' => 'rar',
160 'application/rar' => 'rar',
161 'application/x-rar-compressed' => 'rar',
162 'audio/x-pn-realaudio-plugin' => 'rpm',
163 'application/x-pkcs7' => 'rsa',
164 'text/rtf' => 'rtf',
165 'text/richtext' => 'rtx',
166 'video/vnd.rn-realvideo' => 'rv',
167 'application/x-stuffit' => 'sit',
168 'application/smil' => 'smil',
169 'text/srt' => 'srt',
170 'image/svg+xml' => 'svg',
171 'application/x-shockwave-flash' => 'swf',
172 'application/x-tar' => 'tar',
173 'application/x-gzip-compressed' => 'tgz',
174 'image/tiff' => 'tiff',
175 'text/plain' => 'txt',
176 'text/x-vcard' => 'vcf',
177 'application/videolan' => 'vlc',
178 'text/vtt' => 'vtt',
179 'audio/x-wav' => 'wav',
180 'audio/wave' => 'wav',
181 'audio/wav' => 'wav',
182 'application/wbxml' => 'wbxml',
183 'video/webm' => 'webm',
184 'image/webp' => 'webp',
185 'audio/x-ms-wma' => 'wma',
186 'application/wmlc' => 'wmlc',
187 'video/x-ms-wmv' => 'wmv',
188 'video/x-ms-asf' => 'wmv',
189 'application/xhtml+xml' => 'xhtml',
190 'application/excel' => 'xl',
191 'application/msexcel' => 'xls',
192 'application/x-msexcel' => 'xls',
193 'application/x-ms-excel' => 'xls',
194 'application/x-excel' => 'xls',
195 'application/x-dos_ms_excel' => 'xls',
196 'application/xls' => 'xls',
197 'application/x-xls' => 'xls',
198 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
199 'application/vnd.ms-excel' => 'xlsx',
200 'application/xml' => 'xml',
201 'text/xml' => 'xml',
202 'text/xsl' => 'xsl',
203 'application/xspf+xml' => 'xspf',
204 'application/x-compress' => 'z',
205 'application/x-zip' => 'zip',
206 'application/zip' => 'zip',
207 'application/x-zip-compressed' => 'zip',
208 'application/s-compressed' => 'zip',
209 'multipart/x-zip' => 'zip',
210 'text/x-scriptzsh' => 'zsh',
211 ];
212 $boundary = wp_generate_password(24); // Just a random string, use something better than wp_generate_password() though.
213
214
215 $payload = '';
216
217 $args['headers'] = array(
218 'content-type' => 'multipart/form-data; boundary=' . $boundary
219 );
220
221 // First, add the standard POST fields:
222 foreach ( $post_params as $name => $value ) {
223 $payload .= '--' . $boundary;
224 $payload .= "\r\n";
225 $payload .= 'Content-Disposition: form-data; name="' . $name . '"' . "\r\n\r\n";
226 $payload .= $value;
227 $payload .= "\r\n";
228 }
229
230 // Upload the file
231 $file_info = new finfo(FILEINFO_MIME_TYPE);
232 foreach ( $file_params as $name => $file ) {
233 $mime_type = $file_info->buffer($file);
234 $extn = $mime_map[$mime_type];
235
236 $payload .= '--' . $boundary;
237 $payload .= "\r\n";
238 $payload .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $name . '.' . $extn . '"' . "\r\n";
239 $payload .= 'Content-Type: ' . $mime_type . "\r\n";
240 $payload .= "\r\n";
241 $payload .= $file;
242 $payload .= "\r\n";
243 }
244 $payload .= '--' . $boundary . '--';
245 $args['body'] = $payload;
246
247 }
248 $args['timeout'] = '5';
249 $zf_boost_speed_state = get_option('zf_boost_speed', 'off');
250
251 if ( ( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON ) || ( 'off' === $zf_boost_speed_state ) ) {
252 zoho_flow_run_webhook( $url, $args );
253 }
254 // elseif ( !wp_next_scheduled('zoho_flow_run_webhook', array( $url, $args ) ) ) {
255 // wp_schedule_single_event(time(), 'zoho_flow_run_webhook', array( $url, $args ) );
256 // }
257 else{
258 wp_schedule_single_event(time(), 'zoho_flow_run_webhook', array( $url, $args ) );
259 }
260
261
262 }
263
264 add_action('zoho_flow_run_webhook', 'zoho_flow_run_webhook', 10, 2);
265
266 function zoho_flow_run_webhook( $url, $args ){
267 $hook_status_code = zoho_flow_invoke_webhook_url( $url, $args );
268 if( 200 !== $hook_status_code ){
269 if( 410 === $hook_status_code ){
270 zoho_flow_delete_webhook( $url );
271 }
272 elseif( empty( $hook_status_code ) || 400 <= $hook_status_code ){
273 $timestamp = time() + 300; // Set it to run 5 mins from now
274 if ( !wp_next_scheduled('zoho_flow_rerun_after_5_mins', array( $url, $args ) ) ) {
275 wp_schedule_single_event($timestamp, 'zoho_flow_rerun_after_5_mins', array( $url, $args ) );
276 }
277 }
278 }
279 }
280
281 function zoho_flow_invoke_webhook_url( $url, $args ){
282 $res = wp_remote_post( $url, $args );
283 $response_code = wp_remote_retrieve_response_code( $res );
284 return $response_code;
285 }
286
287 add_action('zoho_flow_rerun_after_5_mins', 'zoho_flow_5_mins_rerun', 10, 2);
288
289 function zoho_flow_5_mins_rerun( $url, $args ) {
290
291 $args['timeout'] = '10'; //Increasing the timeout for rerun calls.
292
293 $hook_status_code = zoho_flow_invoke_webhook_url( $url, $args );
294 if( 200 !== $hook_status_code ){
295 if( 410 === $hook_status_code ){
296 zoho_flow_delete_webhook( $url );
297 }
298 elseif( empty( $hook_status_code ) or 400 <= $hook_status_code ){
299 $timestamp = time() + 600; // Set it to run 10 mins from now
300 if ( !wp_next_scheduled('zoho_flow_rerun_after_10_mins', array( $url, $args ) ) ) {
301 wp_schedule_single_event($timestamp, 'zoho_flow_rerun_after_10_mins', array( $url, $args ) );
302 }
303 }
304 }
305 }
306
307 add_action('zoho_flow_rerun_after_10_mins', 'zoho_flow_10_mins_rerun', 10, 2);
308
309 function zoho_flow_10_mins_rerun( $url, $args ) {
310 $hook_status_code = zoho_flow_invoke_webhook_url( $url, $args );
311 if( 200 !== $hook_status_code ){
312 if( 410 === $hook_status_code ){
313 zoho_flow_delete_webhook( $url );
314 }
315 elseif( empty( $hook_status_code ) || 400 <= $hook_status_code ){
316 $timestamp = time() + 1800; // Set it to run 30 mins from now
317 if ( !wp_next_scheduled('zoho_flow_rerun_after_30_mins', array( $url, $args ) ) ) {
318 wp_schedule_single_event($timestamp, 'zoho_flow_rerun_after_30_mins', array( $url, $args ) );
319 }
320 }
321 }
322 }
323
324 add_action('zoho_flow_rerun_after_30_mins', 'zoho_flow_30_mins_rerun', 10, 2);
325
326 function zoho_flow_30_mins_rerun( $url, $args ) {
327 $hook_status_code = zoho_flow_invoke_webhook_url( $url, $args );
328 if( 200 !== $hook_status_code ){
329 if( 410 === $hook_status_code ){
330 zoho_flow_delete_webhook( $url );
331 }
332 elseif( empty( $hook_status_code ) or 400 <= $hook_status_code ){
333 $timestamp = time() + 3600; // Set it to run 60 mins from now
334 if ( !wp_next_scheduled('zoho_flow_rerun_after_60_mins', array( $url, $args ) ) ) {
335 wp_schedule_single_event($timestamp, 'zoho_flow_rerun_after_60_mins', array( $url, $args ) );
336 }
337 }
338 }
339 }
340
341 add_action('zoho_flow_rerun_after_60_mins', 'zoho_flow_60_mins_rerun', 10, 2);
342
343 function zoho_flow_60_mins_rerun( $url, $args ) {
344 $hook_status_code = zoho_flow_invoke_webhook_url( $url, $args );
345 if( 200 !== $hook_status_code ){
346 if( 410 === $hook_status_code ){
347 zoho_flow_delete_webhook( $url );
348 }
349 elseif( empty( $hook_status_code ) or 400 <= $hook_status_code ){
350 // Can be used for further cycles
351 }
352 }
353 }
354
355 function zoho_flow_delete_webhook( $url ){
356 $args = array(
357 'post_type' => WP_ZOHO_FLOW_WEBHOOK_POST_TYPE,
358 'posts_per_page' => -1,
359 'fields' => 'ids',
360 'cache_results' => false,
361 'update_post_meta_cache' => false,
362 'update_post_term_cache' => false,
363 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Required to find webhooks by URL; indexed meta key.
364 'meta_query' => array(
365 array(
366 'key' => 'url',
367 'value' => $url,
368 'compare' => '='
369 )
370 )
371 );
372 $webhook_ids = get_posts( $args );
373 foreach ($webhook_ids as $webhook_id) {
374 wp_delete_post( $webhook_id, true );
375 }
376 }
377
378 function zoho_flow_convert_php_java_datepattern($php_pattern){
379 //https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
380 //https://www.php.net/manual/en/function.date.php
381 $format_mapping = array(
382
383 'd' => 'dd', //Day of the month, 2 digits with leading zeros 01 to 31
384 'D' => 'E', //A textual representation of a day, three letters Mon through Sun
385 'j' => 'd', //Day of the month without leading zeros 1 to 31 ; l (lowercase L) A full textual representation of the day of the week Sunday through Saturday
386 'N' => 'u', //ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0) 1 (for Monday) through 7 (for Sunday)
387 'S' => '', //English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with j
388 'w' => 'F', //Numeric representation of the day of the week 0 (for Sunday) through 6 (for Saturday)
389 'z' => 'D', //The day of the year (starting from 0) 0 through 365
390 // Week --- ---
391 'W' => 'w', //ISO-8601 week number of year, weeks starting on Monday Example: 42 (the 42nd week in the year)
392 //Month --- ---
393 'F' => 'MMMMM', //A full textual representation of a month, such as January or March January through December
394 'm' => 'MM', //Numeric representation of a month, with leading zeros 01 through 12
395 'M' => 'MMM', //A short textual representation of a month, three letters Jan through Dec
396 'n' => 'M', //Numeric representation of a month, without leading zeros 1 through 12
397 't' => '', //Number of days in the given month 28 through 31
398 // Year --- ---
399 'L' => '', //Whether it's a leap year 1 if it is a leap year, 0 otherwise.
400 'o' => 'Y', //ISO-8601 week-numbering year. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0) Examples: 1999 or 2003
401 'Y' => 'yyyy', //A full numeric representation of a year, 4 digits Examples: 1999 or 2003
402 'y' => 'yy', //A two digit representation of a year Examples: 99 or 03
403 // Time --- ---
404 'a' => 'a', //Lowercase Ante meridiem and Post meridiem am or pm
405 'A' => 'a', //Uppercase Ante meridiem and Post meridiem AM or PM
406 'B' => '', //Swatch Internet time 000 through 999
407 'g' => 'h', //12-hour format of an hour without leading zeros 1 through 12
408 'G' => 'H', //24-hour format of an hour without leading zeros 0 through 23
409 'h' => 'hh', //12-hour format of an hour with leading zeros 01 through 12
410 'H' => 'HH', //24-hour format of an hour with leading zeros 00 through 23
411 'i' => 'mm', //Minutes with leading zeros 00 to 59
412 's' => 'ss', //Seconds with leading zeros 00 through 59
413 'u' => '', //Microseconds (added in PHP 5.2.2). Note that date() will always generate 000000 since it takes an integer parameter, whereas DateTime::format() does support microseconds if DateTime was created with microseconds. Example: 654321
414 'v' => 'S', //Milliseconds (added in PHP 7.0.0). Same note applies as for u. Example: 654
415 // Timezone --- ---
416 'e' => 'z', //Timezone identifier (added in PHP 5.1.0) Examples: UTC, GMT, Atlantic/Azores
417 'I' => '', //(capital i) Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise.
418 'O' => 'Z', //Difference to Greenwich time (GMT) without colon between hours and minutes Example: +0200
419 'P' => 'XXX', //Difference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3) Example: +02:00
420 'T' => 'z', //Timezone abbreviation Examples: EST, MDT ...
421 'Z' => 'Z', //Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. -43200 through 50400
422 // Full Date/Time --- ---
423 'c' => "yyyy-MM-dd'T'HH:mm:ssXXX", //ISO 8601 date (added in PHP 5) 2004-02-12T15:19:21+00:00
424 'r' => '', //» RFC 2822 formatted date Example: Thu, 21 Dec 2000 16:01:07 +0200
425 'U' => '', //Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) See also time()
426 );
427
428 $pattern_chars = str_split($php_pattern);
429 $java_pattern = '';
430 foreach ($pattern_chars as $char) {
431 if(!$escape && array_key_exists($char, $format_mapping)){
432 $java_pattern = $java_pattern . $format_mapping[$char];
433 }
434 else if($escape){
435 $java_pattern = $java_pattern . $char;
436 $escape = false;
437 }
438 else if($char == '\\'){
439 $escape = true;
440 if(!$string_sequence){
441 $java_pattern = $java_pattern . "'";
442 $string_sequence = true;
443 }
444 }
445 else if($string_sequence){
446 if(preg_match("/^[a-zA-Z]$/", $char)){
447 $java_pattern = $java_pattern . '\\' . $char;
448 }
449 else{
450 $java_pattern = $java_pattern . "'";
451 $java_pattern = $java_pattern . $char;
452 }
453 $string_sequence = false;
454 }
455 else{
456 $java_pattern = $java_pattern . $char;
457 }
458 }
459 return $java_pattern;
460 }
461