Facebook::getStats()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Borfast\Socializr\Connectors;
4
5
use Borfast\Socializr\Exceptions\AuthorizationException;
6
use Borfast\Socializr\Exceptions\ExpiredTokenException;
7
use Borfast\Socializr\Exceptions\GenericPostingException;
8
use Borfast\Socializr\Group;
9
use Borfast\Socializr\Page;
10
use Borfast\Socializr\Post;
11
use Borfast\Socializr\Profile;
12
use Borfast\Socializr\Response;
13
14
class Facebook extends AbstractConnector
15
{
16
    public static $provider = 'Facebook';
17
18
    /** @var Profile */
19
    protected $profile = null;
20
21
    public function request($path, $method = 'GET', $params = [], $headers = [])
22
    {
23
        $result = parent::request($path, $method, $params, $headers);
24
25
        $json_result = json_decode($result, true);
26
27
28
        if (isset($json_result['error'])) {
29
            if (isset($json_result['error']['error_subcode'])) {
30
                $error_subcode = $json_result['error']['error_subcode'];
31
            } else {
32
                $error_subcode = 'n/a';
33
            }
34
35
            $error_type = $json_result['error']['type'];
36
            $error_code = $json_result['error']['code'];
37
            $error_message = $json_result['error']['message'];
38
39
            $msg = 'Error type: %s. Error code: %s. Error subcode: %s. Message: %s';
40
            $msg = sprintf(
41
                $msg,
42
                $error_type,
43
                $error_code,
44
                $error_subcode,
45
                $error_message
46
            );
47
48
49
            if ($error_type == 'OAuthException' &&
50
                // Handling random issues by steering them towards GenericPostingException
51
                $error_code != 1 &&
52
                strpos($error_message, 'Provided link was incorrect or disallowed') === false &&
53
                strpos($error_message, 'Service temporarily unavailable') === false
54
            ) {
55
                throw new ExpiredTokenException($msg);
56
            } else if ($error_type == 'GraphMethodException' && $error_code == '100') {
57
                throw new AuthorizationException();
58
            } else {
59
                throw new GenericPostingException($msg);
60
            }
61
62
        }
63
64
        return $result;
65
    }
66
67
68
    public function post(Post $post)
69
    {
70
        $msg  = $post->title;
71
        $msg .= "\n\n";
72
        $msg .= $post->body;
73
        $msg = trim($msg);
74
75
        if (empty($post->media)) {
76
            $path = '/'.$this->getProfile()->id.'/feed';
77
78
            $params = [
79
                // 'caption' => $post->title,
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
80
                'description' => '',
81
                'link' => $post->url,
82
                'message' => $msg
83
            ];
84
        } else {
85
            $path = '/'.$this->getProfile()->id.'/photos';
86
87
            $msg .= "\n";
88
            $msg .= $post->url;
89
90
            $params = [
91
                'url' => $post->media[0],
92
                'caption' => $msg
93
            ];
94
        }
95
96
        $method = 'POST';
97
98
        $result = $this->request($path, $method, $params);
99
100
        $json_result = json_decode($result, true);
101
102
        // If there's no ID, the post didn't go through
103
        if (!isset($json_result['id'])) {
104
            $msg = "Unknown error posting to Facebook profile.";
105
            throw new GenericPostingException($msg, 1);
106
        }
107
108
        $response = new Response;
109
        $response->setRawResponse($result); // This is already JSON.
110
        $response->setProvider('Facebook');
111
        $response->setPostId($json_result['id']);
112
113
        return $response;
114
    }
115
116 View Code Duplication
    public function getProfile()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
    {
118
        if (is_null($this->profile)) {
119
            $path = '/me';
120
            $result = $this->request($path);
121
            $json_result = json_decode($result, true);
122
123
            $mapping = [
124
                'id' => 'id',
125
                'email' => 'email',
126
                'name' => 'name',
127
                'first_name' => 'first_name',
128
                'middle_name' => 'middle_name',
129
                'last_name' => 'last_name',
130
                'username' => 'username',
131
                // 'username' => 'email', // Facebook Graph API 2.0 doesn't have username
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
132
                'link' => 'link'
133
            ];
134
135
            $this->profile = Profile::create($mapping, $json_result);
136
            $this->profile->provider = static::$provider;
137
            $this->profile->raw_response = $result;
138
        }
139
140
        return $this->profile;
141
    }
142
143
    public function getPermissions()
144
    {
145
        $profile = $this->getProfile();
146
147
        $path = '/'.$profile->id.'/permissions';
148
        return $this->request($path);
149
    }
150
151
    public function getStats()
152
    {
153
        return $this->getFriendsCount();
154
    }
155
156
    public function getPages()
157
    {
158
        $profile = $this->getProfile();
159
160
        $path = '/'.$profile->id.'/accounts?fields=name,picture,access_token,id,can_post,likes,link,username';
161
        $result = $this->request($path);
162
        $json_result = json_decode($result, true);
163
164
        $pages = [];
165
166
        $mapping = [
167
            'id' => 'id',
168
            'name' => 'name',
169
            'link' => 'link',
170
            'can_post' => 'can_post',
171
            'access_token' => 'access_token'
172
        ];
173
174
        // Make the page IDs available as the array keys
175 View Code Duplication
        if (!empty($json_result['data'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
176
            foreach ($json_result['data'] as $page) {
177
                $pages[$page['id']] = Page::create($mapping, $page);
178
                $pages[$page['id']]->picture = $page['picture']['data']['url'];
179
                $pages[$page['id']]->provider = static::$provider;
180
                $pages[$page['id']]->raw_response = $result;
181
            }
182
        }
183
184
        return $pages;
185
    }
186
187
    public function getGroups()
188
    {
189
        $profile = $this->getProfile();
190
191
        $path = '/'.$profile->id.'/groups?fields=id,name,icon';
192
        $result = $this->request($path);
193
        $json_result = json_decode($result, true);
194
195
        $groups = [];
196
197
        $mapping = [
198
            'id' => 'id',
199
            'name' => 'name',
200
            'picture' => 'icon'
201
        ];
202
203
        // Make the group IDs available as the array keys
204
        if (!empty($json_result['data'])) {
205
            foreach ($json_result['data'] as $group) {
206
                $groups[$group['id']] = Group::create($mapping, $group);
207
                $groups[$group['id']]->picture = $group['icon'];
208
                $groups[$group['id']]->link = 'https://www.facebook.com/groups/' . $group['id'];
209
                $groups[$group['id']]->can_post = true;
210
                $groups[$group['id']]->provider = static::$provider;
211
                $groups[$group['id']]->raw_response = $result;
212
            }
213
        }
214
215
        return $groups;
216
    }
217
218
    /****************************************************
219
     *
220
     * From here on these are Facebook-specific methods.
221
     *
222
     ***************************************************/
223
    public function getFriendsCount()
224
    {
225
        $path = '/'.$this->getProfile()->id.'/friends';
226
        $result = $this->request($path);
227
228
        $response = json_decode($result);
229
230
        if (property_exists($response, 'summary')) {
231
            $response = $response->summary->total_count;
232
        } else {
233
            $response = '-';
234
        }
235
236
        return $response;
237
    }
238
}
239