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

DocumentTransferManager::delete()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 41
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 30
nc 6
nop 2
dl 0
loc 41
rs 8.8177
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
use EWW\Dpf\Domain\Model\Document;
18
use EWW\Dpf\Services\Transfer\ElasticsearchRepository;
19
use EWW\Dpf\Domain\Model\File;
20
21
class DocumentTransferManager
22
{
23
24
    /**
25
     * documenRepository
26
     *
27
     * @var \EWW\Dpf\Domain\Repository\DocumentRepository
28
     * @inject
29
     */
30
    protected $documentRepository;
31
32
    /**
33
     * documenTypeRepository
34
     *
35
     * @var \EWW\Dpf\Domain\Repository\DocumentTypeRepository
36
     * @inject
37
     */
38
    protected $documentTypeRepository;
39
40
    /**
41
     * fileRepository
42
     *
43
     * @var \EWW\Dpf\Domain\Repository\FileRepository
44
     * @inject
45
     */
46
    protected $fileRepository;
47
48
    /**
49
     * objectManager
50
     *
51
     * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
52
     * @inject
53
     */
54
    protected $objectManager;
55
56
    /**
57
     * persistence manager
58
     *
59
     * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
60
     * @inject
61
     */
62
    protected $persistenceManager;
63
64
    /**
65
     * remoteRepository
66
     *
67
     * @var \EWW\Dpf\Services\Transfer\Repository
68
     */
69
    protected $remoteRepository;
70
71
    /**
72
     * Sets the remote repository into which the documents will be stored
73
     *
74
     * @param \EWW\Dpf\Services\Transfer\Repository $remoteRepository
75
     */
76
    public function setRemoteRepository($remoteRepository)
77
    {
78
79
        $this->remoteRepository = $remoteRepository;
80
81
    }
82
83
    /**
84
     * Stores a document into the remote repository
85
     *
86
     * @param \EWW\Dpf\Domain\Model\Document $document
87
     * @return boolean
88
     */
89
    public function ingest($document)
90
    {
91
92
        $document->setTransferStatus(Document::TRANSFER_QUEUED);
93
        $this->documentRepository->update($document);
94
95
        $exporter = new \EWW\Dpf\Services\MetsExporter();
96
97
        $fileData = $document->getFileData();
98
99
        $exporter->setFileData($fileData);
100
101
        $mods = new \EWW\Dpf\Helper\Mods($document->getXmlData());
102
103
        // Set current date as publication date
104
        $dateIssued = (new \DateTime)->format(\DateTime::ISO8601);
105
        $mods->setDateIssued($dateIssued);
106
107
        $exporter->setMods($mods->getModsXml());
108
109
        $exporter->setSlubInfo($document->getSlubInfoData());
110
111
        $exporter->setObjId($document->getObjectIdentifier());
112
113
        $exporter->buildMets();
114
115
        $metsXml = $exporter->getMetsData();
116
117
        // remove document from local index
118
        $elasticsearchRepository = $this->objectManager->get(ElasticsearchRepository::class);
119
        $elasticsearchRepository->delete($document, "");
120
121
        $remoteDocumentId = $this->remoteRepository->ingest($document, $metsXml);
122
123
        if ($remoteDocumentId) {
124
            $document->setDateIssued($dateIssued);
125
            $document->setObjectIdentifier($remoteDocumentId);
126
            $document->setTransferStatus(Document::TRANSFER_SENT);
127
            $this->documentRepository->update($document);
128
            $this->documentRepository->remove($document);
129
130
            return true;
131
        } else {
132
            $document->setTransferStatus(Document::TRANSFER_ERROR);
133
            $this->documentRepository->update($document);
134
            return false;
135
        }
136
137
    }
138
139
    /**
140
     * Updates an existing document in the remote repository
141
     *
142
     * @param \EWW\Dpf\Domain\Model\Document $document
143
     * @return boolean
144
     */
145
    public function update($document)
146
    {
147
        // remove document from local index
148
        $elasticsearchRepository = $this->objectManager->get(ElasticsearchRepository::class);
149
        $elasticsearchRepository->delete($document, "");
150
151
        $document->setTransferStatus(Document::TRANSFER_QUEUED);
152
        $this->documentRepository->update($document);
153
154
        $exporter = new \EWW\Dpf\Services\MetsExporter();
155
156
        $fileData = $document->getFileData();
157
158
        $exporter->setFileData($fileData);
159
160
        $mods = new \EWW\Dpf\Helper\Mods($document->getXmlData());
161
162
        $exporter->setMods($mods->getModsXml());
163
164
        $exporter->setSlubInfo($document->getSlubInfoData());
165
166
        $exporter->setObjId($document->getObjectIdentifier());
167
168
        $exporter->buildMets();
169
170
        $metsXml = $exporter->getMetsData();
171
172
        if ($this->remoteRepository->update($document, $metsXml)) {
173
            $document->setTransferStatus(Document::TRANSFER_SENT);
174
            $this->documentRepository->update($document);
175
            $this->documentRepository->remove($document);
176
177
            return true;
178
        } else {
179
            $document->setTransferStatus(Document::TRANSFER_ERROR);
180
            $this->documentRepository->update($document);
181
            return false;
182
        }
183
184
    }
185
186
    /**
187
     * Gets an existing document from the Fedora repository
188
     *
189
     * @param string $remoteId
190
     * @return boolean
191
     */
192
    public function retrieve($remoteId)
193
    {
194
195
        $metsXml = $this->remoteRepository->retrieve($remoteId);
196
197
        if ($this->documentRepository->findOneByObjectIdentifier($remoteId)) {
0 ignored issues
show
Bug introduced by
The method findOneByObjectIdentifier() does not exist on EWW\Dpf\Domain\Repository\DocumentRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

197
        if ($this->documentRepository->/** @scrutinizer ignore-call */ findOneByObjectIdentifier($remoteId)) {
Loading history...
198
            throw new \Exception("Document already exist: $remoteId");
199
        };
200
201
        if ($metsXml) {
202
            $mets = new \EWW\Dpf\Helper\Mets($metsXml);
203
            $mods = $mets->getMods();
204
            $slub = $mets->getSlub();
205
206
            $title   = $mods->getTitle();
207
            $authors = $mods->getAuthors();
208
209
            $documentTypeName = $slub->getDocumentType();
210
            $documentType     = $this->documentTypeRepository->findOneByName($documentTypeName);
0 ignored issues
show
Bug introduced by
The method findOneByName() does not exist on EWW\Dpf\Domain\Repository\DocumentTypeRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

210
            /** @scrutinizer ignore-call */ 
211
            $documentType     = $this->documentTypeRepository->findOneByName($documentTypeName);
Loading history...
211
212
            if (empty($title) || empty($documentType)) {
213
                return false;
214
            }
215
216
            $state = $mets->getState();
217
218
            switch ($state) {
219
                case "ACTIVE":
220
                    $objectState = Document::OBJECT_STATE_ACTIVE;
221
                    break;
222
                case "INACTIVE":
223
                    $objectState = Document::OBJECT_STATE_INACTIVE;
224
                    break;
225
                case "DELETED":
226
                    $objectState = Document::OBJECT_STATE_DELETED;
227
                    break;
228
                default:
229
                    $objectState = "ERROR";
0 ignored issues
show
Unused Code introduced by
The assignment to $objectState is dead and can be removed.
Loading history...
230
                    throw new \Exception("Unknown object state: " . $state);
231
                    break;
232
            }
233
234
            $document = $this->objectManager->get(Document::class);
235
            $document->setObjectIdentifier($remoteId);
236
            $document->setState($objectState);
237
            $document->setTitle($title);
238
            $document->setAuthors($authors);
239
            $document->setDocumentType($documentType);
240
241
            $document->setXmlData($mods->getModsXml());
242
            $document->setSlubInfoData($slub->getSlubXml());
243
244
            $document->setDateIssued($mods->getDateIssued());
245
246
            $document->setProcessNumber($slub->getProcessNumber());
247
248
            $this->documentRepository->add($document);
249
            $this->persistenceManager->persistAll();
250
251
            foreach ($mets->getFiles() as $attachment) {
252
253
                $file = $this->objectManager->get(File::class);
254
                $file->setContentType($attachment['mimetype']);
255
                $file->setDatastreamIdentifier($attachment['id']);
256
                $file->setLink($attachment['href']);
257
                $file->setTitle($attachment['title']);
258
                $file->setLabel($attachment['title']);
259
                $file->setDownload($attachment['download']);
260
                $file->setArchive($attachment['archive']);
261
262
                if ($attachment['id'] == \EWW\Dpf\Domain\Model\File::PRIMARY_DATASTREAM_IDENTIFIER) {
263
                    $file->setPrimaryFile(true);
264
                }
265
266
                $file->setDocument($document);
267
268
                $this->fileRepository->add($file);
269
            }
270
271
            return true;
272
273
        } else {
274
            return false;
275
        }
276
277
        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...
278
    }
279
280
    /**
281
     * Removes an existing document from the Fedora repository
282
     *
283
     * @param \EWW\Dpf\Domain\Model\Document $document
284
     * @param string $state
285
     * @return boolean
286
     */
287
    public function delete($document, $state)
288
    {
289
290
        $document->setTransferStatus(Document::TRANSFER_QUEUED);
291
        $this->documentRepository->update($document);
292
293
            switch ($state) {
294
                case "revert":
295
                    if ($this->remoteRepository->delete($document, $state)) {
296
                        $document->setTransferStatus(Document::TRANSFER_SENT);
297
                        $document->setState(Document::OBJECT_STATE_ACTIVE);
298
                        $this->documentRepository->update($document);
299
                        return true;
300
                    }
301
                    break;
302
                case "inactivate":
303
                    if ($this->remoteRepository->delete($document, $state)) {
304
                        $document->setTransferStatus(Document::TRANSFER_SENT);
305
                        $document->setState(Document::OBJECT_STATE_INACTIVE);
306
                        $this->documentRepository->update($document);
307
                        return true;
308
                    }
309
                    break;
310
                default:
311
                    // remove document from local index
312
                    $elasticsearchRepository = $this->objectManager->get(ElasticsearchRepository::class);
313
                    $elasticsearchRepository->delete($document, $state);
314
315
                    if ($this->remoteRepository->delete($document, $state)) {
316
                        $document->setTransferStatus(Document::TRANSFER_SENT);
317
                        $document->setState(Document::OBJECT_STATE_DELETED);
318
                        $this->documentRepository->update($document);
319
                        $this->documentRepository->remove($document);
320
                        return true;
321
                    }
322
                    break;
323
            }
324
325
            $document->setTransferStatus(Document::TRANSFER_ERROR);
326
            $this->documentRepository->update($document);
327
            return false;
328
    }
329
330
    public function getNextDocumentId()
331
    {
332
        $nextDocumentIdXML = $this->remoteRepository->getNextDocumentId();
333
334
        if (empty($nextDocumentIdXML)) {
335
            throw new \Exception("Couldn't get a valid document id from repository.");
336
        }
337
338
        $dom = new \DOMDocument();
339
        $dom->loadXML($nextDocumentIdXML);
340
        $xpath = new \DOMXpath($dom);
341
342
        $xpath->registerNamespace("management", "http://www.fedora.info/definitions/1/0/management/");
343
        $nextDocumentId = $xpath->query("/management:pidList/management:pid");
344
345
        return $nextDocumentId->item(0)->nodeValue;
346
    }
347
348
}
349