Passed
Push — 215-feature/change-log-row-col... ( 97b142...156f56 )
by Maria Daniel Deepak
03:18
created

get_masked_value()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 3
dl 0
loc 8
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php namespace EmailLog\Util;
2
3
/**
4
 * Email Log Helper functions.
5
 * Some of these functions would be used the addons.
6
 */
7
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
8
9
/**
10
 * Perform additional sanitation of emails.
11
 *
12
 * @since 1.9
13
 *
14
 * @param string $email    Email string to be sanitized.
15
 * @param bool   $multiple (Optional) Should multiple emails be allowed. True by default.
16
 *
17
 * @return string Sanitized email.
18
 */
19
function sanitize_email( $email, $multiple = true ) {
20 9
	$emails = explode( ',', $email );
21 9
	if ( ! $multiple ) {
22 2
		$emails = array_slice( $emails, 0, 1 );
23 2
	}
24
25 9
	$cleaned_emails = array_map( __NAMESPACE__ . '\\sanitize_email_with_name', $emails );
26
27 9
	return implode( ', ', $cleaned_emails );
28
}
29
30
/**
31
 * Sanitize email with name.
32
 *
33
 * @since 1.9
34
 *
35
 * @param string $string Email string to be sanitized.
36
 *
37
 * @return string Sanitized email.
38
 */
39
function sanitize_email_with_name( $string ) {
40 9
	$string = trim( $string );
41
42 9
	$bracket_pos = strpos( $string, '<' );
43 9
	if ( false !== $bracket_pos ) {
44 5
		if ( $bracket_pos > 0 ) {
45 5
			$name = substr( $string, 0, $bracket_pos );
46 5
			$name = trim( $name );
47
48 5
			$email = substr( $string, $bracket_pos + 1 );
49 5
			$email = str_replace( '>', '', $email );
50
51 5
			return sanitize_text_field( $name ) . ' <' . \sanitize_email( $email ) . '>';
52
		}
53
	}
54
55 4
	return \sanitize_email( $string );
56
}
57
58
/**
59
 * Gets the columns to export logs.
60
 *
61
 * If the More Fields add-on is active, additional columns are returned.
62
 *
63
 * @since 2.0.0
64
 *
65
 * @return string[] List of Columns to export.
66
 */
67
function get_log_columns_to_export() {
68
69
	if ( is_plugin_active( 'email-log-more-fields/email-log-more-fields.php' ) ) {
70
		return array( 'id', 'sent_date', 'to_email', 'subject', 'from', 'cc', 'bcc', 'reply-to', 'attachment' );
71
	}
72
73
	return array( 'id', 'sent_date', 'to_email', 'subject' );
74
}
75
76
/**
77
 * Is it an admin request and not an ajax request.
78
 *
79
 * @since 2.1
80
 *
81
 * @return bool True if admin non ajax request, False otherwise.
82
 */
83
function is_admin_non_ajax_request() {
84
	if ( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() ) {
85
		return false;
86
	}
87
88
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
89
		return false;
90
	}
91
92
	return is_admin();
93
}
94
95
/**
96
 * Checks the Checkbox when values are present in a given array.
97
 *
98
 * Use this function in Checkbox fields.
99
 *
100
 * @since 2.1.0
101
 *
102
 * @param array  $values  List of all possible values.
103
 * @param string $current The current value to be checked.
104
 */
105
function checked_array( $values, $current ) {
106
	if ( ! is_array( $values ) ) {
107
		return;
108
	}
109
110
	if ( in_array( $current, $values ) ) {
111
		echo "checked='checked'";
112
	}
113
}
114
115
/**
116
 * Returns the Email failure SVG.
117
 *
118
 * @see https://www.flaticon.com/free-icon/do-not-disturb-rounded-sign_61072
119
 *
120
 * @since 2.4.0
121
 *
122
 * @return string
123
 */
