Completed
Push — 2.x ( 55c530...efb054 )
by Scott Kingsley
25:44 queued 18:53
created

Pods_Templates_Auto_Template_Front_End   C

Complexity

Total Complexity 61

Size/Duplication

Total Lines 428
Duplicated Lines 4.21 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 18
loc 428
rs 6.018
wmc 61
lcom 1
cbo 2

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 2
C hook_content() 0 46 9
D auto_pods() 0 101 10
C front() 18 52 11
B the_pods() 0 25 2
B current_post_type() 0 25 5
B load_template() 0 39 6
C set_frontier_style_script() 0 66 16

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

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 11 and the first side effect is on line 3.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
if ( class_exists( 'Pods_PFAT_Frontend' ) ) {
3
	return;
4
}
5
6
/**
7
 * Class Pods_Templates_Auto_Template_Front_End
8
 *
9
 * Replaces Pods_PFAT_Frontend
10
 */
11
class Pods_Templates_Auto_Template_Front_End {
12
	function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
13
14
		if( !is_admin() ){
15
			add_action( 'wp', array( $this, 'set_frontier_style_script' ) );
16
		}
17
18
		add_action( 'template_redirect', array( $this, 'hook_content' ) );
19
20
21
	}
22
23
	/**
24
	 * Add hooks for output
25
	 *
26
	 * @since 2.6.6
27
	 */
28
	public function hook_content(){
29
		$filter = 'the_content';
30
31
		// get the current post type
32
		$current_post_type = $this->current_post_type();
33
34
		//now use other methods in class to build array to search in/ use
35
		$possible_pods = $this->auto_pods();
36
37
38
		//check if $current_post_type is the key of the array of possible pods
39
		if ( isset( $possible_pods[ $current_post_type ] ) ) {
40
41
			$this_pod = $possible_pods[ $current_post_type ];
42
43
			if ( is_singular( $current_post_type ) ) {
44
				$filter =  $this_pod[ 'single_filter' ];
45
			} elseif ( is_post_type_archive( $current_post_type ) ) {
46
				$filter =  $this_pod[ 'archive_filter' ];
47
48
			} elseif ( is_home() && $current_post_type === 'post'  ) {
49
				$filter =  $this_pod[ 'archive_filter' ];
50
			} elseif ( is_tax( $current_post_type )  ) {
51
				$filter =  $this_pod[ 'archive_filter' ];
52
53
			}
54
55
		}
56
		/**
57
		 * Allows plugin to append/replace the_excerpt
58
		 *
59
		 * Default is false, set to true to enable.
60
		 */
61
		if ( !defined( 'PFAT_USE_ON_EXCERPT' ) ) {
62
			define( 'PFAT_USE_ON_EXCERPT', false );
63
		}
64
65
66
		add_filter( $filter, array( $this, 'front' ), 10.5 );
67
68
		if (  PFAT_USE_ON_EXCERPT  ) {
69
			add_filter( 'the_excerpt', array ( $this, 'front' ) );
70
		}
71
72
73
	}
74
75
	/**
76
	 * Get all post type and taxonomy Pods
77
	 *
78
	 * @since 2.4.5
79
	 *
80
	 * @return array Of Pod names.
81
	 */
82
	function the_pods() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
83
84
		//use the cached results
85
		$key = '_pods_pfat_the_pods';
86
		$the_pods = pods_transient_get( $key  );
87
88
		//check if we already have the results cached & use it if we can.
89
		if ( false === $the_pods ) {
90
			//get all post type pods
91
			$the_pods = pods_api()->load_pods( array(
92
					'type' => array(
93
						'taxonomy',
94
						'post_type'
95
					),
96
					'names' => true )
97
			);
98
99
			//cache the results
100
			pods_transient_set( $key, $the_pods );
101
102
		}
103
104
		return $the_pods;
105
106
	}
107
108
	/**
109
	 * Get all Pods with auto template enable and its settings
110
	 *
111
	 * @return array With info about auto template settings per post type
112
	 *
113
	 * @since 2.4.5
114
	 */
