Classy   B
last analyzed

Complexity

Total Complexity 41

Size/Duplication

Total Lines 376
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 7

Importance

Changes 6
Bugs 0 Features 3
Metric Value
c 6
b 0
f 3
dl 0
loc 376
rs 8.2769
wmc 41
lcom 2
cbo 7

17 Methods

Rating   Name   Duplication   Size   Complexity  
A get_instance() 0 11 2
A __construct() 0 13 1
A init_appearance() 0 3 1
A load_template_function() 0 3 1
A define_constants() 0 13 1
A init_config() 0 3 1
A filter_templates() 0 7 1
A get_config_var() 0 7 2
A textdomain() 0 7 2
B render() 0 32 5
A maybe_minify() 0 13 2
A minify_html() 0 21 1
A archives_title() 0 5 1
B get_posts() 0 28 6
A get_post() 0 9 2
B get_pagination() 0 58 7
B load_custom_includes() 0 14 5

How to fix   Complexity   

Complex Class

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

1
<?php
2
/**
3
 * The core theme class.
4
 *
5
 * @since 	1.0.0
6
 * @package Classy
7
 * @author 	Andrew Tolochka <[email protected]>
8
 */
9
10
namespace Classy;
11
12
use Windwalker\Renderer\BladeRenderer;
13
14
/**
15
 * Class Classy.
16
 */
