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

UserUpload   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 189
Duplicated Lines 3.7 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 6
Bugs 3 Features 1
Metric Value
wmc 16
c 6
b 3
f 1
lcom 1
cbo 6
dl 7
loc 189
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 7 7 1
A getBaseUrl() 0 4 1
A setBaseUrl() 0 4 1
A upload() 0 23 3
B getUploadTicket() 0 24 3
B getJobStatus() 0 24 3
B getUploadHistory() 0 28 4

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\service;
4
5
use Audiens\AppnexusClient\Auth;
6
use Audiens\AppnexusClient\CachableTrait;
7
use Audiens\AppnexusClient\CacheableInterface;
8
use Audiens\AppnexusClient\entity\UploadTicket;
9
use Audiens\AppnexusClient\entity\UploadJobStatus;
10
use Audiens\AppnexusClient\exceptions\UploadException;
11
use Audiens\AppnexusClient\repository\RepositoryResponse;
12
use Doctrine\Common\Cache\Cache;
13
use GuzzleHttp\Client;
14
use GuzzleHttp\ClientInterface;
15
16
/**
17
 * Class UserSegmentRepository
18
 */
19
class UserUpload implements CacheableInterface
20
{
21
22
    use CachableTrait;
23
24
    const BASE_URL = 'http://api.adnxs.com/batch-segment';
25
26
    const SANDBOX_BASE_URL = 'http://api-test.adnxs.com/batch-segment';
27
28
    /** @var  \SplQueue */
29
    protected $userSegments;
30
31
    /** @var Client|Auth */
32
    protected $client;
33
34
    /** @var  int */
35
    protected $memberId;
36
37
    /** @var  Cache */
38
    protected $cache;
39
40
    /** @var  string */
41
    protected $baseUrl;
42
43
    const CACHE_NAMESPACE = 'appnexus_segment_user_upload';
44
45
    const CACHE_EXPIRATION = 3600;
46
47
    /**
48
     * SegmentRepository constructor.
49
     *
50
     * @param ClientInterface $client
51
     * @param Cache|null      $cache
52
     */
53 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...
54
    {
55
        $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...
56
        $this->cache = $cache;
57
        $this->cacheEnabled = $cache instanceof Cache;
58
        $this->baseUrl = self::BASE_URL;
59
    }
60
61
    /**
62
     * @return string
63
     */
64
    public function getBaseUrl()
65
    {
66
        return $this->baseUrl;
67
    }
68
69
    /**
70
     * @param string $baseUrl
71
     */
72
    public function setBaseUrl($baseUrl)
73
    {
74
        $this->baseUrl = $baseUrl;
75
    }
76
77
78
    /**
79
     * @param $memberId
80
     * @param $fileAsString
81
     *
82
     * @return UploadJobStatus
83
     * @throws UploadException
84
     */
85
    public function upload($memberId, $fileAsString)
86
    {
87
        if (empty($fileAsString)) {
88
            throw UploadException::emptyFile();
89
        }
90
91
        $tempFile = tmpfile();
92
        fwrite($tempFile, $fileAsString);
93
        fseek($tempFile, 0);
94
95
        $job = $this->getUploadTicket($memberId);
96
97
        $response = $this->client->request('POST', $job->getUploadUrl(), ['body' => $tempFile]);
98
99
        $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...
100
101
        if (!$repositoryResponse->isSuccessful()) {
102
            throw UploadException::failed($repositoryResponse);
103
        }
104
105
        return $this->getJobStatus($job);
106
107
    }
108
109
    /**
110
     * @param $memberId
111
     *
112
     * @return UploadJobStatus
113
     * @throws UploadException
114
     */
115
    public function getUploadTicket($memberId)
116
    {
117
118
        $compiledUrl = $this->baseUrl.'?member_id='.$memberId;
119
120
        $response = $this->client->request('POST', $compiledUrl);
121
122
        $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...
123
124
        if (!$repositoryResponse->isSuccessful()) {
125
            throw UploadException::failed($repositoryResponse);
126
        }
127
128
        if (!isset($repositoryResponse->getResponseAsArray()['response']['batch_segment_upload_job'])) {
129
            throw UploadException::missingIndex('response->batch_segment_upload_job');
130
        }
131
132
        $uploadJob = UploadTicket::fromArray(
133
            $repositoryResponse->getResponseAsArray()['response']['batch_segment_upload_job']
134
        );
135
136
        return $uploadJob;
137
138
    }
139
140
    /**
141
     * @param UploadTicket $uploadTicket
142
     *
143
     * @return UploadJobStatus
144
     * @throws UploadException
145
     */
146
    public function getJobStatus(UploadTicket $uploadTicket)
147
    {
148
149
        $compiledUrl = $this->baseUrl."?member_id={$uploadTicket->getMemberId()}&job_id={$uploadTicket->getJobId()}";
150
151
        $response = $this->client->request('GET', $compiledUrl);
152
153
        $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...
154
155
        if (!$repositoryResponse->isSuccessful()) {
156
            throw UploadException::failed($repositoryResponse);
157
        }
158
159
        if (!isset($repositoryResponse->getResponseAsArray()['response']['batch_segment_upload_job'][0])) {
160
            throw UploadException::missingIndex('response->batch_segment_upload_job->0');
161
        }
162
163
        $uploadJobStatus = UploadJobStatus::fromArray(
164
            $repositoryResponse->getResponseAsArray()['response']['batch_segment_upload_job'][0]
165
        );
166
167
        return $uploadJobStatus;
168
169
    }
170
171
    /**
172
     * @param     $memberId
173
     * @param int $start
174
     * @param int $maxResults
175
     *
176
     * @return UploadJobStatus[]
177
     * @throws \Exception
178
     */
179
    public function getUploadHistory($memberId, $start = 0, $maxResults = 100)
180
    {
181
182
        $compiledUrl = $this->baseUrl."?member_id=$memberId&start_element=$start&num_elements=$maxResults";
183
184
        $response = $this->client->request('GET', $compiledUrl);
185
186
        $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...
187
188
        if (!$repositoryResponse->isSuccessful()) {
189
            throw UploadException::failed($repositoryResponse);
190
        }
191
192
        if (!isset($repositoryResponse->getResponseAsArray()['response']['batch_segment_upload_job'][0])) {
193
            throw UploadException::missingIndex('response->batch_segment_upload_job->0');
194
        }
195
196
        $uploadStatuses = [];
197
198
        $responseAsArray = $repositoryResponse->getResponseAsArray();
199
200
        foreach ($responseAsArray['response']['batch_segment_upload_job'] as $response) {
201
            $uploadStatuses[] = UploadJobStatus::fromArray($response);
202
        }
203
204
        return $uploadStatuses;
205
206
    }
207
}
208