Completed
Push — master ( bc6754...ed64c2 )
by
unknown
07:19
created

Hierarchy   C

Complexity

Total Complexity 56

Size/Duplication

Total Lines 386
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 386
rs 6.5957
wmc 56
lcom 1
cbo 2

8 Methods

Rating   Name   Duplication   Size   Complexity  
D check_request() 0 43 18
A get_current_request() 0 11 2
A get_file_path() 0 19 3
A file_exists() 0 9 1
A get_available_file() 0 17 3
D get_request_hierarchy_list() 0 202 24
A is_classy_template() 0 4 2
A get_classy_template() 0 11 3

How to fix   Complexity   

Complex Class

Complex classes like Hierarchy 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 Hierarchy, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace Classy;
3
4
/**
5
 * Implements WordPress Hierarchy
6
 */
7
8
class Hierarchy {
9
10
	/**
11
	 * Stores current request for multiple use
12
	 *
13
	 * @var string/null
14
	 */
15
	protected static $current_request = null;
16
17
	/**
18
	 * Protected function to get current request type
19
	 *
20
	 * @return string
21
	 */
22
	protected static function check_request() {
23
24
		if ( is_404() ) : return '404';
25
26
		elseif ( is_search() ) : return 'search';
27
28
		elseif ( is_front_page() ) : return 'front-page';
29
30
		elseif ( is_home() ) : return 'home';
31
32
		elseif ( is_post_type_archive() ) : return 'post_type_archive';
33
34
		elseif ( is_tax() ) : return 'taxonomy';
35
36
		elseif ( is_attachment() ) : return 'attachment';
37
38
		elseif ( is_single() ) : return 'single';
39
40
		elseif ( self::is_classy_template() ) : return 'classy-template';
41
42
		elseif ( is_page() ) : return 'page';
43
44
		elseif ( is_singular() ) : return 'singular';
45
46
		elseif ( is_category() ) : return 'category';
47
48
		elseif ( is_tag() ) : return 'tag';
49
50
		elseif ( is_author() ) : return 'author';
51
52
		elseif ( is_date() ) : return 'date';
53
54
		elseif ( is_archive() ) : return 'archive';
55
56
		elseif ( is_paged() ) : return 'paged';
57
58
		else :
59
60
			return 'index';
61
62
		endif;
63
64
	}
65
66
	/**
67
	 * Returns current request type
68
	 *
69
	 * @return string
70
	 */
71
	public static function get_current_request() {
72
73
		if ( null === self::$current_request ) {
74
75
			self::$current_request = self::check_request();
76
77
		}
78
79
		return self::$current_request;
80
81
	}
82
83
84
	/**
85
	 * Returns file's absolute path
86
	 *
87
	 * @param  string $type     view/scope
88
	 * @param  string $view path to view ex: "post/archive"
89
	 * @return string           full fule path
90
	 */
91
	public static function get_file_path( $type = 'view', $view ) {
92
93
		$view = str_replace( '.', '/', $view );
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $view. This often makes code more readable.
Loading history...
94
95
		if ( 'view' === $type ) {
96
97
			$folder = View::$folder;
98
99
			return CLASSY_THEME_PATH . $folder . '/' . $view . '.blade.php';
100
101
		} elseif ( 'scope' === $type ) {
102
103
			$folder = Scope::$folder;
104
105
			return CLASSY_THEME_PATH . $folder . '/' . $view . '.php';
106
107
		}
108
109
	}
110
111
112
	/**
113
	 * Checks if view exists
114
	 *
115
	 * @param  string $type view|scope
116
	 * @param  string $file in blade path format, ex: layout|header
117
	 * @return boolean true|false
118
	 */
119
	public static function file_exists( $type = 'view', $file ) {
120
121
		$file = str_replace( '.', '/', $file );
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $file. This often makes code more readable.
Loading history...
122
123
		$file_path = self::get_file_path( $type, $file );
124
125
		return file_exists( $file_path );
126
127
	}
128
129
130
	/**
131
	 * Returns view name for render, based on type of request
132
	 *
133
	 * @param  string $type view|scope
134
	 * @param  string $type
135
	 * @return array
136
	 */
137
	public static function get_available_file( $type = 'view', $page ) {
138
139
		$views = self::get_request_hierarchy_list( $page );
140
141
		foreach ( $views as $view ) {
142
143
			if ( self::file_exists( $type, $view ) ) :
0 ignored issues
show
Security Bug introduced by
It seems like $view defined by $view on line 141 can also be of type false; however, Classy\Hierarchy::file_exists() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
144
145
				return $view;
146
147
			endif;
148
149
		}
150
151
		return false;
152
153
	}
154
155
156
	/**
157
	 * Returns list of filenames to check, based on type of request
158
	 *
159
	 * @param  string $type
160
	 * @return array
161
	 */
162
	private static function get_request_hierarchy_list( $type ) {
163
164
		$views = array();
165
166
		// Home
167
168
		if ( 'home' === $type ) :
169
170
			$views[] = 'home';
171
172
			// Single
173
174
		elseif ( 'single' === $type ) :
175
176
			$post_type = get_post_type();
177
178
			$views[] = $post_type . '.single';
179
180
			$views[] = 'single';
181
182
			// Post type
183
184
		elseif ( 'post_type_archive' === $type ) :
185
186
			$post_type = get_post_type();
187
188
			$views[] = $post_type . '.archive';
189
190
			$views[] = 'archive';
191
192
			// Taxonomy
193
194
		elseif ( 'taxonomy' === $type ) :
195
196
			$term = get_queried_object();
197
198
			if ( ! empty( $term->slug ) ) {
199
200
				$taxonomy = $term->taxonomy;
201
202
				$views[] = "taxonomy.$taxonomy-{$term->slug}";
203
				$views[] = "taxonomy.$taxonomy";
204
205
			}
206
207
			$views[] = 'taxonomy.taxonomy';
208
209
			$views[] = 'taxonomy';
210
211
			// Category
212
213
		elseif ( 'category' === $type ) :
214
215
			$category = get_queried_object();
216
217
			if ( ! empty( $category->slug ) ) {
218
				$views[] = "category.{$category->slug}";
219
				$views[] = "category.{$category->term_id}";
220
			}
221
222
			$views[] = 'category.category';
223
224
			$views[] = 'category';
225
226
			// Attachment
227
228
		elseif ( 'attachment' === $type ) :
229
230
			$attachment = get_queried_object();
231
232
			if ( $attachment ) {
233
234
				if ( false !== strpos( $attachment->post_mime_type, '/' ) ) {
235
236
					list( $type, $subtype ) = explode( '/', $attachment->post_mime_type );
237
238
				} else {
239
240
					list( $type, $subtype ) = array( $attachment->post_mime_type, '' );
241
242
				}
243
244
				if ( ! empty( $subtype ) ) {
245
					$views[] = "attachment.{$type}.{$subtype}";
246
					$views[] = "attachment.{$subtype}";
247
248
					$views[] = "{$type}.{$subtype}";
249
					$views[] = "{$subtype}";
250
				}
251
252
				$views[] = "attachment.{$type}";
253
				$views[] = "{$type}";
254
255
			}
256
257
			$views[] = 'attachment.attachment';
258
259
			$views[] = 'attachment';
260
261
			// Tag
262
263
		elseif ( 'tag' === $type ) :
264
265
			$tag = get_queried_object();
266
267
			if ( ! empty( $tag->slug ) ) {
268
				$views[] = "post.tag.{$tag->slug}";
269
				$views[] = "post.tag.{$tag->term_id}";
270
271
				$views[] = "tag.{$tag->slug}";
272
				$views[] = "tag.{$tag->term_id}";
273
			}
274
			$views[] = 'post.tag';
275
276
			$views[] = 'tag';
277
278
			// Author
279
280
		elseif ( 'author' === $type ) :
281
282
			$author = get_queried_object();
283
284
			if ( $author instanceof WP_User ) {
0 ignored issues
show
Bug introduced by
The class Classy\WP_User does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
285
				$views[] = "post.author.{$author->user_nicename}";
286
				$views[] = "post.author.{$author->ID}";
287
288
				$views[] = "author.{$author->user_nicename}";
289
				$views[] = "author.{$author->ID}";
290
			}
291
292
			$views[] = 'post.author';
293
294
			$views[] = 'author';
295
296
			// Front Page
297
298
		elseif ( 'front-page' === $type ) :
299
300
			$views[] = 'front-page.front-page';
301
			$views[] = 'front-page';
302
303
			$views[] = 'home.home';
304
			$views[] = 'home';
305
306
			$views = array_merge( $views, self::get_request_hierarchy_list( 'post_type_archive' ) );
307
308
			// Page
309
310
		elseif ( 'classy-template' === $type ) :
311
312
			$template = self::get_classy_template();
313
314
			$views[] = $template;
315
316
			$views[] = 'page.' . $template;
317
318
			$views[] = 'template.' . $template;
319
320
			$views[] = 'page.page';
321
322
			$views[] = 'page';
323
324
		elseif ( 'page' === $type ) :
325
326
			$id = get_queried_object_id();
327
328
			$pagename = get_query_var( 'pagename' );
329
330
			if ( ! $pagename && $id ) {
331
				// If a static page is set as the front page, $pagename will not be set. Retrieve it from the queried object
332
				$post = get_queried_object();
333
334
				if ( $post ) {
335
					$pagename = $post->post_name;
336
				}
337
			}
338
339
			if ( $pagename ) {
340
				$views[] = 'page.' . $pagename;
341
			}
342
343
			if ( $id ) {
344
				$views[] = 'page.' . $id;
345
			}
346
347
			$views[] = 'page.page';
348
349
			$views[] = 'page';
350
351
			// Default
352
353
		else :
354
355
			$views[] = $type;
356
357
		endif;
358
359
		$views[] = 'index';
360
361
		return $views;
362
363
	}
364
365
366
	/**
367
	 * Checks if this is classy custom template
368
	 *
369
	 * @return boolean
370
	 */
371
	public static function is_classy_template() {
372
373
		return self::get_classy_template() ? true : false;
374
	}
375
376
377
	/**
378
	 * Returns classy template name or boolean if this is not classy template
379
	 *
380
	 * @return mixed
381
	 */
382
	public static function get_classy_template() {
383
384
		$template_slug = get_page_template_slug();
385
386
		preg_match( '/classy\-(.*)/', $template_slug, $matches );
387
388
		if ( ! empty( $matches ) && isset( $matches[1] ) ) { return $matches[1]; }
389
390
		return false;
391
392
	}
393
}
394