115
	function auto_pods() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
116
		/**
117
		 * Filter to override all settings for which templates are used.
118
		 *
119
		 * Note: If this filter does not return null, all back-end settings are ignored. To add to settings with a filter, use 'pods_pfat_auto_pods';
120
		 *
121
		 * @param array $auto_pods Array of parameters to use instead of those from settings.
122
		 *
123
		 * @return array Settings arrays for each post type.
124
		 *
125
		 * @since 2.4.5
126
		 */
127
		$auto_pods = apply_filters( 'pods_pfat_auto_pods_override', null );
128
		if ( !is_null( $auto_pods ) ) {
129
			return $auto_pods;
130
		}
131
132
		//try to get cached results of this method
133
		$key = '_pods_pfat_auto_pods';
134
		$auto_pods = pods_transient_get( $key );
135
	
136
137
		//check if we already have the results cached & use it if we can.
138
		if ( $auto_pods === false  ) {
139
			//get possible pods
140
			$the_pods = $this->the_pods();
141
142
			//start output array empty
143
			$auto_pods = array();
144
145
			//get pods api class
146
			$api = pods_api();
147
148
			//loop through each to see if auto templates is enabled
149
			foreach ( $the_pods as $the_pod => $the_pod_label ) {
150
				//get this Pods' data.
151
				$pod_data = $api->load_pod( array( 'name' => $the_pod ) );
152
153
				//if auto template is enabled add info about Pod to array
154
				if ( 1 == pods_v( 'pfat_enable', $pod_data[ 'options' ] ) ) {
155
					//check if pfat_single and pfat_archive are set
156
					$single = pods_v( 'pfat_single', $pod_data[ 'options' ], false, true );
157
					$archive = pods_v( 'pfat_archive', $pod_data[ 'options' ], false, true );
158
					$single_append = pods_v( 'pfat_append_single', $pod_data[ 'options' ], true, true );
159
					$archive_append = pods_v( 'pfat_append_archive', $pod_data[ 'options' ], true, true );
160
					$single_filter = pods_v( 'pfat_filter_single', $pod_data[ 'options' ], 'the_content', true );
161
					$archive_filter = pods_v( 'pfat_filter_archive', $pod_data[ 'options' ], 'the_content', true );
162
					$type = pods_v( 'type', $pod_data, false, true );
163
					//check if it's a post type that has an arhive
164
					if ( $type === 'post_type' && $the_pod !== 'post' || $the_pod !== 'page' ) {
165
						$has_archive = pods_v( 'has_archive', $pod_data['options'], false, true );
166
					}
167
					else {
168
						$has_archive = true;
169
					}
170
171
					if( empty( $single_filter ) ){
172
						$single_filter = 'the_content';
173
					}
174
175
					if( empty( $archive_filter  ) ){
176
						$archive_filter = 'the_content';
177
					}
178
179
					//build output array
180
					$auto_pods[ $the_pod ] = array(
181
						'name' => $the_pod,
182
						'label'	=> $the_pod_label,
183
						'single' => $single,
184
						'archive' => $archive,
185
						'single_append' => $single_append,
186
						'archive_append' => $archive_append,
187
						'has_archive'	=> $has_archive,
188
						'single_filter' => $single_filter,
189
						'archive_filter' => $archive_filter,
190
						'type' => $type,
191
					);
192
				}
193
194
			} //endforeach
195
196
			//cache the results
197
			pods_transient_set( $key, $auto_pods );
198
		}
199
200
		/**
201
		 * Add to or change settings.
202
		 *
203
		 * Use this filter to change or add to the settings set in the back-end for this plugin. Has no effect if 'pods_pfat_auto_pods_override' filter is being used.
204
		 *
205
		 * @param array $auto_pods Array of parameters to use instead of those from settings.
206
		 *
207
		 * @return array Settings arrays for each post type.
208
		 *
209
		 * @since 2.4.5
210
		 */
