Passed
Push — master ( 87cf99...8ae428 )
by Ralf
08:45
created

FedoraRepository::delete()   B

Complexity

Conditions 8
Paths 26

Size

Total Lines 42
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 29
nc 26
nop 2
dl 0
loc 42
rs 8.2114
c 0
b 0
f 0
1
<?php
2
namespace EWW\Dpf\Services\Transfer;
3
4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
$extpath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('dpf');
18
19
\Httpful\Bootstrap::init();
20
21
22
use \EWW\Dpf\Services\Logger\TransferLogger;
23
use \Httpful\Request;
24
25
class FedoraRepository implements Repository
26
{
27
28
    /**
29
     * documentTransferLogRepository
30
     *
31
     * @var \EWW\Dpf\Domain\Repository\DocumentTransferLogRepository
32
     * @inject
33
     */
34
    protected $documentTransferLogRepository;
35
36
    /**
37
    * clientConfigurationManager
38
    *
39
    * @var \EWW\Dpf\Configuration\ClientConfigurationManager
40
    * @inject
41
    */
42
    protected $clientConfigurationManager;
43
44
    /**
45
     * objectManager
46
     *
47
     * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
48
     * @inject
49
     */
50
    protected $objectManager;
51
52
    protected $response;
53
54
    protected $errors = array();
55
56
    const X_ON_BEHALF_OF = 'X-On-Behalf-Of';
57
    const QUCOSA_TYPE    = 'application/vnd.qucosa.mets+xml';
58
59
60
    /**
61
     * Saves a new document into the Fedora repository
62
     *
63
     * @param \EWW\Dpf\Domain\Model\Document $document
64
     * @return string
65
     * @throws \Exception
66
     */
67
    public function ingest($document, $metsXml)
68
    {
69
        try {
70
71
            $response = Request::post($this->clientConfigurationManager->getSwordHost() . "/sword/" . $this->getSWORDCollection())
72
                ->sendsXml()
73
                ->body($metsXml)
74
                ->authenticateWith($this->clientConfigurationManager->getSwordUser(), $this->clientConfigurationManager->getSwordPassword())
75
                ->sendsType(FedoraRepository::QUCOSA_TYPE)
76
                ->addHeader(FedoraRepository::X_ON_BEHALF_OF, $this->getOwnerId())
77
                ->addHeader('Slug', $document->getReservedObjectIdentifier())
78
                ->send();
79
80
            // if transfer successful
81
            if (!$response->hasErrors() && $response->code == 201) {
82
                return $this->getRemoteDocumentId($response);
83
            } else {
84
                TransferLogger::Log('INGEST', $document->getUid(), null, $response);
85
                throw new \EWW\Dpf\Exceptions\IngestDocumentErrorException("Fedora error while ingest document.");
86
            }
87
        }
88
        catch (\Exception $exception) {
89
            TransferLogger::Log('INGEST', $document->getUid(), null, $exception->getMessage());
90
91
            if ($exception instanceof \Httpful\Exception\ConnectionErrorException) {
92
                $message = $exception->getMessage();
93
                throw new \EWW\Dpf\Exceptions\RepositoryConnectionErrorException($message);
94
            } else {
95
                throw $exception;
96
            }
97
        }
98
99
        return null;
0 ignored issues
show
Unused Code introduced by
return null is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
100
    }
101
102
    /**
103
     * Updates an existing document in the Fedora repository
104
     *
105
     * @param \EWW\Dpf\Domain\Model\Document $document
106
     * @param string $metsXml
107
     * @return string
108
     * @throws \Exception
109
     */
110
    public function update($document, $metsXml)
111
    {
112
113
        $remoteId = $document->getObjectIdentifier();
114
115
        try {
116
            $response = Request::put($this->clientConfigurationManager->getSwordHost() . "/sword/" . $this->getSWORDCollection() . "/" . $remoteId)
117
                ->sendsXml()
118
                ->body($metsXml)
119
                ->authenticateWith($this->clientConfigurationManager->getSwordUser(), $this->clientConfigurationManager->getSwordPassword())
120
                ->sendsType(FedoraRepository::QUCOSA_TYPE)
121
                ->addHeader(FedoraRepository::X_ON_BEHALF_OF, $this->getOwnerId())
122
                ->send();
123
124
            // if transfer successful
125
            if (!$response->hasErrors() && $response->code == 200) {
126
                return $this->getRemoteDocumentId($response);
127
            } else {
128
                TransferLogger::Log('UPDATE', $document->getUid(), $remoteId, $response);
129
                throw new \EWW\Dpf\Exceptions\UpdateDocumentErrorException("Fedora error while update document.");
130
            }
131
        } catch (\Exception $exception) {
132
            TransferLogger::Log('UPDATE', $document->getUid(), null, $exception->getMessage());
133
134
            if ($exception instanceof \Httpful\Exception\ConnectionErrorException) {
135
                $message = $exception->getMessage();
136
                throw new \EWW\Dpf\Exceptions\RepositoryConnectionErrorException($message);
137
            } else {
138
                throw $exception;
139
            }
140
        }
141
142
        return null;
0 ignored issues
show
Unused Code introduced by
return null is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
143
    }
144
145
    /**
146
     * Gets an existing document from the Fedora repository
147
     *
148
     * @param string $remoteId
149
     * @return string
150
     * @throws \Exception
151
     */
152
    public function retrieve($remoteId)
153
    {
154
155
        try {
156
            $response = Request::get($this->clientConfigurationManager->getFedoraHost() . "/fedora/objects/" . $remoteId . "/methods/qucosa:SDef/getMETSDissemination")
157
                ->authenticateWith($this->clientConfigurationManager->getFedoraUser(), $this->clientConfigurationManager->getFedoraPassword())
158
                ->addHeader(FedoraRepository::X_ON_BEHALF_OF, $this->getOwnerId())
159
                ->send();
160
161
            // if transfer successful
162
            if (!$response->hasErrors() && $response->code == 200) {
163
                return $response->__toString();
164
            } else {
165
                TransferLogger::Log('RETRIEVE', null, $remoteId, $response);
166
                throw new \EWW\Dpf\Exceptions\RetrieveDocumentErrorException("Fedora has returned an error.");
167
            }
168
        } catch (\Exception $exception) {
169
            TransferLogger::Log('RETRIEVE', null, $remoteId, $exception->getMessage());
170
171
            if ($exception instanceof \Httpful\Exception\ConnectionErrorException) {
172
                $message = $exception->getMessage();
173
                throw new \EWW\Dpf\Exceptions\RepositoryConnectionErrorException($message);
174
            } else {
175
                throw $exception;
176
            }
177
        }
178
179
        return null;
0 ignored issues
show
Unused Code introduced by
return null is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
180
    }
181
182
    /**
183
     * Reserves a new DocumentId (qucosa id)
184
     *
185
     * @param string $remoteId
186
     * @return string
187
     * @throws \Exception
188
     */
189
    public function getNextDocumentId()
190
    {
191
        try {
192
            $response = Request::get($this->clientConfigurationManager->getFedoraHost() . "/fedora/management/getNextPID?numPIDs=1&namespace=qucosa&xml=true")
193
                ->authenticateWith($this->clientConfigurationManager->getFedoraUser(), $this->clientConfigurationManager->getFedoraPassword())
194
                ->addHeader(FedoraRepository::X_ON_BEHALF_OF, $this->getOwnerId())
195
            //->addHeader()
196
                ->send();
197
198
            // if transfer successful
199
            if (!$response->hasErrors() && $response->code == 200) {
200
                return $response->__toString();
201
            } else {
202
                TransferLogger::Log('GET_NEXT_DOCUMENT_ID', null, null, $response);
203
                throw new \EWW\Dpf\Exceptions\NextDocumentIdErrorException("Fedora error while getting a document id.");
204
            }
205
        } catch (\Exception $exception) {
206
            TransferLogger::Log('GET_NEXT_DOCUMENT_ID', null, null, $exception->getMessage());
207
208
            if ($exception instanceof \Httpful\Exception\ConnectionErrorException) {
209
                $message = $exception->getMessage();
210
                throw new \EWW\Dpf\Exceptions\RepositoryConnectionErrorException($message);
211
            } else {
212
                throw $exception;
213
            }
214
        }
215
216
        return null;
0 ignored issues
show
Unused Code introduced by
return null is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
217
    }
218
219
    /**
220
     * Removes an existing document from the Fedora repository
221
     *
222
     * @param \EWW\Dpf\Domain\Model\Document $document
223
     * @param $state
224
     * @return boolean
225
     * @throws \Exception
226
     */
227
    public function delete($document, $state)
228
    {
229
230
        $remoteId = $document->getObjectIdentifier();
231
232
        $state = ($state) ? "?" . $state : "";
233
234
        try {
235
            $response = Request::delete($this->clientConfigurationManager->getSwordHost() . "/sword/" . $this->getSWORDCollection() . "/" . $remoteId . $state)
236
                ->authenticateWith($this->clientConfigurationManager->getSwordUser(), $this->clientConfigurationManager->getSwordPassword())
237
                ->addHeader(FedoraRepository::X_ON_BEHALF_OF, $this->getOwnerId())
238
                ->send();
239
240
            // if transfer successful
241
            if (!$response->hasErrors() && $response->code == 204) {
242
                return true;
243
            } else {
244
                TransferLogger::Log('DELETE', $document->getUid(), $remoteId, $response);
245
                switch ($state) {
246
                    case "revert":
247
                        throw new \EWW\Dpf\Exceptions\ActivateDocumentErrorException("Fedora error while activate document.");
248
                        break;
249
                    case "inactivate":
250
                        throw new \EWW\Dpf\Exceptions\RestoreDocumentErrorException("Fedora error while restore document.");
251
                        break;
252
                    default:
253
                        throw new \EWW\Dpf\Exceptions\DeleteDocumentErrorException("Fedora error while delete document.");
254
                        break;
255
                }
256
            }
257
        } catch (\Exception $exception) {
258
            TransferLogger::Log('DELETE', $document->getUid(), null, $exception->getMessage());
259
260
            if ($exception instanceof \Httpful\Exception\ConnectionErrorException) {
261
                $message = $exception->getMessage();
262
                throw new \EWW\Dpf\Exceptions\RepositoryConnectionErrorException($message);
263
            } else {
264
                throw $exception;
265
            }
266
        }
267
268
        return false;
0 ignored issues
show
Unused Code introduced by
return false is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
269
    }
270
271
    /**
272
     * Gets the remoteDocumentId from the repository XML response.
273
     *
274
     * @param  \Httpful\Response $response
275
     * @return string
276
     */
277
    protected function getRemoteDocumentId($response)
278
    {
279
280
        // Get repository ID and write into document
281
        $responseDom = new \DOMDocument();
282
        $responseDom->loadXML($response->raw_body);
283
        $responseXpath = new \DOMXPath($responseDom);
284
        $responseXpath->registerNamespace("atom", "http://www.w3.org/2005/Atom");
285
        $responseNodes = $responseXpath->query("/atom:entry/atom:id");
286
287
        if ($responseNodes->length > 0) {
288
            $objectIdentifier = $responseNodes->item(0)->nodeValue;
289
            return $objectIdentifier;
290
        }
291
292
        return null;
293
    }
294
295
    protected function getOwnerId()
296
    {
297
        $ownerId = $this->clientConfigurationManager->getOwnerId();
298
        if (empty($ownerId)) {
299
            throw new \Exception('Owner id can not be empty or null!');
300
        }
301
302
        return $ownerId;
303
    }
304
305
    protected function getSWORDCollection()
306
    {
307
        return $this->clientConfigurationManager->getSwordCollectionNamespace();
308
    }
309
}
310