LinkedinGroup   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 125
Duplicated Lines 18.4 %

Coupling/Cohesion

Components 2
Dependencies 11

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 10
c 3
b 0
f 0
lcom 2
cbo 11
dl 23
loc 125
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
C post() 0 81 8
A getProfile() 23 23 1
A getStats() 0 7 1

How to fix   Duplicated Code   

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:

1
<?php
2
3
namespace Borfast\Socializr\Connectors;
4
5
use OAuth\Common\Storage\Exception\TokenNotFoundException;
6
use Borfast\Socializr\Exceptions\AuthorizationException;
7
use Borfast\Socializr\Exceptions\LinkedinForbiddenException;
8
use Borfast\Socializr\Exceptions\LinkedinPostingException;
9
use Borfast\Socializr\Post;
10
use Borfast\Socializr\Profile;
11
use Borfast\Socializr\Response;
12
use GuzzleHttp\Client as Guzzle;
13
use GuzzleHttp\Exception\ClientException;
14
15
class LinkedinGroup extends AbstractConnector
16
{
17
    public static $provider = 'linkedin';
18
19
    /**
20
     * @param Post $post
21
     * @return Response
22
     * @throws LinkedinForbiddenException
23
     * @throws LinkedinPostingException
24
     */
25
    public function post(Post $post)
26
    {
27
        $group_id = $post->options['group_id'];
28
29
        try {
30
            $token = $this->service->getStorage()->retrieveAccessToken('Linkedin')->getAccessToken();
31
        } catch (TokenNotFoundException $e) {
32
            throw new AuthorizationException();
33
        }
34
35
        $path = '/groups/'.$group_id.'/posts?format=json&oauth2_access_token='.$token;
36
        $params = [
37
            'title' => $post->title,
38
            'summary' => '',
39
            'content' => [
40
                'title' => $post->title . ' @',
41
                'submitted-url' => $post->url,
42
                'description' => $post->body,
43
            ],
44
        ];
45
46
        // Add media files, if they were sent.
47
        if (isset($post->media) && array_key_exists(0, $post->media)) {
48
            $params['content']['submitted-image-url'] = $post->media[0];
49
        }
50
51
        $params = json_encode($params);
52
53
        $url = 'https://api.linkedin.com/v1'.$path;
54
        // Linkedin API requires the Content-Type header set to application/json
55
        $options = [
56
            'headers' => ['Content-Type' => 'application/json'],
57
            'body' => $params
58
        ];
59
60
        $client = new Guzzle();
61
        try {
62
            $result = $client->post($url, $options);
63
        } catch (ClientException $e) {
64
            if ($e->getCode() >= 400) {
65
                throw new LinkedinForbiddenException($e);
66
            } else {
67
                throw $e;
68
            }
69
        }
70
71
        if ($result->getStatusCode() > 300) {
72
            $msg = "Error posting to Linkedin group. Error code from Linkedin: %s. Error message from Linkedin: %s";
73
            $msg = sprintf($msg, $result->status_code, json_decode($result->body)->message);
0 ignored issues
show
Bug introduced by
Accessing status_code on the interface GuzzleHttp\Message\ResponseInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
Accessing body on the interface GuzzleHttp\Message\ResponseInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
74
            throw new LinkedinPostingException($msg, $result->status_code);
0 ignored issues
show
Bug introduced by
Accessing status_code on the interface GuzzleHttp\Message\ResponseInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
75
        }
76
77
        $response = new Response;
78
        $response->setRawResponse($result); // This is already JSON.
79
        $response->setProvider(static::$provider);
80
        //$response->setPostId($result->getHeader('x-li-uuid'));
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
81
82
        // As amazing as it may sound, there's a three year old bug that LinkedIn
83
        // knows of but doesn't fix, which is simply the group posts URL is not
84
        // returned when we create the post, and when the post endpoint is queried
85
        // it returns a URL containing an incorrect domain: api.linkedin.com
86
        // instead of www.linkedin.com. They acknowledge this in the "Known Issues"
87
        // section of the groups API documentation and say the workaround is simple:
88
        // just swap the domains. Well, thanks for nothing. Would it be so hard for
89
        // them to return a public URL along with the response of the creation?...
90
        // So we need to make another API call to fetch the correct URL, because
91
        // it's not even possible to generate it manually.
92
93
        // Moderated groups don't return a 'location' header, so let's skip it if that's the case.
94
        $location = $result->getHeader('Location');
95
        if (!empty($location)) {
96
            $url = $location . ':(id,site-group-post-url)?format=json&oauth2_access_token=' . $token;
97
            $result = $client->get($url);
98
            $json = $result->json();
99
100
            $post_url = str_replace('api.linkedin.com/v1', 'www.linkedin.com', $json['siteGroupPostUrl']);
101
            $response->setPostUrl($post_url);
102
        }
103
104
        return $response;
105
    }
106
107
108 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...
109
    {
110
        $path = '/people/~:(id,first-name,last-name,maiden-name,public-profile-url,formatted-name,num-connections,email-address,num-recommenders)?format=json';
111
        $response = $this->service->request($path);
112
        $profile_json = json_decode($response, true);
113
114
        $mapping = [
115
            'id' => 'id',
116
            'email' => 'emailAddress',
117
            'name' => 'formattedName',
118
            'first_name' => 'firstName',
119
            'middle_name' => 'maidenName',
120
            'last_name' => 'lastName',
121
            // 'username' => 'username',
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
122
            'link' => 'publicProfileUrl'
123
        ];
124
125
        $profile = Profile::create($mapping, $profile_json);
126
        $profile->provider = static::$provider;
127
        $profile->raw_response = $response;
128
129
        return $profile;
130
    }
131
132
    public function getStats()
133
    {
134
        $path = 'groups/'.$this->id.':(id,num-members)?format=json';
135
        $response = json_decode($this->request($path));
136
137
        return $response->numMembers;
138
    }
139
}
140