211
		$auto_pods = apply_filters( 'pods_pfat_auto_pods', $auto_pods );
212
213
		return $auto_pods;
214
215
	}
216
217
	/**
218
	 * Fetches the current post type.
219
	 *
220
	 * @return string current post type.
221
	 *
222
	 * @since 2.4.5
223
	 */
224
	function current_post_type() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
225
		//start by getting current post or stdClass object
226
		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...
227
		$obj = $wp_query->get_queried_object();
228
229
		//see if we are on a post type and if so, set $current_post_type to post type
230
		if ( isset( $obj->post_type ) ) {
231
			$current_post_type = $obj->post_type;
232
233
		}
234
		elseif ( isset( $obj->taxonomy ) ) {
235
			$current_post_type = $obj->taxonomy;
236
		}
237
		elseif ( isset ( $obj->name ) ) {
238
			$current_post_type = $obj->name;
239
		}
240
		elseif ( is_home() ) {
241
			$current_post_type = 'post';
242
		}
243
		else {
244
			$current_post_type = false;
245
		}
246
247
		return $current_post_type;
248
	}
249
250
	/**
251
	 * Outputs templates after the content as needed.
252
	 *
253
	 * @param string $content Post content
254
	 *
255
	 * @uses 'the_content' filter
256
	 *
257
	 * @return string Post content with the template appended if appropriate.
258
	 *
259
	 * @since 2.4.5
260
	 */
261
	function front( $content ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
262
263
		// get the current post type
264
		$current_post_type = $this->current_post_type();
265
266
		//now use other methods in class to build array to search in/ use
267
		$possible_pods = $this->auto_pods();
268
269
270
		//check if $current_post_type is the key of the array of possible pods
271
		if ( isset( $possible_pods[ $current_post_type ] ) ) {
272
273
			//build Pods object for current item
274
			global $post;
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...
275
			$pods = pods( $current_post_type, $post->ID );
276
277
			//get array for the current post type
278
			$this_pod = $possible_pods[ $current_post_type ];
279
280
281
			if ( $this_pod[ 'single' ] && is_singular( $current_post_type ) ) {
282
				//load the template
283
				$content = $this->load_template( $this_pod[ 'single' ], $content , $pods, $this_pod[ 'single_append' ] );
284
			}
285
			//if pfat_archive was set try to use that template
286
			//check if we are on an archive of the post type
287 View Code Duplication
			elseif ( $this_pod[ 'archive' ] && is_post_type_archive( $current_post_type ) ) {
288
				//load the template
289
				$content = $this->load_template( $this_pod[ 'archive' ], $content , $pods, $this_pod[ 'archive_append' ] );
290
291
			}
292
			//if pfat_archive was set and we're in the blog index, try to append template
293 View Code Duplication
			elseif ( is_home() && $this_pod[ 'archive' ] && $current_post_type === 'post'  ) {
294
				//append the template
295
				$content = $this->load_template( $this_pod[ 'archive' ], $content , $pods, $this_pod[ 'archive_append' ] );
296
297
			}
298
			//if is taxonomy archive of the selected taxonomy
299 View Code Duplication
			elseif ( is_tax( $current_post_type )  ) {
300
				//if pfat_single was set try to use that template
301
				if ( $this_pod[ 'archive' ] ) {
302
					//append the template
303
					$content = $this->load_template( $this_pod[ 'archive' ], $content , $pods, $this_pod[ 'archive_append' ] );
304
				}
305
306
			}
307
308
		}
309
310
		return $content;
311
312
	}
313
314
	/**
315
	 * Attach Pods Template to $content
316
	 *
317
	 * @param string        $template_name  The name of a Pods Template to load.
318
	 * @param string        $content        Post content
319
	 * @param Pods          $pods           Current Pods object.
320
	 * @param bool|string   $append         Optional. Whether to append, prepend or replace content. Defaults to true, which appends, if false, content is replaced, if 'prepend' content is prepended.
321
	 *
322
	 * @return string $content with Pods Template appended if template exists
323
	 *
324
	 * @since 2.4.5
325
	 */
