Completed
Pull Request — master (#17)
by Christian
03:05
created

StatementsApiClient::getStatements()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 4
nop 1
crap 3
1
<?php
2
3
/*
4
 * This file is part of the xAPI package.
5
 *
6
 * (c) Christian Flothmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Xabbuh\XApi\Client\Api;
13
14
use Http\Message\MultipartStream\MultipartStreamBuilder;
15
use Xabbuh\XApi\Client\Http\AttachmentsBody;
16
use Xabbuh\XApi\Client\Request\HandlerInterface;
17
use Xabbuh\XApi\Model\StatementId;
18
use Xabbuh\XApi\Serializer\ActorSerializerInterface;
19
use Xabbuh\XApi\Serializer\StatementResultSerializerInterface;
20
use Xabbuh\XApi\Serializer\StatementSerializerInterface;
21
use Xabbuh\XApi\Model\Actor;
22
use Xabbuh\XApi\Model\Statement;
23
use Xabbuh\XApi\Model\StatementResult;
24
use Xabbuh\XApi\Model\StatementsFilter;
25
26
/**
27
 * Client to access the statements API of an xAPI based learning record store.
28
 *
29
 * @author Christian Flothmann <[email protected]>
30
 */
31
final class StatementsApiClient implements StatementsApiClientInterface
32
{
33
    private $requestHandler;
34
    private $version;
35
    private $statementSerializer;
36
    private $statementResultSerializer;
37
    private $actorSerializer;
38
39
    /**
40
     * @param HandlerInterface                   $requestHandler            The HTTP request handler
41
     * @param string                             $version                   The xAPI version
42
     * @param StatementSerializerInterface       $statementSerializer       The statement serializer
43
     * @param StatementResultSerializerInterface $statementResultSerializer The statement result serializer
44
     * @param ActorSerializerInterface           $actorSerializer           The actor serializer
45
     */
46 17
    public function __construct(
47
        HandlerInterface $requestHandler,
48
        $version,
49
        StatementSerializerInterface $statementSerializer,
50
        StatementResultSerializerInterface $statementResultSerializer,
51
        ActorSerializerInterface $actorSerializer
52
    ) {
53 17
        $this->requestHandler = $requestHandler;
54 17
        $this->version = $version;
55 17
        $this->statementSerializer = $statementSerializer;
56 17
        $this->statementResultSerializer = $statementResultSerializer;
57 17
        $this->actorSerializer = $actorSerializer;
58 17
    }
59
60
    /**
61
     * {@inheritDoc}
62
     */
63 4
    public function storeStatement(Statement $statement)
64
    {
65 4
        if (null !== $statement->getId()) {
66 2
            return $this->doStoreStatements(
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->doStoreStatements...d()->getValue()), 204); of type array|Xabbuh\XApi\Model\Statement adds the type array to the return on line 66 which is incompatible with the return type declared by the interface Xabbuh\XApi\Client\Api\S...terface::storeStatement of type Xabbuh\XApi\Model\Statement.
Loading history...
67
                $statement,
68 2
                'put',
69 2
                array('statementId' => $statement->getId()->getValue()),
70 2
                204
71
            );
72
        } else {
73 2
            return $this->doStoreStatements($statement);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->doStoreStatements($statement); of type array|Xabbuh\XApi\Model\Statement adds the type array to the return on line 73 which is incompatible with the return type declared by the interface Xabbuh\XApi\Client\Api\S...terface::storeStatement of type Xabbuh\XApi\Model\Statement.
Loading history...
74
        }
75
    }
76
77
    /**
78
     * {@inheritDoc}
79
     */
80 4
    public function storeStatements(array $statements)
81
    {
82
        // check that only Statements without ids will be sent to the LRS
83 4
        foreach ($statements as $statement) {
84
            /** @var Statement $statement */
85
86 4
            $isStatement = is_object($statement) && $statement instanceof Statement;
87
88 4
            if (!$isStatement || null !== $statement->getId()) {
89 4
                throw new \InvalidArgumentException('API can only handle statements without ids');
90
            }
91
        }
92
93 1
        return $this->doStoreStatements($statements);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->doStoreStatements($statements); of type array|Xabbuh\XApi\Model\Statement adds the type Xabbuh\XApi\Model\Statement to the return on line 93 which is incompatible with the return type declared by the interface Xabbuh\XApi\Client\Api\S...erface::storeStatements of type Xabbuh\XApi\Model\Statement[].
Loading history...
94
    }
95
96
    /**
97
     * {@inheritDoc}
98
     */
99 1
    public function voidStatement(Statement $statement, Actor $actor)
100
    {
101 1
        return $this->storeStatement($statement->getVoidStatement($actor));
102
    }
103
104
    /**
105
     * {@inheritDoc}
106
     */
107 2
    public function getStatement(StatementId $statementId, $attachments = true)