124
function get_email_failed_svg() {
125
	return <<<EOT
126
<?xml version="1.0" encoding="iso-8859-1"?>
127
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
128
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
129
<svg class="el_sent_status--failed" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
130
	 width="15px" height="15px" viewBox="0 0 510 510" style="enable-background:new 0 0 510 510;" xml:space="preserve">
131
<g>
132
	<g id="do-not-disturb">
133
		<path d="M255,0C114.75,0,0,114.75,0,255s114.75,255,255,255s255-114.75,255-255S395.25,0,255,0z M51,255c0-112.2,91.8-204,204-204
134
			c45.9,0,89.25,15.3,124.95,43.35l-285.6,285.6C66.3,344.25,51,300.9,51,255z M255,459c-45.9,0-89.25-15.3-124.95-43.35
135
			L415.65,130.05C443.7,165.75,459,209.1,459,255C459,367.2,367.2,459,255,459z"/>
136
	</g>
137
</g>
138
<g>
139
</g>
140
<g>
141
</g>
142
<g>
143
</g>
144
<g>
145
</g>
146
<g>
147
</g>
148
<g>
149
</g>
150
<g>
151
</g>
152
<g>
153
</g>
154
<g>
155
</g>
156
<g>
157
</g>
158
<g>
159
</g>
160
<g>
161
</g>
162
<g>
163
</g>
164
<g>
165
</g>
166
<g>
167
</g>
168
</svg>
169
EOT;
170
}
171
172
/**
173
 * Returns the Email sent SVG.
174
 *
175
 * @see https://www.flaticon.com/free-icon/tick-inside-circle_61222
176
 *
177
 * @since 2.4.0
178
 *
179
 * @return string
180
 */
181
function get_email_sent_svg() {
182
	return <<<EOT
183
<?xml version="1.0" encoding="iso-8859-1"?>
184
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
185
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
186
<svg class="el_sent_status--sent" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
187
	 width="15px" height="15px" viewBox="0 0 510 510" style="enable-background:new 0 0 510 510;" xml:space="preserve">
188
<g>
189
	<g id="check-circle-outline">
190
		<path d="M150.45,206.55l-35.7,35.7L229.5,357l255-255l-35.7-35.7L229.5,285.6L150.45,206.55z M459,255c0,112.2-91.8,204-204,204
191
			S51,367.2,51,255S142.8,51,255,51c20.4,0,38.25,2.55,56.1,7.65l40.801-40.8C321.3,7.65,288.15,0,255,0C114.75,0,0,114.75,0,255
192
			s114.75,255,255,255s255-114.75,255-255H459z"/>
193
	</g>
194
</g>
195
<g>
196
</g>
197
<g>
198
</g>
199
<g>
200
</g>
201
<g>
202
</g>
203
<g>
204
</g>
205
<g>
206
</g>
207
<g>
208
</g>
209
<g>
210
</g>
211
<g>
212
</g>
213
<g>
214
</g>
215
<g>
216
</g>
217
<g>
218
</g>
219
<g>
220
</g>
221
<g>
222
</g>
223
<g>
224
</g>
225
</svg>
226
227
EOT;
228
229
}
230
231
/**
232
 * @param int $result
233
 *
234
 * @return string
235
 */
236
function get_log_row_class_by_result_code( $result ) {
237
	$log_row_classes = array(
238
		0 => 'el_email_sent_status--failed',
239
		1 => 'el_email_sent_status--sent',
240
	);
241
	if ( empty ( $result ) ) {
242
		return $log_row_classes[0];
243
	}
244
245
	$result = absint( $result );
246
	if ( array_key_exists( $result, $log_row_classes ) ) {
247
		return $log_row_classes[ $result ];
248
	}
249
250
	return $log_row_classes[0];
251
}
252
253
/**
254
 * Returns Comma separated values of the given array elements.
255
 *
256
 * Use $delimiter param to join elements other than `,`.
257
 *
258
 * @since 2.3.0
259
 *
260
 * @param array|string $value     The array whose values are to be joined.
261
 * @param string       $delimiter Optional. Default is `,`.
262
 *
263
 * @return string
264
 */
265
function join_array_elements_with_delimiter( $value, $delimiter = ',' ) {
266
	if ( is_array( $value ) ) {
267
		return implode( $delimiter, $value );
268
	}
269
270
	return is_string( $value ) ? $value : '';
271
}
272
273
/**
274
 * Gets the User defined Date time format.
275
 *
276
 * @used-by \EmailLog\Core\UI\Setting\CoreSetting
277
 * @used-by \EmailLog\Util\render_auto_delete_logs_next_run_schedule()
278
 *
279
 * @since   2.3.0
280
 *
281
 * @return string
282
 */
283
function get_user_defined_date_time_format() {
284
	return sprintf( '%1$s %2$s', get_option( 'date_format', 'Y-m-d' ), get_option( 'time_format', 'g:i a' ) );
0 ignored issues
show
Bug introduced by
It seems like get_option('date_format', 'Y-m-d') can also be of type false; however, parameter $args of sprintf() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

284
	return sprintf( '%1$s %2$s', /** @scrutinizer ignore-type */ get_option( 'date_format', 'Y-m-d' ), get_option( 'time_format', 'g:i a' ) );
Loading history...
285
}
286
287
/**
288
 * Renders the next run auto delete logs schedule in Date and time format set within WordPress.
289
 *
290
 * @used-by \EmailLog\Addon\UI\Setting\DashboardWidget
291
 * @used-by \EmailLog\Core\UI\Component\AutoDeleteLogsSetting
292
 *
293
 * @since 2.3.0
294
 */
