Completed
Pull Request — master (#891)
by
unknown
03:05
created

TimberPostGetter   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 36
c 4
b 0
f 0
lcom 1
cbo 2
dl 0
loc 122
rs 8.8

9 Methods

Rating   Name   Duplication   Size   Complexity  
A get_posts() 0 4 1
A get_post() 0 6 2
A query_post() 0 6 3
C query_posts() 0 22 9
A get_pids() 0 10 3
A loop_to_id() 0 13 4
A wp_query_has_posts() 0 4 3
A is_post_class_or_class_map() 0 10 4
B get_class_for_use_as_timber_post() 0 15 7
1
<?php
2
3
class TimberPostGetter {
4
5
	/**
6
	 * @param mixed $query
7
	 * @param string $PostClass
8
	 * @return array|bool|null
9
	 */
10
	static function get_post($query = false, $PostClass = 'TimberPost') {
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...
11
		$posts = self::get_posts( $query, $PostClass );
12
		if ( $post = reset($posts ) ) {
13
			return $post;
14
		}
15
	}
16
17
	static function get_posts( $query = false, $PostClass = 'TimberPost', $return_collection = false ) {
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...
18
		$posts = self::query_posts( $query, $PostClass );
19
		return apply_filters('timber_post_getter_get_posts', $posts->get_posts( $return_collection ));
0 ignored issues
show
Unused Code introduced by
The call to TimberPostsCollection::get_posts() has too many arguments starting with $return_collection.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
20
	}
21
22
	static function query_post( $query = false, $PostClass = 'TimberPost' ) {
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...
23
		$posts = self::query_posts( $query, $PostClass );
24
		if ( method_exists($posts, 'current') && $post = $posts->current() ) {
0 ignored issues
show
Bug introduced by
The method current does only exist in TimberQueryIterator, but not in TimberPostsCollection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
25
			return $post;
26
		}
27
	}
28
29
	/**
30
	 * @param mixed $query
31
	 * @param string $PostClass
32
	 * @return array|bool|null
0 ignored issues
show
Documentation introduced by
Should the return type not be TimberPostsCollection|TimberQueryIterator?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
33
	 */
34
	static function query_posts($query = false, $PostClass = 'TimberPost' ) {
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...
35
		if ( $type = self::get_class_for_use_as_timber_post($query) ) {
36
			$PostClass = $type;
37
			if ( self::is_post_class_or_class_map($query) ) {
38
				$query = false;
39
			}
40
		}
41
42
		if (is_object($query) && !is_a($query, 'WP_Query') ){
43
			// The only object other than a query is a type of post object
44
			$query = array( $query );
45
		}
46
47
		if ( is_array( $query ) && count( $query ) && isset( $query[0] ) && is_object( $query[0] ) ) {
48
			// We have an array of post objects that already have data
49
			return new TimberPostsCollection( $query, $PostClass );
0 ignored issues
show
Bug introduced by
It seems like $PostClass defined by $type on line 36 can also be of type boolean; however, TimberPostsCollection::__construct() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
50
		} else {
51
			// We have a query (of sorts) to work with
52
			$tqi = new TimberQueryIterator( $query, $PostClass );
0 ignored issues
show
Bug introduced by
It seems like $PostClass defined by $type on line 36 can also be of type boolean; however, TimberQueryIterator::__construct() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
53
			return $tqi;
54
		}
55
	}
56
57
	static function get_pids($query){
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...
58
		$posts = self::get_posts($query);
59
		$pids = array();
60
		foreach($posts as $post){
61
			if (isset($post->ID)){
62
				$pids[] = $post->ID;
63
			}
64
		}
65
		return $pids;
66
	}
67
68
	static function loop_to_id() {
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...
69
		if (!self::wp_query_has_posts()) { return false; }
70
71
		global $wp_query;
72
		$post_num = property_exists($wp_query, 'current_post')
73
				  ? $wp_query->current_post + 1
74
				  : 0
75
				  ;
76
77
		if (!isset($wp_query->posts[$post_num])) { return false; }
78
79
		return $wp_query->posts[$post_num]->ID;
80
	}
81
82
	/**
83
	 * @return bool
84
	 */
85
	static function wp_query_has_posts() {
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...
86
		global $wp_query;
87
		return ($wp_query && property_exists($wp_query, 'posts') && $wp_query->posts);
88
	}
89
90
	/**
91
	 * @param string|array $arg
92
	 * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
93
	 */
94
	static function is_post_class_or_class_map($arg){
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...
95
		$maybe_type = self::get_class_for_use_as_timber_post( $arg );
96
		if ( is_array($arg) && isset($arg['post_type'])) {
97
			//the user has passed a true WP_Query-style query array that needs to be used later, so the $arg is not a class map or post class
98
			return false;
99
		}
100
		if ( $maybe_type ) {
101
			return true;
102
		}
103
	}
104
105
	/**
106
	 * @param string|array $arg
107
	 * @return string|bool if a $type is found; false if not
108
	 */
109
	static function get_class_for_use_as_timber_post($arg) {
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...
110
		$type = false;
111
112
		if ( is_string($arg) ) {
113
			$type = $arg;
114
		} else if ( is_array($arg) && isset($arg['post_type']) ) {
115
			$type = $arg['post_type'];
116
		}
117
118
		if(!$type) return false;
119
120
		if (class_exists($type) && is_subclass_of($type, 'TimberPost')) {
121
			return $type;
122
		}
123
	}
124
}
125