Completed
Pull Request — master (#19)
by Sergey
03:17
created

Response::getData()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 19
rs 8.8571
cc 5
eloc 9
nc 5
nop 2
1
<?php
2
3
namespace seregazhuk\PinterestBot\Api;
4
5
use seregazhuk\PinterestBot\Interfaces\ResponseInterface;
6
7
class Response implements ResponseInterface
8
{
9
    /**
10
     * @var array
11
     */
12
    protected $response;
13
14
    /**
15
     * @var array
16
     */
17
    protected $lastError;
18
19
    /**
20
     * Check if specified data exists in response
21
     * @param      $response
22
     * @param null $key
23
     * @return array|bool
24
     */
25
    public function getData($response, $key = null)
26
    {
27
28
        if ( ! $this->checkErrorInResponse($response)) {
29
            return false;
30
        }
31
32
        if (isset($response['resource_response']['data'])) {
33
            $data = $response['resource_response']['data'];
34
35
            if ($key) {
36
                return array_key_exists($key, $data) ? $data[$key] : false;
37
            }
38
39
            return $data;
40
        }
41
42
        return false;
43
    }
44
45
    /**
46
     * Checks if response is not empty
47
     *
48
     * @param array $response
49
     * @return bool
50
     */
51
    public function notEmpty($response)
52
    {
53
        return ! empty($this->getData($response));
54
    }
55
56
    public function checkResponse($response)
57
    {
58
        return ($this->notEmpty($response) && $this->checkErrorInResponse($response));
59
    }
60
61
    /**
62
     * Check for error info in api response and save
63
     * it.
64
     *
65
     * @param array $response
66
     * @return bool
67
     */
68
    public function checkErrorInResponse($response)
69
    {
70
        $this->lastError = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $lastError.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
71
72
        if (isset($response['resource_response']['error']) && ! empty($response['resource_response']['error'])) {
73
            $this->lastError = $response['resource_response']['error'];
74
            return false;
75
        }
76
77
        return true;
78
    }
79
80
    /**
81
     * Parse bookmarks from response
82
     * @param array $response
83
     * @return string|null
84
     */
85
    public function getBookmarksFromResponse($response)
86
    {
87
        if ( ! $this->checkErrorInResponse($response)) {
88
            return null;
89
        }
90
        if (isset($response['resource']['options']['bookmarks'][0])) {
91
            return [$response['resource']['options']['bookmarks'][0]];
0 ignored issues
show
Bug Best Practice introduced by
The return type of return array($response['...ons']['bookmarks'][0]); (array) is incompatible with the return type declared by the interface seregazhuk\PinterestBot\...etBookmarksFromResponse of type string|null.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
92
        }
93
94
        return null;
95
    }
96
97
    /**
98
     * Checks Pinterest API paginated response, and parses data
99
     * with bookmarks info from it.
100
     *
101
     * @param array $response
102
     * @return array
103
     */
104
    public function getPaginationData($response)
105
    {
106
        if ( ! $this->checkResponse($response)) {
107
            return [];
108
        }
109
110
        $bookmarks = $this->getBookmarksFromResponse($response);
111
        if ($data = self::getData($response)) {
112
            return ['data' => $data, 'bookmarks' => $bookmarks];
113
        }
114
115
        return [];
116
    }
117
118
    /**
119
     * Parses Pinterest search API response for data and bookmarks
120
     * for next pagination page
121
     *
122
     * @param array $response
123
     * @param bool  $bookmarksUsed
124
     * @return array|null
125
     */
126
    public function parseSearchResponse($response, $bookmarksUsed = true)
127
    {
128
        if ($response === null || ! $bookmarksUsed) {
129
            return self::parseSimpledSearchResponse($response);
130
        }
131
132
        return $this->getPaginationData($response);
133
    }
134
135
    /**
136
     * Parses simple Pinterest search API response
137
     * on request with bookmarks
138
     *
139
     * @param $response
140
     * @return array
141
     */
142
    public function parseSimpledSearchResponse($response)
143
    {
144
        $bookmarks = [];
145
        if (isset($response['module']['tree']['resource']['options']['bookmarks'][0])) {
146
            $bookmarks = $response['module']['tree']['resource']['options']['bookmarks'][0];
147
        }
148
149
        if ( ! empty($response['module']['tree']['data']['results'])) {
150
            return ['data' => $response['module']['tree']['data']['results'], 'bookmarks' => [$bookmarks]];
151
        }
152
153
        return [];
154
    }
155
156
    /**
157
     * @return array
158
     */
159
    public function getLastError()
160
    {
161
        return $this->lastError;
162
    }
163
}