295
function render_auto_delete_logs_next_run_schedule() {
296
	?>
297
	<?php if ( wp_next_scheduled( 'el_scheduled_delete_logs' ) ) : ?>
298
		<p>
299
			<?php _e( 'Auto delete logs cron will be triggered next at', 'email-log' ); ?>:
300
			<?php $date_time_format = get_user_defined_date_time_format(); ?>
301
			<strong><?php echo get_date_from_gmt( date( 'Y-m-d H:i:s', wp_next_scheduled( 'el_scheduled_delete_logs' ) ), $date_time_format ); ?></strong>
0 ignored issues
show
Bug introduced by
It seems like wp_next_scheduled('el_scheduled_delete_logs') can also be of type false; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

301
			<strong><?php echo get_date_from_gmt( date( 'Y-m-d H:i:s', /** @scrutinizer ignore-type */ wp_next_scheduled( 'el_scheduled_delete_logs' ) ), $date_time_format ); ?></strong>
Loading history...
302
		</p>
303
	<?php endif; ?>
304
	<?php
305
}
306
307
/**
308
 * Gets the value by key from the array.
309
 *
310
 * If the key isn't found, then null is returned.
311
 *
312
 * @since 2.3.0
313
 *
314
 * @param array  $array   The actual array.
315
 * @param string $key     The key whose value is to be retrieved.
316
 * @param string $default Optional.
317
 *
318
 * @return mixed|null
319
 */
320
function el_array_get( $array, $key, $default = null ) {
321
	return isset( $array[ $key ] ) ? $array[ $key ] : $default;
322
}
323
324
/**
325
 * Returns TRUE if the given search term is Advanced Search Term.
326
 *
327
 * @param string $term Search Term.
328
 *
329
 * @return bool
330
 */
331
function is_advanced_search_term( $term ) {
332
	if ( ! is_string( $term ) ) {
0 ignored issues
show
introduced by
The condition is_string($term) is always true.
Loading history...
333
		return false;
334
	}
335
336
	$predicates = get_advanced_search_term_predicates( $term );
337
338
	return ! empty( $predicates );
339
}
340
341
/**
342
 * Gets the Search Term Predicates.
343
 *
344
 * Example:
345
 *
346
 * If $term = to:[email protected] then,
347
 *
348
 * the output would be
349
 *
350
 * $output = array(
351
 *      'to' => [email protected]
352
 * )
353
 *
354
 * @since 2.3.0
355
 *
356
 * @param string $term Search Term.
357
 *
358
 * @return array
359
 */
360
function get_advanced_search_term_predicates( $term ) {
361
	if ( ! is_string( $term ) ) {
0 ignored issues
show
introduced by
The condition is_string($term) is always true.
Loading history...
362
		return array();
363
	}
364
365
	$predicates           = explode( ' ', $term );
366
	$predicates_organized = array();
367
368
	foreach ( $predicates as $predicate ) {
369
		$is_match = preg_match( '/(id|email|to|cc|bcc|reply-to):(.*)$/', $predicate, $matches );
370
		if ( 1 === $is_match ) {
371
			$predicates_organized[ $matches[1] ] = $matches[2];
372
		}
373
	}
374
375
	return $predicates_organized;
376
}
377
378
/**
379
 * Gets the Advanced Search URL.
380
 *
381
 * @since 2.3.0
382
 *
383
 * @return string
384
 */
385
function get_advanced_search_url() {
386
	$admin_url = get_admin_url( null, 'admin.php?page=email-log' );
387
388
	return add_query_arg( 'el_as', 1, $admin_url );
389
}
390
391
/**
392
 * Gets the Column labels to be used in LogList table.
393
 *
394
 * @since 2.3.2
395
 * @since 2.3.0
396
 *
397
 * @param string $db_column
398
 *
399
 * @return string
400
 */