326
	function load_template( $template_name, $content, $pods, $append = true  ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
327
328
		//prevent infinite loops caused by this method acting on post_content
329
		remove_filter( 'the_content', array( $this, 'front' ) );
330
331
		/**
332
		 * Change which template -- by name -- to be used.
333
		 *
334
		 * @since 2.5.6
335
		 *
336
		 * @param string        $template_name  The name of a Pods Template to load.
337
		 * @param Pods          $pods           Current Pods object.
338
		 * @param bool|string   $append         Whether Template will be appended (true), prepended ("prepend") or replaced (false).
339
		 */
340
		$template_name = apply_filters( 'pods_auto_template_template_name', $template_name, $pods, $append );
341
342
		$template = $pods->template( $template_name );
343
		add_filter( 'the_content', array( $this, 'front' ) );
344
345
		//check if we have a valid template
346
		if ( !is_null( $template ) ) {
347
			//if so append it to content or replace content.
348
349
			if ( $append === 'replace' ) {
350
				$content = $template;
351
			}
352
			elseif ( $append === 'prepend' ) {
353
				$content = $template . $content;
354
			}
355
			elseif ( $append || $append === 'append' ) {
356
				$content = $content . $template;
357
			}
358
			else {
359
				$content = $template;
360
			}
361
		}
362
363
		return $content;
364
	}
365
366
367
	/**
368
	 * Sets Styles and Scripts from the Frontier template addons.
369
	 *
370
	 * @since 2.4.5
371
	 */
372
	function set_frontier_style_script(){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
373
374
		if( ! class_exists( 'Pods_Frontier' ) ) {
375
			return;
376
		}
377
378
		// cet the current post type
379
		$current_post_type = $this->current_post_type();
380
381
		//now use other methods in class to build array to search in/ use
382
		$possible_pods = $this->auto_pods();
383
384
		if ( isset( $possible_pods[ $current_post_type ] ) ) {
385
386
			$this_pod = $possible_pods[ $current_post_type ];
387
388
			if ( $this_pod[ 'single' ] && is_singular( $current_post_type ) ) {
389
				//set template
390
				$template = $this_pod[ 'single' ];
391
392
			}
393
			//if pfat_archive was set try to use that template
394
			//check if we are on an archive of the post type
395
			elseif ( $this_pod[ 'archive' ] && is_post_type_archive( $current_post_type ) ) {
396
				//set template
397
				$template = $this_pod[ 'archive' ];
398
399
			}
400
			//if pfat_archive was set and we're in the blog index, try to append template
401
			elseif ( is_home() && $this_pod[ 'archive' ] && $current_post_type === 'post'  ) {
402
				//set template
403
				$template = $this_pod[ 'archive' ];
404
405
			}
406
			//if is taxonomy archive of the selected taxonomy
407
			elseif ( is_tax( $current_post_type )  ) {
408
				//if pfat_single was set try to use that template
409
				if ( $this_pod[ 'archive' ] ) {
410
					//set template
411
					$template = $this_pod[ 'archive' ];
412
				}
413
414
			}
415
416
			if( isset( $template ) ){
417
				global $frontier_styles, $frontier_scripts;
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...
418
419
				$template_post = pods()->api->load_template( array('name' => $template ) );
420
421
				if( !empty( $template_post['id'] ) ){
422
					// got a template - check for styles & scripts
423
					$meta = get_post_meta($template_post['id'], 'view_template', true);
424
425
					$frontier = new Pods_Frontier;
426
					if(!empty($meta['css'])){
427
						$frontier_styles .= $meta['css'];
428
					}
429
430
					if(!empty($meta['js'])){
431
						$frontier_scripts .= $meta['js'];
432
					}
433
				}
434
			}
435
436
		}
437
	}
438
}
439