Passed
Push — feature/mask-field-addon ( b6fc3b...de5f66 )
by Maria Daniel Deepak
03:11
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 13
	$emails = explode( ',', $email );
21 13
	if ( ! $multiple ) {
22 3
		$emails = array_slice( $emails, 0, 1 );
23 3
	}
24
25 13
	$cleaned_emails = array_map( __NAMESPACE__ . '\\sanitize_email_with_name', $emails );
26
27 13
	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 13
	$string = trim( $string );
41
42 13
	$bracket_pos = strpos( $string, '<' );
43 13
	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 8
	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 2
	if ( ! is_array( $values ) ) {
1 ignored issue
show
introduced by
The condition is_array($values) is always true.
Loading history...
107 1
		return;
108
	}
109
110 1
	if ( in_array( $current, $values ) ) {
111 1
		echo "checked='checked'";
112 1
	}
113 1
}
114
115
/**
116
 * Returns Comma separated values of the given array elements.
117
 *
118
 * Use $delimiter param to join elements other than `,`.
119
 *
120
 * @since 2.3.0
121
 *
122
 * @param array|string $value     The array whose values are to be joined.
123
 * @param string       $delimiter Optional. Default is `,`.
124
 *
125
 * @return string
126
 */
127
function join_array_elements_with_delimiter( $value, $delimiter = ',' ) {
128
	if ( is_array( $value ) ) {
129
		return implode( $delimiter, $value );
130
	}
131
132
	return is_string( $value ) ? $value : '';
1 ignored issue
show
introduced by
The condition is_string($value) is always true.
Loading history...
133
}
134
135
/**
136
 * Gets the User defined Date time format.
137
 *
138
 * @used-by \EmailLog\Core\UI\Setting\CoreSetting
139
 * @used-by \EmailLog\Util\render_auto_delete_logs_next_run_schedule()
140
 *
141
 * @since   2.3.0
142
 *
143
 * @return string
144
 */
145
function get_user_defined_date_time_format() {
146
	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

146
	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...
147
}
148
149
/**
150
 * Renders the next run auto delete logs schedule in Date and time format set within WordPress.
151
 *
152
 * @used-by \EmailLog\Addon\UI\Setting\DashboardWidget
153
 * @used-by \EmailLog\Core\UI\Component\AutoDeleteLogsSetting
154
 *
155
 * @since 2.3.0
156
 */
157
function render_auto_delete_logs_next_run_schedule() {
158
	?>
159
	<?php if ( wp_next_scheduled( 'el_scheduled_delete_logs' ) ) : ?>
160
		<p>
161
			<?php _e( 'Auto delete logs cron will be triggered next at', 'email-log' ); ?>:
162
			<?php $date_time_format = get_user_defined_date_time_format(); ?>
163
			<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

163
			<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...
164
		</p>
165
	<?php endif; ?>
166
	<?php
167
}
168
169
/**
170
 * Gets the value by key from the array.
171
 *
172
 * If the key isn't found, then null is returned.
173
 *
174
 * @since 2.3.0
175
 *
176
 * @param array  $array   The actual array.
177
 * @param string $key     The key whose value is to be retrieved.
178
 * @param string $default Optional.
179
 *
180
 * @return mixed|null
181
 */
182
function el_array_get( $array, $key, $default = null ) {
183
	return isset( $array[ $key ] ) ? $array[ $key ] : $default;
184
}
185
186
/**
187
 * Returns TRUE if the given search term is Advanced Search Term.
188
 *
189
 * @param string $term Search Term.
190
 *
191
 * @return bool
192
 */
193
function is_advanced_search_term( $term ) {
194
	if ( ! is_string( $term ) ) {
0 ignored issues
show
introduced by
The condition is_string($term) is always true.
Loading history...
195
		return false;
196
	}
197
198
	$predicates = get_advanced_search_term_predicates( $term );
199
200
	return ! empty( $predicates );
201
}
202
203
/**
204
 * Gets the Search Term Predicates.
205
 *
206
 * Example:
207
 *
208
 * If $term = to:[email protected] then,
209
 *
210
 * the output would be
211
 *
212
 * $output = array(
213
 *      'to' => [email protected]
214
 * )
215
 *
216
 * @since 2.3.0
217
 *
218
 * @param string $term Search Term.
219
 *
220
 * @return array
221
 */
222
function get_advanced_search_term_predicates( $term ) {
223
	if ( ! is_string( $term ) ) {
0 ignored issues
show
introduced by
The condition is_string($term) is always true.
Loading history...
224
		return array();
225
	}
226
227
	$predicates           = explode( ' ', $term );
228
	$predicates_organized = array();
229
230
	foreach ( $predicates as $predicate ) {
231
		$is_match = preg_match( '/(id|email|to|cc|bcc|reply-to):(.*)$/', $predicate, $matches );
232
		if ( 1 === $is_match ) {
233
			$predicates_organized[ $matches[1] ] = $matches[2];
234
		}
235
	}
236
237
	return $predicates_organized;
238
}
239
240
/**
241
 * Gets the Advanced Search URL.
242
 *
243
 * @since 2.3.0
244
 *
245
 * @return string
246
 */
247
function get_advanced_search_url() {
248
	$admin_url = get_admin_url( null, 'admin.php?page=email-log' );
249
250
	return add_query_arg( 'el_as', 1, $admin_url );
251
}
252
253
/**
254
 * Gets the Column labels to be used in LogList table.
255
 *
256
 * @since 2.3.0
257
 *
258
 * @param string $db_column
259
 *
260
 * @return string
261
 */
