Comment   B
last analyzed

Complexity

Total Complexity 40

Size/Duplication

Total Lines 322
Duplicated Lines 4.04 %

Coupling/Cohesion

Components 5
Dependencies 2

Importance

Changes 4
Bugs 1 Features 1
Metric Value
dl 13
loc 322
rs 8.2608
c 4
b 1
f 1
wmc 40
lcom 5
cbo 2

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 2
A author() 0 14 4
A content() 0 3 1
A approved() 0 3 1
A date() 0 6 2
A has_parent() 0 3 1
B avatar() 0 25 5
A get_avatar_email() 0 12 2
C get_default_avatar() 0 29 12
A get_avatar_host() 0 14 3
A get_avatar_url() 0 10 2
A add_child() 0 8 2
A update_child_levels() 12 12 3

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 Comment 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 Comment, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Wrapper and helper for WP_Comment class.
4
 *
5
 * @package Classy
6
 */
7
8
namespace Classy;
9
10
/**
11
 * Class Comment.
12
 */
13
class Comment extends Basis {
14
15
	/**
16
	 * Comment ID.
17
	 *
18
	 * @var int
19
	 */
20
	public $comment_ID;
21
22
	/**
23
	 * Comment post ID.
24
	 *
25
	 * @var int
26
	 */
27
	public $comment_post_ID;
28
29
	/**
30
	 * Comment Author name.
31
	 *
32
	 * @var string
33
	 */
34
	public $comment_author;
35
36
	/**
37
	 * Comment author email.
38
	 *
39
	 * @var string
40
	 */
41
	public $comment_author_email;
42
43
	/**
44
	 * Comment author link.
45
	 *
46
	 * @var string
47
	 */
48
	public $comment_author_url;
49
50
	/**
51
	 * Comment.
52
	 *
53
	 * @var string
54
	 */
55
	public $comment_content;
56
57
	/**
58
	 * Comment approved.
59
	 *
60
	 * @var boolean
61
	 */
62
	public $comment_approved;
63
64
	/**
65
	 * Comment date.
66
	 *
67
	 * @var string
68
	 */
69
	public $comment_date;
70
71
	/**
72
	 * User ID.
73
	 *
74
	 * @var int
75
	 */
76
	public $user_id;
77
78
	/**
79
	 * Comment nested level.
80
	 *
81
	 * @var int
82
	 */
83
	public $level;
84
85
	/**
86
	 * Comment Parent ID.
87
	 *
88
	 * @var int
89
	 */
90
	public $comment_parent;
91
92
	/**
93
	 * Child comments.
94
	 *
95
	 * @var array
96
	 */
97
	protected $children = array();
98
99
	/**
100
	 * Checks if provided arg is instance of WP_Comment and init it.
101
	 *
102
	 * @param \WP_Comment $item WP_Comment object.
103
	 */
104
	public function __construct( $item ) {
105
		if ( is_a( $item, '\WP_Comment' ) ) {
106
			$this->import( $item );
107
		}
108
	}
109
110
	/**
111
	 * Returns User object of comment author.
112
	 *
113
	 * @return \Classy\Models\User
114
	 */
115
	public function author() {
116
		if ( ! $this->user_id ) {
117
118
			$author = new Models\User( 0 );
119
120
			if ( isset( $this->comment_author ) && $this->comment_author ) {
121
				$author->name = $this->comment_author;
122
			}
123
124
			return $author;
125
		}
126
127
		return new Models\User( $this->user_id );
128
	}
129
130
	/**
131
	 * Returns comment content.
132
	 *
133
	 * @return string
134
	 */
135
	public function content() {
136
		return apply_filters( 'get_comment_text ', $this->comment_content );
137
	}
138
139
	/**
140
	 * Return true if comment is approved.
141
	 *
142
	 * @return boolean
143
	 */
144
	public function approved() {
145
		return $this->comment_approved;
146
	}
147
148
	/**
149
	 * Returns comment date.
150
	 *
151
	 * @param string $date_format Optional. PHP date format defaults to the date_format option if not specified.
152
	 *
153
	 * @return string
154
	 */
155
	public function date( $date_format = '' ) {
156
		$df = $date_format ? $date_format : get_option( 'date_format' );
157
		$the_date = (string) mysql2date( $df, $this->comment_date );
158
159
		return apply_filters( 'get_comment_date ', $the_date, $df );
160
	}
161
162
	/**
163
	 * Returns true if comment has parent.
164
	 *
165
	 * @return boolean
166
	 */
167
	public function has_parent() {
168
		return $this->comment_parent > 0;
169
	}
170
171
	/**
172
	 * Shows gravatar.
173
	 *
174
	 * @param integer $size    avatar image size
175
	 * @param string  $default
176
	 *
177
	 * @return string
178
	 */
179
	public function avatar( $size = 92, $default = '' ) {
180
		if ( ! get_option( 'show_avatars' ) ) {
181
			return false;
182
		}
183
184
		if ( ! is_numeric( $size ) ) { $size = '92'; }
185
186
		$email = $this->get_avatar_email();
187
		$email_hash = '';
188
189
		if ( ! empty( $email ) ) {
190
			$email_hash = md5( strtolower( trim( $email ) ) );
191
		}
192
193
		$host = $this->get_avatar_host( $email_hash );
194
		$default = $this->get_default_avatar( $default, $email, $size, $host );
195
196
		if ( ! empty( $email ) ) {
197
			$avatar = $this->get_avatar_url( $default, $host, $email_hash, $size );
198
		} else {
199
			$avatar = $default;
200
		}
201
202
		return $avatar;
203
	}
204
205
	/**
206
	 * Returns email address that will be used for generating avatar.
207
	 *
208
	 * @return string
209
	 */
210
	protected function get_avatar_email() {
211
		$id = (int) $this->user_id;
212
		$user = get_userdata( $id );
213
214
		if ( $user ) {
215
			$email = $user->user_email;
216
		} else {
217
			$email = $this->comment_author_email;
218
		}
219
220
		return $email;
221
	}
222
223
	/**
224
	 * Returns default avatar url.
225
	 *
226
	 * @param  string $default
227
	 * @param  string $email
228
	 * @param  int $size
229
	 * @param  string $host
230
	 * @return string
231
	 */
232
	protected function get_default_avatar( $default, $email, $size, $host ) {
233
		if ( '/' === substr( $default, 0, 1 ) ) {
234
			$default = home_url() . $default;
235
		}
236
237
		if ( empty( $default ) ) {
238
			$avatar_default = get_option( 'avatar_default' );
239
			if ( empty( $avatar_default ) ) {
240
				$default = 'mystery';
241
			} else {
242
				$default = $avatar_default;
243
			}
244
		}
245
246
		if ( 'mystery' === $default ) {
247
			$default = $host . '/avatar/ad516503a11cd5ca435acc9bb6523536?s=' . $size;
248
			// ad516503a11cd5ca435acc9bb6523536 == md5('[email protected]')
249
		} else if ( 'blank' === $default ) {
250
			$default = $email ? 'blank' : includes_url( 'images/blank.gif' );
251
		} else if ( ! empty( $email ) && 'gravatar_default' === $default ) {
252
			$default = '';
253
		} else if ( 'gravatar_default' === $default ) {
254
			$default = $host . '/avatar/?s=' . $size;
255
		} else if ( empty( $email ) && ! strstr( $default, 'http://' ) ) {
256
			$default = $host . '/avatar/?d=' . $default . '&amp;s=' . $size;
257
		}
258
259
		return $default;
260
	}
261
262
	/**
263
	 * Returns gravatar host.
264
	 *
265
	 * @param  string $email_hash
266
	 * @return string
267
	 */
268
	protected function get_avatar_host( $email_hash ) {
269
270
		if ( is_ssl() ) {
271
			$host = 'https://secure.gravatar.com';
272
		} else {
273
			if ( ! empty( $email_hash ) ) {
274
				$host = sprintf( 'http://%d.gravatar.com', (hexdec( $email_hash[0] ) % 2) );
275
			} else {
276
				$host = 'http://0.gravatar.com';
277
			}
278
		}
279
280
		return $host;
281
	}
282
283
	/**
284
	 * Returns avatar url
285
	 *
286
	 * @param  string $default
287
	 * @param  string $host
288
	 * @param  string $email_hash
289
	 * @param  int $size
290
	 * @return string
291
	 */
292
	protected function get_avatar_url( $default, $host, $email_hash, $size ) {
293
		$_return = $host . '/avatar/' . $email_hash . '?s=' . $size . '&amp;d=' . urlencode( $default );
294
		$rating = get_option( 'avatar_rating' );
295
296
		if ( ! empty( $rating ) ) {
297
			$_return .= '&amp;r=' . $rating;
298
		}
299
300
		return str_replace( '&#038;', '&amp;', esc_url( $_return ) );
301
	}
302
303
	/**
304
	 * Adds child to current Comment
305
	 *
306
	 * @param Comment $comment
307
	 */
308
	public function add_child( $comment ) {
309
		$this->children[] = $comment;
310
		$item->level = $this->level + 1;
0 ignored issues
show
Bug introduced by
The variable $item does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
311
312
		if ( $item->children ) {
313
			$this->update_child_levels();
314
		}
315
	}
316
317
	/**
318
	 * Updates children nesting level param
319
	 *
320
	 * @return boolean
321
	 */
322 View Code Duplication
	protected function update_child_levels() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
323
		if ( is_array( $this->children ) ) {
324
			foreach ( $this->children as $child ) {
325
				$child->level = $this->level + 1;
326
				$child->update_child_levels();
327
			}
328
329
			return true;
330
		}
331
332
		return false;
333
	}
334
}
335