Completed
Push — master ( 01b1f4...cd2255 )
by Francesco
03:06
created

SegmentRepository   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 215
Duplicated Lines 3.26 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 13
Bugs 3 Features 3
Metric Value
wmc 18
c 13
b 3
f 3
lcom 1
cbo 8
dl 7
loc 215
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 7 7 1
A getBaseUrl() 0 4 1
A setBaseUrl() 0 4 1
B add() 0 28 3
A remove() 0 12 1
A update() 0 20 2
A findOneById() 0 20 2
C findAll() 0 42 7

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 Audiens\AppnexusClient\repository;
4
5
use Audiens\AppnexusClient\CachableTrait;
6
use Audiens\AppnexusClient\CacheableInterface;
7
use Audiens\AppnexusClient\entity\Segment;
8
use Audiens\AppnexusClient\exceptions\RepositoryException;
9
use Doctrine\Common\Cache\Cache;
10
use GuzzleHttp\Client;
11
use GuzzleHttp\ClientInterface;
12
13
/**
14
 * Class SegmentRepository
15
 */
16
class SegmentRepository implements CacheableInterface
17
{
18
19
    use CachableTrait;
20
21
    const BASE_URL = 'https://api.adnxs.com/segment/';
22
23
    const SANDBOX_BASE_URL = 'http://api-test.adnxs.com/segment/';
24
25
    /** @var Client */
26
    protected $client;
27
28
    /** @var  int */
29
    protected $memberId;
30
31
    /** @var  Cache */
32
    protected $cache;
33
34
    /** @var  string */
35
    protected $baseUrl;
36
37
    const CACHE_NAMESPACE = 'appnexus_segment_repository_find_all';
38
39
    const CACHE_EXPIRATION = 3600;
40
41
    /**
42
     * SegmentRepository constructor.
43
     *
44
     * @param ClientInterface $client
45
     * @param Cache|null      $cache
46
     */
47 View Code Duplication
    public function __construct(ClientInterface $client, Cache $cache = null)
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...
48
    {
49
        $this->client = $client;
0 ignored issues
show
Documentation Bug introduced by
$client is of type object<GuzzleHttp\ClientInterface>, but the property $client was declared to be of type object<GuzzleHttp\Client>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
50
        $this->cache = $cache;
51
        $this->cacheEnabled = $cache instanceof Cache;
52
        $this->baseUrl = self::BASE_URL;
53
    }
54
55
    /**
56
     * @return string
57
     */
58
    public function getBaseUrl()
59
    {
60
        return $this->baseUrl;
61
    }
62
63
    /**
64
     * @param string $baseUrl
65
     */
66
    public function setBaseUrl($baseUrl)
67
    {
68
        $this->baseUrl = $baseUrl;
69
    }
70
71
72
    /**
73
     * @param Segment $segment
74
     *
75
     * @return RepositoryResponse
76
     * @throws RepositoryException
77
     */
78
    public function add(Segment $segment)
79
    {
80
81
        $compiledUrl = $this->baseUrl.$segment->getMemberId();
82
83
        $payload = [
84
            'segment' => $segment->toArray(),
85
        ];
86
87
        $response = $this->client->request('POST', $compiledUrl, ['body' => json_encode($payload)]);
88
89
        $repositoryResponse = RepositoryResponse::fromResponse($response);
0 ignored issues
show
Compatibility introduced by
$response of type object<Psr\Http\Message\ResponseInterface> is not a sub-type of object<GuzzleHttp\Psr7\Response>. It seems like you assume a concrete implementation of the interface Psr\Http\Message\ResponseInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
90
91
        if ($repositoryResponse->isSuccessful()) {
92
            $stream = $response->getBody();
93
            $responseContent = json_decode($stream->getContents(), true);
94
            $stream->rewind();
95
96
            if (!(isset($responseContent['response']['segment']['id']))) {
97
                throw RepositoryException::wrongFormat(serialize($responseContent));
98
            }
99
100
            $segment->setId($responseContent['response']['segment']['id']);
101
        }
102
103
        return $repositoryResponse;
104
105
    }
106
107
    /**
108
     * @param $memberId
109
     * @param $id
110
     *
111
     * @return RepositoryResponse
112
     */
113
    public function remove($memberId, $id)
114
    {
115
116
        $compiledUrl = $this->baseUrl.$memberId.'/'.$id;
117
118
        $response = $this->client->request('DELETE', $compiledUrl);
119
120
        $repositoryResponse = RepositoryResponse::fromResponse($response);
0 ignored issues
show
Compatibility introduced by
$response of type object<Psr\Http\Message\ResponseInterface> is not a sub-type of object<GuzzleHttp\Psr7\Response>. It seems like you assume a concrete implementation of the interface Psr\Http\Message\ResponseInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
121
122
        return $repositoryResponse;
123
124
    }
125
126
    /**
127
     * @param Segment $segment
128
     *
129
     * @return RepositoryResponse
130
     * @throws RepositoryException
131
     */
132
    public function update(Segment $segment)
133
    {
134
135
        if (!$segment->getId()) {
136
            throw RepositoryException::missingId($segment);
137
        }
138
139
        $compiledUrl = $this->baseUrl.$segment->getMemberId().'/'.$segment->getId();
140
141
        $payload = [
142
            'segment' => $segment->toArray(),
143
        ];
144
145
        $response = $this->client->request('PUT', $compiledUrl, ['body' => json_encode($payload)]);
146
147
        $repositoryResponse = RepositoryResponse::fromResponse($response);
0 ignored issues
show
Compatibility introduced by
$response of type object<Psr\Http\Message\ResponseInterface> is not a sub-type of object<GuzzleHttp\Psr7\Response>. It seems like you assume a concrete implementation of the interface Psr\Http\Message\ResponseInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
148
149
        return $repositoryResponse;
150
151
    }
152
153
    /**
154
     * @param $id
155
     * @param $memberId
156
     *
157
     * @return Segment|null
158
     */
159
    public function findOneById($memberId, $id)
160
    {
161
162
        $compiledUrl = $this->baseUrl.$memberId.'/'.$id;
163
164
        $response = $this->client->request('GET', $compiledUrl);
165
166
        $repositoryResponse = RepositoryResponse::fromResponse($response);
0 ignored issues
show
Compatibility introduced by
$response of type object<Psr\Http\Message\ResponseInterface> is not a sub-type of object<GuzzleHttp\Psr7\Response>. It seems like you assume a concrete implementation of the interface Psr\Http\Message\ResponseInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
167
168
        if (!$repositoryResponse->isSuccessful()) {
169
            return null;
170
        }
171
172
        $stream = $response->getBody();
173
        $responseContent = json_decode($stream->getContents(), true);
174
        $stream->rewind();
175
176
        return Segment::fromArray($responseContent['response']['segment']);
177
178
    }
179
180
    /**
181
     * @param     $memberId
182
     * @param int $start
183
     * @param int $maxResults
184
     *
185
     * @return Segment[]|null
186
     * @throws RepositoryException
187
     */
188
    public function findAll($memberId, $start = 0, $maxResults = 100)
189
    {
190
191
        $cacheKey = self::CACHE_NAMESPACE.sha1($memberId.$start.$maxResults);
192
193
        if ($this->isCacheEnabled()) {
194
            if ($this->cache->contains($cacheKey)) {
195
                return $this->cache->fetch($cacheKey);
196
            }
197
        }
198
199
        $compiledUrl = $this->baseUrl.$memberId."?start_element=$start&num_elements=$maxResults";
200
201
        $response = $this->client->request('GET', $compiledUrl);
202
203
        $repositoryResponse = RepositoryResponse::fromResponse($response);
0 ignored issues
show
Compatibility introduced by
$response of type object<Psr\Http\Message\ResponseInterface> is not a sub-type of object<GuzzleHttp\Psr7\Response>. It seems like you assume a concrete implementation of the interface Psr\Http\Message\ResponseInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
204
205
        if (!$repositoryResponse->isSuccessful()) {
206
            throw RepositoryException::failed($repositoryResponse);
207
        }
208
209
        $stream = $response->getBody();
210
        $responseContent = json_decode($stream->getContents(), true);
211
        $stream->rewind();
212
213
        $result = [];
214
215
        if (!$responseContent['response']['segments']) {
216
            $responseContent['response']['segments'] = [];
217
        }
218
219
        foreach ($responseContent['response']['segments'] as $segmentArray) {
220
            $result[] = Segment::fromArray($segmentArray);
221
        }
222
223
        if ($this->isCacheEnabled()) {
224
            $this->cache->save($cacheKey, $result, self::CACHE_EXPIRATION);
225
        }
226
227
        return $result;
228
229
    }
230
}
231