Test Failed
Push — master ( dc11f8...b6268a )
by Stiofan
54s
created

GeoDir_Privacy_Exporters   F

Complexity

Total Complexity 96

Size/Duplication

Total Lines 390
Duplicated Lines 20.77 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 0
Metric Value
dl 81
loc 390
rs 1.5789
c 0
b 0
f 0
wmc 96
lcom 0
cbo 1

4 Methods

Rating   Name   Duplication   Size   Complexity  
B post_data_exporter() 0 35 4
F get_post_personal_data() 45 250 75
B posts_by_author() 0 33 6
C review_data_exporter() 36 50 11

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like GeoDir_Privacy_Exporters often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use GeoDir_Privacy_Exporters, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Personal data exporters.
4
 *
5
 * @since 1.2.26
6
 * @package GeoDirectory
7
 */
8
9
defined( 'ABSPATH' ) || exit;
10
11
/**
12
 * GeoDir_Privacy_Exporters Class.
13
 */
14
class GeoDir_Privacy_Exporters {
15
	/**
16
	 * Finds and exports data which could be used to identify a person from GeoDirectory data associated with an email address.
17
	 *
18
	 * Posts are exported in blocks of 10 to avoid timeouts.
19
	 *
20
	 * @since 1.2.26
21
	 * @param string $email_address The user email address.
22
	 * @param int    $page  Page.
23
	 * @return array An array of personal data in name value pairs
24
	 */
25
	public static function post_data_exporter( $email_address, $page ) {
26
		$post_type 		= GeoDir_Privacy::exporter_post_type();
27
28
		$done           = false;
0 ignored issues
show
Unused Code introduced by
$done is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
29
		$page           = (int) $page;
30
		$data_to_export = array();
31
32
		$posts 			= self::posts_by_author( $email_address, $post_type, $page );
33
34
		if ( 0 < count( $posts ) ) {
35
			$obj_post_type = get_post_type_object( $post_type );
36
37
			foreach ( $posts as $post_ID ) {
38
				$gd_post = geodir_get_post_info( $post_ID );
39
				if ( empty( $gd_post ) ) {
40
					continue;
41
				}
42
43
				$data_to_export[] = array(
44
					'group_id'    => 'geodirectory-post-' . $post_type,
45
					'group_label' => __( $obj_post_type->labels->name, 'geodirectory' ),
46
					'item_id'     => 'post-' . $post_ID,
47
					'data'        => self::get_post_personal_data( $gd_post ),
0 ignored issues
show
Documentation introduced by
$gd_post is of type object|boolean, but the function expects a object<WP_Post>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
48
				);
49
			}
50
			$done = 10 > count( $posts );
51
		} else {
52
			$done = true;
53
		}
54
55
		return array(
56
			'data' => $data_to_export,
57
			'done' => $done,
58
		);
59
	}
60
61
	/**
62
	 * Get personal data (key/value pairs) for an post object.
63
	 *
64
	 * @since 1.6.26
65
	 * @param WP_Post $gd_post The post object.
66
	 * @return array
67
	 */
68
	protected static function get_post_personal_data( $gd_post ) {
69
		$post_categories = array();
70
		$post_tags = array();
71
		$default_category = '';
72
73
		$cat_taxonomy = $gd_post->post_type . 'category';
74
		$tag_taxonomy = $gd_post->post_type . '_tags';
75
76
		$post_terms = wp_get_post_terms( $gd_post->ID, array( $cat_taxonomy, $tag_taxonomy ) );
77
		if ( ! empty( $post_terms ) && ! is_wp_error( $post_terms ) ) {
78
			foreach ( $post_terms as $term ) {
79
				if ( $term->taxonomy == $cat_taxonomy ) {
80
					$post_categories[] = $term->name;
81
				} else {
82
					$post_tags[] = $term->name;
83
				}
84
85
				if ( $gd_post->default_category == $term->term_id ) {
86
					$default_category = $term->name;
87
				}
88
			}
89
		}
90
91
		$personal_data = array();
92
		$personal_data[] = array(
93
			'name'  => __( 'Post ID', 'geodirectory' ),
94
			'value' => $gd_post->ID,
95
		);
96
		$personal_data[] = array(
97
			'name'  => __( 'Post Title', 'geodirectory' ),
98
			'value' => $gd_post->post_title,
99
		);
100
		$personal_data[] = array(
101
			'name'  => __( 'Post Date', 'geodirectory' ),
102
			'value' => $gd_post->post_date,
103
		);
104
		$personal_data[] = array(
105
			'name'  => __( 'Post Status', 'geodirectory' ),
106
			'value' => $gd_post->post_status,
107
		);
108
		$personal_data[] = array(
109
			'name'  => __( 'Post Categories', 'geodirectory' ),
110
			'value' => ( ! empty( $post_categories ) ? implode( ', ', $post_categories ) : '' ),
111
		);
112
		if ( $default_category ) {
113
			$personal_data[] = array(
114
				'name'  => __( 'Default Category', 'geodirectory' ),
115
				'value' => $default_category,
116
			);
117
		}
118 View Code Duplication
		if ( ! empty( $post_tags ) ) {
119
			$personal_data[] = array(
120
				'name'  => __( 'Post Tags', 'geodirectory' ),
121
				'value' => implode( ', ', $post_tags ),
122
			);
123
		}
124
		$personal_data[] = array(
125
			'name'  => __( 'Post URL', 'geodirectory' ),
126
			'value' => get_permalink( $gd_post->ID ),
127
		);
128
129
		$custom_fields 	= geodir_post_custom_fields( $gd_post->package_id, 'all', $gd_post->post_type );
130
		$post_fields 	= array_keys( (array) $gd_post );
131
132
		foreach ( $custom_fields as $key => $field ) {
133
			$field_name 			= ! empty( $field['htmlvar_name'] ) ? $field['htmlvar_name'] : '';
134
			if ( empty( $field_name ) ) {
135
				continue;
136
			}
137
138
			$field 					= stripslashes_deep( $field );
139
140
			$extra_fields 			= ! empty( $field['extra_fields'] ) ? $field['extra_fields'] : array();
141
			$data_type              = $field['data_type'];
0 ignored issues
show
Unused Code introduced by
$data_type is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
142
			$field_type             = $field['field_type'];
143
			$field_title			= $field['site_title'];
144
			if ( $field_name == 'post' ) {
145
				$field_name = 'post_address';
146
			}
147
148
			if ( ! in_array( $field_name, $post_fields ) ) {
149
				continue;
150
			}
151
152
			$name = $field_title;
153
			$value = '';
154
			switch ( $field_type ) {
155
				case 'address':
156
					$location_allowed = function_exists( 'geodir_cpt_no_location' ) && geodir_cpt_no_location( $gd_post->post_type ) ? false : true;
157
					if ( $location_allowed && ! empty( $gd_post->post_country ) && ! empty( $gd_post->post_region ) && ! empty( $gd_post->post_city ) ) {
158
						$personal_data[] = array(
159
							'name'  => __( 'Post Address', 'geodirectory' ),
160
							'value' => $gd_post->post_address,
161
						);
162
						$personal_data[] = array(
163
							'name'  => __( 'Post City', 'geodirectory' ),
164
							'value' => $gd_post->post_city,
165
						);
166
						$personal_data[] = array(
167
							'name'  => __( 'Post Region', 'geodirectory' ),
168
							'value' => $gd_post->post_region,
169
						);
170
						$personal_data[] = array(
171
							'name'  => __( 'Post Country', 'geodirectory' ),
172
							'value' => $gd_post->post_country,
173
						);
174
						$personal_data[] = array(
175
							'name'  => __( 'Post Zip', 'geodirectory' ),
176
							'value' => $gd_post->post_zip,
177
						);
178
						$personal_data[] = array(
179
							'name'  => __( 'Post Latitude', 'geodirectory' ),
180
							'value' => $gd_post->post_latitude,
181
						);
182
						$personal_data[] = array(
183
							'name'  => __( 'Post Longitude', 'geodirectory' ),
184
							'value' => $gd_post->post_longitude,
185
						);
186
					}
187
				break;
188
				case 'checkbox':
189
					if ( ! empty( $gd_post->{$field_name} ) ) {
190
						$value = __( 'Yes', 'geodirectory' );
191
					} else {
192
						$value = __( 'No', 'geodirectory' );
193
					}
194
					break;
195
				case 'datepicker':
196
					$value = $gd_post->{$field_name} != '0000-00-00' ? $gd_post->{$field_name} : '';
197
					break;
198
				case 'radio':
199
					if ( $gd_post->{$field_name} !== '' ) {
200
						if ( $gd_post->{$field_name} == 'f' || $gd_post->{$field_name} == '0') {
201
							$value = __( 'No', 'geodirectory' );
202
						} else if ( $gd_post->{$field_name} == 't' || $gd_post->{$field_name} == '1') {
203
							$value = __( 'Yes', 'geodirectory' );
204 View Code Duplication
						} else {
205
							if ( !empty( $field['option_values'] ) ) {
206
								$cf_option_values = geodir_string_values_to_options(stripslashes_deep( $field['option_values'] ), true );
207
								if ( ! empty( $cf_option_values ) ) {
208
									foreach ( $cf_option_values as $cf_option_value ) {
209
										if ( isset( $cf_option_value['value'] ) && $cf_option_value['value'] == $gd_post->{$field_name} ) {
210
											$value = $cf_option_value['label'];
211
										}
212
									}
213
								}
214
							}
215
						}
216
					}
217
					break;
218
				case 'select':
219
					$value = __( $gd_post->{$field_name}, 'geodirectory');
220 View Code Duplication
					if ( !empty( $field['option_values'] ) ) {
221
						$cf_option_values = geodir_string_values_to_options(stripslashes_deep( $field['option_values'] ), true );
222
						if ( ! empty( $cf_option_values ) ) {
223
							foreach ( $cf_option_values as $cf_option_value ) {
224
								if ( isset( $cf_option_value['value'] ) && $cf_option_value['value'] == $gd_post->{$field_name} ) {
225
									$value = $cf_option_value['label'];
226
								}
227
							}
228
						}
229
					}
230
					break;
231
				case 'multiselect':
232
					$field_values = explode( ',', trim( $gd_post->{$field_name}, "," ) );
233
					if ( is_array( $field_values ) ) {
234
						$field_values = array_map( 'trim', $field_values );
235
					}
236
					$values = array();
237 View Code Duplication
					if ( ! empty( $field['option_values'] ) ) {
238
						$cf_option_values = geodir_string_values_to_options(stripslashes_deep( $field['option_values'] ), true );
239
240
						if ( ! empty( $cf_option_values ) ) {
241
							foreach ( $cf_option_values as $cf_option_value ) {
242
								if ( isset( $cf_option_value['value'] ) && in_array( $cf_option_value['value'], $field_values ) ) {
243
									$values[] = $cf_option_value['label'];
244
								}
245
							}
246
						}
247
					}
248
					$value = ! empty( $values ) ? implode( ', ', $values ) : '';
249
					break;
250
				case 'time':
251
					$value = $gd_post->{$field_name} != '00:00:00' ? $gd_post->{$field_name} : '';
252
					break;
253
				case 'email':
254
				case 'phone':
255
				case 'text':
256
				case 'url':
257
				case 'html':
258
				case 'textarea':
259
					$value = $gd_post->{$field_name} ? strip_tags( $gd_post->{$field_name} ) : '';
260
					break;
261
				case 'file':
262
					$files = explode( ",", $gd_post->{$field_name} );
263
					if ( ! empty( $files ) ) {
264
						$allowed_file_types = !empty( $extra_fields['gd_file_types'] ) && is_array( $extra_fields['gd_file_types'] ) && !in_array( "*", $extra_fields['gd_file_types'] ) ? $extra_fields['gd_file_types'] : '';
265
266
						$file_urls = array();
267
						foreach ( $files as $file ) {
268
							if ( ! empty( $file ) ) {
269
								$image_name_arr = explode( '/', $file );
270
								$curr_img_dir = $image_name_arr[ count( $image_name_arr ) - 2];
0 ignored issues
show
Unused Code introduced by
$curr_img_dir is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
271
								$filename = end($image_name_arr);
272
								$img_name_arr = explode('.', $filename);
0 ignored issues
show
Unused Code introduced by
$img_name_arr is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
273
274
								$arr_file_type = wp_check_filetype( $filename );
275
								if ( empty( $arr_file_type['ext'] ) || empty( $arr_file_type['type'] ) ) {
276
									continue;
277
								}
278
279
								$uploaded_file_type = $arr_file_type['type'];
280
								$uploaded_file_ext = $arr_file_type['ext'];
281
282
								if ( ! empty( $allowed_file_types ) && !in_array( $uploaded_file_ext, $allowed_file_types ) ) {
283
									continue; // Invalid file type.
284
								}
285
								$image_file_types = array( 'image/jpg', 'image/jpeg', 'image/gif', 'image/png', 'image/bmp', 'image/x-icon' );
286
								$audio_file_types = array( 'audio/mpeg', 'audio/ogg', 'audio/mp4', 'audio/vnd.wav', 'audio/basic', 'audio/mid' );
0 ignored issues
show
Unused Code introduced by
$audio_file_types is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
287
288
								// If the uploaded file is image
289
								if ( in_array( $uploaded_file_type, $image_file_types ) ) {
290
									$file_urls[] = $file;
291
								}
292
							}
293
						}
294
						$value = ! empty( $file_urls ) ? implode( ', ', $file_urls ) : '';
295
					}
296
					break;
297
			}
298
299 View Code Duplication
			if ( ! empty( $name ) && $value !== '' ) {
300
				$personal_data[] = array(
301
					'name'  => __( $name, 'geodirectory' ),
302
					'value' => $value,
303
				);
304
			}
305
		}
306
307
		/**
308
		 * Allow extensions to register their own personal data for this post for the export.
309
		 *
310
		 * @since 1.6.26
311
		 * @param array    $personal_data Array of name value pairs to expose in the export.
312
		 * @param WP_Post $gd_post The post object.
313
		 */
314
		$personal_data = apply_filters( 'geodir_privacy_export_post_personal_data', $personal_data, $gd_post );
315
316
		return $personal_data;
317
	}
318
319
	public static function posts_by_author( $email_address, $post_type, $page ) {
320
		if ( empty( $email_address ) || empty( $post_type ) || empty( $page ) ) {
321
			return array();
322
		}
323
324
		$user = get_user_by( 'email', $email_address );
325
		if ( empty( $user ) ) {
326
			return array();
327
		}
328
329
		$statuses = array_keys( get_post_statuses() );
330
		$skip_statuses = geodir_imex_export_skip_statuses();
331
		if ( ! empty( $skip_statuses ) ) {
332
			$statuses = array_diff( $statuses, $skip_statuses );
333
		}
334
335
		$query_args    = array(
336
			'post_type'			=> $post_type,
337
			'post_status'		=> $statuses,
338
			'fields'			=> 'ids',
339
			'author'   			=> $user->ID,
340
			'posts_per_page'	=> 10,
341
			'paged'     		=> $page,
342
			'orderby'  			=> 'ID',
343
			'order'	   			=> 'ASC'
344
		);
345
346
		$query_args = apply_filters( 'geodir_privacy_post_data_exporter_post_query', $query_args, $post_type, $email_address, $page );
347
348
		$posts = get_posts( $query_args );
349
350
		return apply_filters( 'geodir_privacy_post_data_exporter_posts', $posts, $query_args, $post_type, $email_address, $page );
351
	}
352
353
	public static function review_data_exporter( $response, $exporter_index, $email_address, $page, $request_id, $send_as_email, $exporter_key ) {
0 ignored issues
show
Unused Code introduced by
The parameter $exporter_index is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $email_address is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $page is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $request_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $send_as_email is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $exporter_key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
354
		$exporter_key = GeoDir_Privacy::personal_data_exporter_key();
355
356
		if ( $exporter_key == 'wordpress-comments' && ! empty( $response['data'] ) ) {
357
			foreach ( $response['data'] as $key => $data ) {
358
				$comment_id = str_replace( 'comment-', '', $data['item_id'] );
359
360
				$review = geodir_get_review( $comment_id );
361
				if ( ! empty( $review ) ) {
362 View Code Duplication
					if ( ! empty( $review->overall_rating ) ) {
363
						$response['data'][ $key ]['data'][] = array(
364
							'name'  => __( 'Review Rating', 'geodirectory' ),
365
							'value' => (float)$review->overall_rating,
366
						);
367
					}
368 View Code Duplication
					if ( ! empty( $review->post_city ) ) {
369
						$response['data'][ $key ]['data'][] = array(
370
							'name'  => __( 'Review City', 'geodirectory' ),
371
							'value' => $review->post_city,
372
						);
373
					}
374 View Code Duplication
					if ( ! empty( $review->post_region ) ) {
375
						$response['data'][ $key ]['data'][] = array(
376
							'name'  => __( 'Review Region', 'geodirectory' ),
377
							'value' => $review->post_region,
378
						);
379
					}
380 View Code Duplication
					if ( ! empty( $review->post_country ) ) {
381
						$response['data'][ $key ]['data'][] = array(
382
							'name'  => __( 'Review Country', 'geodirectory' ),
383
							'value' => $review->post_country,
384
						);
385
					}
386 View Code Duplication
					if ( ! empty( $review->post_latitude ) ) {
387
						$response['data'][ $key ]['data'][] = array(
388
							'name'  => __( 'Review Latitude', 'geodirectory' ),
389
							'value' => $review->post_latitude,
390
						);
391
					}
392 View Code Duplication
					if ( ! empty( $review->post_longitude ) ) {
393
						$response['data'][ $key ]['data'][] = array(
394
							'name'  => __( 'Review Longitude', 'geodirectory' ),
395
							'value' => $review->post_longitude,
396
						);
397
					}
398
				}
399
			}
400
		}
401
		return $response;
402
	}
403
}
404