17
class Classy {
18
19
	/**
20
	 * Singleton instance of plugin
21
	 *
22
	 * @var Classy
23
	 * @since  0.1.0
24
	 */
25
	protected static $single_instance = null;
26
27
	/**
28
	 * Creates or returns an instance of this class.
29
	 *
30
	 * @since  0.1.0
31
	 * @return Classy A single instance of this class.
32
	 */
33
	public static function get_instance() {
34
35
		if ( null === self::$single_instance ) {
36
37
			self::$single_instance = new self();
38
39
		}
40
41
		return self::$single_instance;
42
43
	}
44
45
	/**
46
	 * Define the core functionality of the them.
47
	 *
48
	 * Set the theme name and the theme version that can be used throughout the theme.
49
	 *
50
	 * @since    1.0.0
51
	 */
52
	protected function __construct() {
53
		$this->define_constants();
54
55
		$this->init_appearance();
56
57
		$this->load_template_function();
58
59
		$this->init_config();
60
61
		$this->load_custom_includes();
62
63
		add_filter( 'theme_page_templates', array( $this, 'filter_templates' ) );
64
	}
65
66
	/**
67
	 * Init Appearance class.
68
	 */
69
	private function init_appearance() {
70
		new Appearance();
71
	}
72
73
	/**
74
	 * Load template functions.
75
	 */
76
	private function load_template_function() {
77
		require_once( CLASSY_THEME_FRAMEWORK_PATH . 'core/functions/template-functions.php' );
78
	}
79
80
	/**
81
	 * Loads custom files specified in custom/config.php.
82
	 */
83
	private function load_custom_includes() {
84
		$include = self::get_config_var( 'include' );
85
86
		if ( is_array( $include ) ) {
87
			foreach ( $include as $file ) {
88
				$files = (array) glob( CLASSY_THEME_FRAMEWORK_PATH . 'custom/' . $file );
89
				foreach ( $files as $filename ) {
90
					if ( is_readable( $filename ) ) {
91
						require_once $filename;
92
					}
93
				}
94
			}
95
		}
96
	}
97
98
	/**
99
	 * Defines plugin constants
100
	 *
101
	 * @since    1.0.0
102
	 * @access   private
103
	 */
104
	private function define_constants() {
105
106
		$theme = wp_get_theme();
107
108
		define( 'CLASSY_THEME', $theme->template );
109
		define( 'CLASSY_THEME_NAME', $theme->get( 'Name' ) );
110
		define( 'CLASSY_THEME_PATH', get_template_directory() . '/' );
111
		define( 'CLASSY_THEME_DIR', get_template_directory_uri() . '/' );
112
		define( 'CLASSY_THEME_VERSION', $theme->get( 'Version' ) );
113
		define( 'CLASSY_THEME_FRAMEWORK_PATH', CLASSY_THEME_PATH . 'app/' );
114
		define( 'CLASSY_THEME_FRAMEWORK_DIR', CLASSY_THEME_DIR . 'app/' );
115
116
	}
117
118
	/**
119
	 * Init Theme Configuration
120
	 */
121
	private function init_config() {
122
		Config::init();
123
	}
124
125
	/**
126
	 * Filters registered templates and adds custom theme templates.
127
	 *
128
	 * @param array $page_templates Available WordPress templates.
129
	 *
130
	 * @return array
131
	 */
132
	public function filter_templates( $page_templates = array() ) {
133
134
		$custom_templates = View::get_page_templates_list();
135
136
		return array_merge( $page_templates, $custom_templates );
137
138
	}
139
140
	/**
141
	 * Returns theme config variable.
142
	 *
143
	 * @param string $name Variable's name.
144
	 *
145
	 * @return mixed|bool Return false if variable not found.
146
	 */
147
	public static function get_config_var( $name ) {
148
149
		$vars = Config::get_vars();
150
151
		return ( isset( $vars[ $name ] ) ) ? $vars[ $name ] : false;
152
153
	}
154
155
	/**
156
	 * Returns theme textdomain
157
	 *
158
	 * @return string
159
	 */
160
	public static function textdomain() {
161
162
		$textdomain = Classy::get_config_var( 'textdomain' );
163
164
		return $textdomain ? $textdomain : CLASSY_THEME;
165
166
	}
167
168
	/**
169
	 * Performs view render.
170
	 * If there is $view attribute presented, it will render requested view.
171
	 * If it's not it will try to find necessary view based on $wp_query
172
	 *
173
	 * @param  string|null $view View path in blade format, ex: single, layout.default, single.partials.slider and etc.
174
	 * @param  array|null  $data Additional params.
175
	 * @return void
176
	 */
177
	public static function render( $view = null, $data = null ) {
178
179
		$views = CLASSY_THEME_PATH . View::$folder;
180
		$cache = WP_CONTENT_DIR . '/viewcache';
181
		$common_scope = Scope::get_common_scope();
182
183
		if ( null !== $view && is_string( $view ) ) {
184
185
			if ( $data && is_array( $data ) ) {
186
187
				$scope = array_merge( $common_scope, $data );
188
189
			} else {
190
191
				$scope = $common_scope;
192
193
			}
194
		} else {
195
196
			$view = View::get_view();
197
198
			$scope = Scope::get_scope();
199
200
		}
201
202
		$renderer = new BladeRenderer( $views, array( 'cache_path' => $cache ) );
0 ignored issues
show
Documentation introduced by
$views is of type string, but the function expects a object<SplPriorityQueue>|null.

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...
203
204
		$html = $renderer->render( $view, $scope );
205
206
		echo self::maybe_minify( $html );
207
208
	}
209
210
	/**
211
	 * Minifies html in case the minify_html option is set to true.
212
	 *
213
	 * @param  string $html HTML string.
214
	 * @return string
215
	 */
216
	private static function maybe_minify( $html ) {
217
218
		$minify_html = self::get_config_var( 'minify_html' );
219
220
		if ( true === $minify_html ) {
221
222
			$html = self::minify_html( $html );
223
224
		}
225
226
		return $html;
227
228
	}
229
230
	/**
231
	 * Returns minified version of string with removed whitespaces and empty strings.
232
	 *
233
	 * @param  string $html HTML string.
234
	 * @return string
235
	 */
236
	private static function minify_html( $html ) {
237
238
		$search = array(
239
			"/\n/s",
240
			'/\>[^\S ]+/s',  // Strip whitespaces after tags, except space.
241
			'/[^\S ]+\</s',  // Strip whitespaces before tags, except space.
242
			'/(\s)+/s',       // Shorten multiple whitespace sequences.
243
			'/<!--(.|\s)*?-->/',
244
		);
245
246
		$replace = array(
247
			'',
248
			'>',
249
			'<',
250
			'\\1',
251
			'',
252
		);
253
254
		return preg_replace( $search, $replace, $html );
255
256
	}
257
258
	/**
259
	 * Alias for Helper::get_archives_title()
260
	 * Returns page title for archive page.
261
	 * Example: Archives, Author: John Doe, Tag: Lorem Ipsum
262
	 *
263
	 * @return string
264
	 */
265
	public static function archives_title() {
266
267
		return Helper::get_archives_title();
268
269
	}
270
271
	/**
272
	 * Returns posts
273
	 *
274
	 * @param  mixed  $args   Array of query args.
275
	 * @param  string $return object/id/Post.
276
	 *
277
	 * @return array
278
	 */
279
	public static function get_posts( $args = false, $return = '\Classy\Models\Post' ) {
280
281
		$_return = array();
282
283
		$query = Query_Helper::find_query( $args );
284
285
		if ( isset( $query->posts ) ) {
286
287
			foreach ( $query->posts as $post ) {
288
289
				if ( 'id' === $return ) {
290
291
					$_return[] = $post->id;
292
293
				} elseif ( 'object' === $return ) {
294
295
					$_return[] = $post;
296
297
				} elseif ( class_exists( $return ) ) {
298
299
					$_return[] = new $return( $post );
300
301
				}
302
			}
303
		}
304
305
		return $_return;
306
	}
307
308
309
	/**
310
	 * Returns post.
311
	 *
312
	 * @param  mixed  $args 		Array of query args.
313
	 * @param  string $return_type 	Post/object/id.
314
	 *
315
	 * @return mixed
316
	 */
317
	public static function get_post( $args = false, $return_type = '\Classy\Models\Post' ) {
318
319
		$posts = self::get_posts( $args, $return_type );
320
321
		if ( $post = reset( $posts ) ) {
322
			return $post;
323
		}
324
325
	}
326
327
	/**
328
	 * @todo: Write description here.
329
	 *
330
	 * @param array $prefs Args for paginate_links.
331
	 *
332
	 * @return array mixed
333
	 */
334
	public static function get_pagination( $prefs = array() ) {
335
336
		global $wp_query;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
337
		global $paged;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
338
		global $wp_rewrite;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
339
340
		$args = array();
341
		$args['total'] = ceil( $wp_query->found_posts / $wp_query->query_vars['posts_per_page'] );
342
343
		if ( $wp_rewrite->using_permalinks() ) {
344
345
			$url = explode( '?', get_pagenum_link( 0 ) );
346
347
			if ( isset( $url[1] ) ) {
348
				parse_str( $url[1], $query );
349
				$args['add_args'] = $query;
350
			}
351
352
			$args['format'] = 'page/%#%';
353
			$args['base'] = trailingslashit( $url[0] ).'%_%';
354
355
		} else {
356
			$big = 999999999;
357
			$args['base'] = str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) );
358
		}
359
360
		$args['type'] = 'array';
361
		$args['current'] = max( 1, get_query_var( 'paged' ) );
362
		$args['mid_size'] = max( 9 - $args['current'], 3 );
363
		$args['prev_next'] = false;
364
365
		if ( is_int( $prefs ) ) {
366
			$args['mid_size'] = $prefs - 2;
367
		} else {
368
			$args = array_merge( $args, $prefs );
369
		}
370
371
		$data = array();
372
		$data['pages'] = Helper::paginate_links( $args );
373
		$next = get_next_posts_page_link( $args['total'] );
374
375
		if ( $next ) {
376
			$data['next'] = array( 'link' => untrailingslashit( $next ), 'class' => 'page-numbers next' );
377
		}
378
379
		$prev = previous_posts( false );
380
381
		if ( $prev ) {
382
			$data['prev'] = array( 'link' => untrailingslashit( $prev ), 'class' => 'page-numbers prev' );
383
		}
384
385
		if ( $paged < 2 ) {
386
			$data['prev'] = null;
387
		}
388
389
		return Helper::array_to_object( $data );
390
391
	}
392
}
393