262
function get_column_label_by_db_column( $db_column ) {
263
	$labels = array(
264 1
		'id'          => __( 'ID', 'email-log' ),
265 1
		'sent_date'   => __( 'Sent at', 'email-log' ),
266 1
		'to'          => __( 'To', 'email-log' ), // EmailLog\Core\UI\ListTable::get_columns() uses `to`
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
267 1
		'to_email'    => __( 'To', 'email-log' ),
268 1
		'subject'     => __( 'Subject', 'email-log' ),
269 1
		'message'     => __( 'Message', 'email-log' ),
270 1
		'from'        => __( 'From', 'email-log' ),
271 1
		'cc'          => __( 'CC', 'email-log' ),
272 1
		'bcc'         => __( 'BCC', 'email-log' ),
273 1
		'reply-to'    => __( 'Reply To', 'email-log' ),
274 1
		'attachments' => __( 'Attachment', 'email-log' ),
275 1
		'attachment'  => __( 'Attachment', 'email-log' ),
276 1
	);
277
278
	/**
279
	 * Filters the Labels used through out the Email Log plugin.
280
	 *
281
	 * @since 2.3.0
282
	 *
283
	 * @param array $labels {
284
	 *                      List of DB Columns and its respective labels.
285
	 *
286
	 *                      Example:
287
	 *                      'id'          => __( 'ID', 'email-log' ),
288
	 *
289
	 * @type string $key    DB Column or any key for which a Label would be required. Accepts a internationalized string as Label.
290
	 *              }
291
	 */
292 1
	$labels = apply_filters( 'el_db_column_labels', $labels );
293
294 1
	if ( array_key_exists( $db_column, $labels ) ) {
295 1
		return $labels[ $db_column ];
296
	}
297
298
	return $db_column;
299
}
300
301
/**
302
 * Returns an array of Email Log columns.
303
 *
304
 * Keys are the column names in the DB.
305
 * This holds true except for CC, BCC & Reply To as they are put under one column `headers`.
306
 *
307
 * @since 2.4.0
308
 *
309
 * @return array Key value pair of Email Log columns.
310
 */
311
function get_email_log_columns() {
312
	return array(
313
		'sent_date'   => __( 'Sent at', '' ),
314
		'to_email'    => __( 'To', '' ),
315
		'subject'     => __( 'Subject', '' ),
316
		'from'        => __( 'From', '' ),
317
		'cc'          => __( 'CC', '' ),
318
		'bcc'         => __( 'BCC', '' ),
319
		'reply_to'    => __( 'Reply To', '' ),
320
		'message'     => __( 'Message', '' ),
321
		'attachments' => __( 'Attachment', '' ),
322
		'ip_address'  => __( 'IP Address', '' ),
323
	);
324
}
325
326
/**
327
 * Abstract of the core logic behind masking.
328
 *
329
 * @since 2.3.2
330
 *
331
 * @param string $value Content
332
 * @param string $mask_char Mask character.
333
 * @param int $percent The higher the percent, the more masking character on the email.
334
 *
335
 * @return string
336
 */
337
function get_masked_value( $value, $mask_char, $percent ) {
338
	$len        = strlen( $value );
339
	$mask_count = floor( $len * $percent / 100 );
340
	$offset     = floor( ( $len - $mask_count ) / 2 );
341
342
	return substr( $value, 0, $offset )
0 ignored issues
show
Bug introduced by
$offset of type double is incompatible with the type integer expected by parameter $length of substr(). ( Ignorable by Annotation )

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

342
	return substr( $value, 0, /** @scrutinizer ignore-type */ $offset )
Loading history...
343
	       . str_repeat( $mask_char, $mask_count )
0 ignored issues
show
Bug introduced by
$mask_count of type double is incompatible with the type integer expected by parameter $multiplier of str_repeat(). ( Ignorable by Annotation )

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

343
	       . str_repeat( $mask_char, /** @scrutinizer ignore-type */ $mask_count )
Loading history...
344
	       . substr( $value, $mask_count + $offset );
0 ignored issues
show
Bug introduced by
$mask_count + $offset of type double is incompatible with the type integer expected by parameter $start of substr(). ( Ignorable by Annotation )

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

344
	       . substr( $value, /** @scrutinizer ignore-type */ $mask_count + $offset );
Loading history...
345
}
346
347
/**
348
 * Masks Email address.
349
 *
350
 * @see http://www.webhostingtalk.com/showthread.php?t=1014672
351
 *
352
 * @since 2.3.2
353
 *
354
 * @uses get_masked_value()
355
 *
356
 * @param string $email Email to be masked.
357
 * @param string $mask_char Mask character.
358
 * @param int $percent The higher the percent, the more masking character on the email.
359
 *
360
 * @return string
361
 */
362
function mask_email( $email, $mask_char = '*', $percent = 50 ) {
363
	if ( ! is_email( $email ) ) {
364
		return $email;
365
	}
366
367
	list( $user, $domain ) = preg_split( "/@/", $email );
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal /@/ does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
368
369
	return sprintf( '%1$s@%2$s',
370
		get_masked_value( $user, $mask_char, $percent ),
371
		get_masked_value( $domain, $mask_char, $percent )
372
	);
373
}
374
375
/**
376
 * Mask Content fields.
377
 *
378
 * Content fields can be Subject or Email message.
379
 *
380
 * @since 2.3.2
381
 *
382
 * @uses get_masked_value()
383
 *
384
 * @param string $content The actual content.
385
 * @param string $mask_char Mask character.
386
 * @param int $percent The higher the percent, the more masking character on the email.
387
 *
388
 * @return string
389
 */
390
function mask_content( $content, $mask_char = '*', $percent = 80 ) {
391
	$content = wp_strip_all_tags( $content );
392
393
	return get_masked_value( $content, $mask_char, $percent );
394
}
395