108
    {
109 2
        return $this->doGetStatements('statements', array(
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->doGetStatements('...s ? 'true' : 'false')); of type Xabbuh\XApi\Model\Statem...i\Model\StatementResult adds the type Xabbuh\XApi\Model\StatementResult to the return on line 109 which is incompatible with the return type declared by the interface Xabbuh\XApi\Client\Api\S...Interface::getStatement of type Xabbuh\XApi\Model\Statement.
Loading history...
110 2
            'statementId' => $statementId->getValue(),
111 2
            'attachments' => $attachments ? 'true' : 'false',
112
        ));
113
    }
114
115
    /**
116
     * {@inheritDoc}
117
     */
118 2
    public function getVoidedStatement(StatementId $statementId, $attachments = true)
119
    {
120 2
        return $this->doGetStatements('statements', array(
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->doGetStatements('...s ? 'true' : 'false')); of type Xabbuh\XApi\Model\Statem...i\Model\StatementResult adds the type Xabbuh\XApi\Model\StatementResult to the return on line 120 which is incompatible with the return type declared by the interface Xabbuh\XApi\Client\Api\S...ace::getVoidedStatement of type Xabbuh\XApi\Model\Statement.
Loading history...
121 2
            'voidedStatementId' => $statementId->getValue(),
122 2
            'attachments' => $attachments ? 'true' : 'false',
123
        ));
124
    }
125
126
    /**
127
     * {@inheritDoc}
128
     */
129 4
    public function getStatements(StatementsFilter $filter = null)
130
    {
131 4
        $urlParameters = array();
132
133 4
        if (null !== $filter) {
134 3
            $urlParameters = $filter->getFilter();
135
        }
136
137
        // the Agent must be JSON encoded
138 4
        if (isset($urlParameters['agent'])) {
139 1
            $urlParameters['agent'] = $this->actorSerializer->serializeActor($urlParameters['agent']);
140
        }
141
142 4
        return $this->doGetStatements('statements', $urlParameters);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->doGetStatements('...ents', $urlParameters); of type Xabbuh\XApi\Model\Statem...i\Model\StatementResult adds the type Xabbuh\XApi\Model\Statement to the return on line 142 which is incompatible with the return type declared by the interface Xabbuh\XApi\Client\Api\S...nterface::getStatements of type Xabbuh\XApi\Model\StatementResult.
Loading history...
143
    }
144
145
    /**
146
     * {@inheritDoc}
147
     */
148 1
    public function getNextStatements(StatementResult $statementResult)
149
    {
150 1
        return $this->doGetStatements($statementResult->getMoreUrlPath()->getValue());
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->doGetStatements($...UrlPath()->getValue()); of type Xabbuh\XApi\Model\Statem...i\Model\StatementResult adds the type Xabbuh\XApi\Model\Statement to the return on line 150 which is incompatible with the return type declared by the interface Xabbuh\XApi\Client\Api\S...face::getNextStatements of type Xabbuh\XApi\Model\StatementResult.
Loading history...
151
    }
152
153
    /**
154
     * @param Statement|Statement[] $statements
155
     * @param string                $method
156
     * @param string[]              $parameters
157
     * @param int                   $validStatusCode
158
     *
159
     * @return Statement|Statement[] The created statement(s)
160
     */
161 5
    private function doStoreStatements($statements, $method = 'post', $parameters = array(), $validStatusCode = 200)
162
    {
163 5
        $attachments = array();
164
165 5
        if (is_array($statements)) {
166 1
            foreach ($statements as $statement) {
167 1
                if (null !== $statement->getAttachments()) {
168
                    foreach ($statement->getAttachments() as $attachment) {
169
                        if ($attachment->getContent()) {
170 1
                            $attachments[] = $attachment;
171
                        }
172
                    }
173
                }
174
            }
175
176 1
            $serializedStatements = $this->statementSerializer->serializeStatements($statements);
177
        } else {
178 4
            if (null !== $statements->getAttachments()) {
179
                foreach ($statements->getAttachments() as $attachment) {
180
                    if ($attachment->getContent()) {
0 ignored issues
show
Bug introduced by
The method getContent() does not exist on Xabbuh\XApi\Model\Attachment. Did you maybe mean getContentType()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
181
                        $attachments[] = $attachment;
182
                    }
183
                }
184
            }
185
186 4
            $serializedStatements = $this->statementSerializer->serializeStatement($statements);
187
        }
188
189 5
        $headers = array();
190
191 5
        if (!empty($attachments)) {
192
            $builder = new AttachmentsBody($serializedStatements, $attachments);
193
            $headers = array(
194
                'Content-Type' => 'multipart/mixed; boundary='.$builder->getBoundary(),
195
            );
196
            $body = $builder->build();
197
        } else {
198 5
            $body = $serializedStatements;
199
        }
200
201 5
        $request = $this->requestHandler->createRequest(
202
            $method,
203 5
            'statements',
204
            $parameters,
205
            $body,
206
            $headers
207
        );
208 5
        $response = $this->requestHandler->executeRequest($request, array($validStatusCode));
209 5
        $statementIds = json_decode((string) $response->getBody());
210
211 5
        if (is_array($statements)) {
212
            /** @var Statement[] $statements */
213 1
            $createdStatements = array();
214
215 1
            foreach ($statements as $index => $statement) {
216 1
                $createdStatements[] = $statement->withId(StatementId::fromString($statementIds[$index]));
217
            }
218
219 1
            return $createdStatements;
220
        } else {
221
            /** @var Statement $statements */
222
223 4
            if (200 === $validStatusCode) {
224 2
                return $statements->withId(StatementId::fromString($statementIds[0]));
225
            } else {
226 2
                return $statements;
227
            }
228
        }
229
    }
230
231
    /**
232
     * Fetch one or more Statements.
233
     *
234
     * @param string $url           URL to request
235
     * @param array  $urlParameters URL parameters
236
     *
237
     * @return Statement|StatementResult
238
     */
239 9
    private function doGetStatements($url, array $urlParameters = array())
240
    {
241 9
        $request = $this->requestHandler->createRequest('get', $url, $urlParameters);
242 9
        $response = $this->requestHandler->executeRequest($request, array(200));
243
244 7
        if (isset($urlParameters['statementId']) || isset($urlParameters['voidedStatementId'])) {
245 2
            return $this->statementSerializer->deserializeStatement((string) $response->getBody());
246
        } else {
247 5
            return $this->statementResultSerializer->deserializeStatementResult((string) $response->getBody());
248
        }
249
    }
250
}
251