401
function get_column_label_by_db_column( $db_column ) {
402
	// Standard column labels are on the right.
403
	// $mapping[ $non_standard_key ] => $standard_key
404
	$mapping = array(
405
		'to'          => 'to_email', // EmailLog\Core\UI\ListTable::get_columns() uses `to`
406
		'reply-to'    => 'reply_to',
407
		'attachment'  => 'attachments',
408
		'sent_status' => 'result',
409
	);
410
411
	$labels = get_email_log_columns();
412
413
	/**
414
	 * Filters the Labels used through out the Email Log plugin.
415
	 *
416
	 * @since 2.3.0
417
	 *
418
	 * @param array $labels {
419
	 *                      List of DB Columns and its respective labels.
420
	 *
421
	 *                      Example:
422
	 *                      'id'          => __( 'ID', 'email-log' ),
423
	 *
424
	 * @type string $key    DB Column or any key for which a Label would be required. Accepts a internationalized string as Label.
425
	 *              }
426
	 */
427
	$labels = apply_filters( 'el_db_column_labels', $labels );
428
429
	if ( array_key_exists( $db_column, $labels ) ) {
430
		return $labels[ $db_column ];
431
	} else if ( array_key_exists( $db_column, $mapping ) ) {
432
		$label_key = $mapping[ $db_column ];
433
		return $labels[ $label_key ];
434
	}
435
436
	return $db_column;
437
}
438
439
/**
440
 * Returns an array of Email Log columns.
441
 *
442
 * Keys are the column names in the DB.
443
 * This holds true except for CC, BCC & Reply To as they are put under one column `headers`.
444
 *
445
 * @since 2.3.2
446
 *
447
 * @return array Key value pair of Email Log columns.
448
 */
449
function get_email_log_columns() {
450
	return array(
451
		'id'          => __( 'ID', 'email-log' ),
452
		'sent_date'   => __( 'Sent at', 'email-log' ),
453
		'to_email'    => __( 'To', 'email-log' ),
454
		'subject'     => __( 'Subject', 'email-log' ),
455
		'message'     => __( 'Message', 'email-log' ),
456
		'from'        => __( 'From', 'email-log' ),
457
		'cc'          => __( 'CC', 'email-log' ),
458
		'bcc'         => __( 'BCC', 'email-log' ),
459
		'attachments' => __( 'Attachment', 'email-log' ),
460
		'ip_address'  => __( 'IP Address', 'email-log' ),
461
		'reply_to'    => __( 'Reply To', 'email-log' ),
462
		'result'      => __( 'Sent Status', 'email-log' ),
463
	);
464
}
465
466
/**
467
 * Abstract of the core logic behind masking.
468
 *
469
 * @since 2.3.2
470
 *
471
 * @param string $value     Content
472
 * @param string $mask_char Mask character.
473
 * @param int    $percent   The higher the percent, the more masking character on the email.
474
 *
475
 * @return string
476
 */
477
function get_masked_value( $value, $mask_char, $percent ) {
478
	$len        = strlen( $value );
479
	$mask_count = (int) floor( $len * $percent / 100 );
480
	$offset     = (int) floor( ( $len - $mask_count ) / 2 );
481
482
	return substr( $value, 0, $offset )
483
	       . str_repeat( $mask_char, $mask_count )
484
	       . substr( $value, $mask_count + $offset );
485
}
486
487
/**
488
 * Masks Email address.
489
 *
490
 * @see http://www.webhostingtalk.com/showthread.php?t=1014672
491
 * @since 2.3.2
492
 *
493
 * @uses get_masked_value()
494
 *
495
 * @param string $email     Email to be masked.
496
 * @param string $mask_char Mask character.
497
 * @param int    $percent   The higher the percent, the more masking character on the email.
498
 *
499
 * @return string
500
 */
501
function mask_email( $email, $mask_char = '*', $percent = 50 ) {
502
	if ( ! is_email( $email ) ) {
503
		return $email;
504
	}
505
506
	list( $user, $domain ) = preg_split( '/@/', $email );
507
508
	return sprintf( '%1$s@%2$s',
509
		get_masked_value( $user, $mask_char, $percent ),
510
		get_masked_value( $domain, $mask_char, $percent )
511
	);
512
}
513
514
/**
515
 * Mask Content fields.
516
 *
517
 * Content fields can be Subject or Email message.
518
 *
519
 * @since 2.3.2
520
 *
521
 * @uses get_masked_value()
522
 *
523
 * @param string $content   The actual content.
524
 * @param string $mask_char Mask character.
525
 * @param int    $percent   The higher the percent, the more masking character on the email.
526
 *
527
 * @return string
528
 */
529
function mask_content( $content, $mask_char = '*', $percent = 80 ) {
530
	$content = wp_strip_all_tags( $content );
531
532
	return get_masked_value( $content, $mask_char, $percent );
533
}
534