Passed
Pull Request — master (#175)
by
unknown
08:11
created

DocumentTransferManager   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 336
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 1
Metric Value
eloc 139
c 5
b 0
f 1
dl 0
loc 336
rs 10
wmc 28

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getNextDocumentId() 0 16 2
A setRemoteRepository() 0 4 1
B retrieve() 0 91 9
A update() 0 29 2
A ingest() 0 41 2
A getLastModDate() 0 9 2
A delete() 0 11 4
A overrideFilePathIfEmbargo() 0 17 6
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\Domain\Workflow\DocumentWorkflow;
19
use EWW\Dpf\Domain\Model\File;
20
21
class DocumentTransferManager
22
{
23
    const DELETE = "delete";
24
    const REVERT = "revert";
25
    const INACTIVATE = "inactivate";
26
27
    /**
28
     * documenRepository
29
     *
30
     * @var \EWW\Dpf\Domain\Repository\DocumentRepository
31
     * @inject
32
     */
33
    protected $documentRepository;
34
35
    /**
36
     * documenTypeRepository
37
     *
38
     * @var \EWW\Dpf\Domain\Repository\DocumentTypeRepository
39
     * @inject
40
     */
41
    protected $documentTypeRepository;
42
43
    /**
44
     * fileRepository
45
     *
46
     * @var \EWW\Dpf\Domain\Repository\FileRepository
47
     * @inject
48
     */
49
    protected $fileRepository;
50
51
    /**
52
     * objectManager
53
     *
54
     * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
55
     * @inject
56
     */
57
    protected $objectManager;
58
59
    /**
60
     * persistence manager
61
     *
62
     * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
63
     * @inject
64
     */
65
    protected $persistenceManager;
66
67
    /**
68
     * remoteRepository
69
     *
70
     * @var \EWW\Dpf\Services\Transfer\Repository
71
     */
72
    protected $remoteRepository;
73
74
    /**
75
     * Sets the remote repository into which the documents will be stored
76
     *
77
     * @param \EWW\Dpf\Services\Transfer\Repository $remoteRepository
78
     */
79
    public function setRemoteRepository($remoteRepository)
80
    {
81
82
        $this->remoteRepository = $remoteRepository;
83
84
    }
85
86
    /**
87
     * Stores a document into the remote repository
88
     *
89
     * @param \EWW\Dpf\Domain\Model\Document $document
90
     * @return \EWW\Dpf\Domain\Model\Document|bool
91
     */
92
    public function ingest($document)
93
    {
94
        $this->documentRepository->update($document);
95
96
        $exporter = new \EWW\Dpf\Services\MetsExporter();
97
98
        $fileData = $document->getFileData();
99
100
        $fileData = $this->overrideFilePathIfEmbargo($document, $fileData);
101
102
        $exporter->setFileData($fileData);
103
104
        $mods = new \EWW\Dpf\Helper\Mods($document->getXmlData());
105
106
        // Set current date as publication date
107
        $dateIssued = (new \DateTime)->format(\DateTime::ISO8601);
108
        $mods->setDateIssued($dateIssued);
109
110
        $exporter->setMods($mods->getModsXml());
111
112
        // Set the document creator
113
        $slub = new \EWW\Dpf\Helper\Slub($document->getSlubInfoData());
114
        $slub->setDocumentCreator($document->getCreator());
115
        $exporter->setSlubInfo($slub->getSlubXml());
116
117
        $exporter->setObjId($document->getObjectIdentifier());
118
119
        $exporter->buildMets();
120
121
        $metsXml = $exporter->getMetsData();
122
123
        $remoteDocumentId = $this->remoteRepository->ingest($document, $metsXml);
124
125
        if ($remoteDocumentId) {
126
            $document->setDateIssued($dateIssued);
127
            $document->setObjectIdentifier($remoteDocumentId);
128
            $this->documentRepository->update($document);
129
            return $document;
130
        } else {
131
            $this->documentRepository->update($document);
132
            return false;
133
        }
134
135
    }
136
137
    /**
138
     * If embargo date is set, file path must not be published
139
     *
140
     * @param $document
141
     * @param $fileData
142
     * @return mixed
143
     * @throws \Exception
144
     */
145
    public function overrideFilePathIfEmbargo($document, $fileData) {
146
        $currentDate = new \DateTime('now');
147
148
        if ($currentDate < $document->getEmbargoDate()) {
149
            foreach ($fileData as $fileSection => $files) {
150
                foreach ($files as $fileId => $fileProperties) {
151
                    foreach ($fileProperties as $key => $value) {
152
                        if ($key == 'path') {
153
                            $fileData[$fileSection][$fileId][$key] = '#';
154
                        }
155
                    }
156
                    unset($fileData[$fileSection][$fileId]);
157
                }
158
            }
159
        }
160
161
        return $fileData;
162
    }
163
164
    /**
165
     * Updates an existing document in the remote repository
166
     *
167
     * @param \EWW\Dpf\Domain\Model\Document $document
168
     * @return boolean
169
     */
170
    public function update($document)
171
    {
172
        $exporter = new \EWW\Dpf\Services\MetsExporter();
173
174
        $fileData = $document->getFileData();
175
176
        $fileData = $this->overrideFilePathIfEmbargo($document, $fileData);
177
178
        $exporter->setFileData($fileData);
179
180
        $mods = new \EWW\Dpf\Helper\Mods($document->getXmlData());
181
182
        $exporter->setMods($mods->getModsXml());
183
184
        // Set the document creator
185
        $slub = new \EWW\Dpf\Helper\Slub($document->getSlubInfoData());
186
        $slub->setDocumentCreator($document->getCreator());
187
        $exporter->setSlubInfo($slub->getSlubXml());
188
189
        $exporter->setObjId($document->getObjectIdentifier());
190
191
        $exporter->buildMets();
192
193
        $metsXml = $exporter->getMetsData();
194
195
        if ($this->remoteRepository->update($document, $metsXml)) {
196
            return true;
197
        } else {
198
            return false;
199
        }
200
201
    }
202
203
    /**
204
     * Gets an existing document from the Fedora repository
205
     *
206
     * @param string $remoteId
207
     *
208
     * @return \EWW\Dpf\Domain\Model\Document|null
209
     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
210
     */
211
    public function retrieve($remoteId)
212
    {
213
        $metsXml = $this->remoteRepository->retrieve($remoteId);
214
215
        if ($metsXml) {
216
            $mets = new \EWW\Dpf\Helper\Mets($metsXml);
217
            $mods = $mets->getMods();
218
            $slub = $mets->getSlub();
219
220
            $title   = $mods->getTitle();
221
            $authors = $mods->getAuthors();
222
223
            $documentTypeName = $slub->getDocumentType();
224
            $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

224
            /** @scrutinizer ignore-call */ 
225
            $documentType     = $this->documentTypeRepository->findOneByName($documentTypeName);
Loading history...
225
226
            if (empty($title) || empty($documentType)) {
227
                return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type EWW\Dpf\Domain\Model\Document|null.
Loading history...
228
            }
229
230
            $state = $mets->getState();
231
232
            /* @var $document \EWW\Dpf\Domain\Model\Document */
233
            $document = $this->objectManager->get(Document::class);
234
235
            switch ($state) {
236
                case "ACTIVE":
237
                    $document->setState(DocumentWorkflow::STATE_NONE_ACTIVE);
238
                    break;
239
                case "INACTIVE":
240
                    $document->setState(DocumentWorkflow::STATE_NONE_INACTIVE);
241
                    break;
242
                case "DELETED":
243
                    $document->setState(DocumentWorkflow::STATE_NONE_DELETED);
244
                    break;
245
                default:
246
                    throw new \Exception("Unknown object state: " . $state);
247
                    break;
248
            }
249
250
            $document->setRemoteLastModDate($mets->getLastModDate());
251
            $document->setObjectIdentifier($remoteId);
252
            $document->setTitle($title);
253
            $document->setAuthors($authors);
254
            $document->setDocumentType($documentType);
255
256
            $document->setXmlData($mods->getModsXml());
257
            $document->setSlubInfoData($slub->getSlubXml());
258
259
            $document->setDateIssued($mods->getDateIssued());
260
261
            $document->setProcessNumber($slub->getProcessNumber());
262
263
            $document->setCreator($slub->getDocumentCreator());
264
265
            $document->setTemporary(TRUE);
266
267
            $this->documentRepository->add($document);
268
            $this->persistenceManager->persistAll();
269
270
            foreach ($mets->getFiles() as $attachment) {
271
272
                $file = $this->objectManager->get(File::class);
273
                $file->setContentType($attachment['mimetype']);
274
                $file->setDatastreamIdentifier($attachment['id']);
275
                $file->setLink($attachment['href']);
276
                $file->setTitle($attachment['title']);
277
                $file->setLabel($attachment['title']);
278
                $file->setDownload($attachment['download']);
279
                $file->setArchive($attachment['archive']);
280
                $file->setFileGroupDeleted($attachment['deleted']);
281
282
                if ($attachment['id'] == \EWW\Dpf\Domain\Model\File::PRIMARY_DATASTREAM_IDENTIFIER) {
283
                    $file->setPrimaryFile(true);
284
                }
285
286
                $file->setDocument($document);
287
288
                $this->fileRepository->add($file);
289
                $document->addFile($file);
290
            }
291
292
            $this->documentRepository->update($document);
293
            $this->persistenceManager->persistAll();
294
295
            return $document;
296
297
        } else {
298
            return NULL;
299
        }
300
301
        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...
302
    }
303
304
    /**
305
     * Removes an existing document from the Fedora repository
306
     *
307
     * @param \EWW\Dpf\Domain\Model\Document $document
308
     * @param string $state
309
     * @return boolean
310
     */
311
    public function delete($document, $state)
312
    {
313
        if ($state == self::REVERT || $state == self::INACTIVATE) {
314
            return $this->remoteRepository->delete($document, $state);
315
        }
316
317
        if ($state == self::DELETE) {
318
            return $this->remoteRepository->delete($document, $state);
319
        }
320
321
        return false;
322
    }
323
324
    public function getNextDocumentId()
325
    {
326
        $nextDocumentIdXML = $this->remoteRepository->getNextDocumentId();
327
328
        if (empty($nextDocumentIdXML)) {
329
            throw new \Exception("Couldn't get a valid document id from repository.");
330
        }
331
332
        $dom = new \DOMDocument();
333
        $dom->loadXML($nextDocumentIdXML);
334
        $xpath = new \DOMXpath($dom);
335
336
        $xpath->registerNamespace("management", "http://www.fedora.info/definitions/1/0/management/");
337
        $nextDocumentId = $xpath->query("/management:pidList/management:pid");
338
339
        return $nextDocumentId->item(0)->nodeValue;
340
    }
341
342
    /**
343
     * Gets the last modification date of the remote document (remoteId)
344
     *
345
     * @param string $remoteId
346
     * @return string
347
     */
348
    public function getLastModDate($remoteId) {
349
        $metsXml = $this->remoteRepository->retrieve($remoteId);
350
351
        if ($metsXml) {
352
            $mets = new \EWW\Dpf\Helper\Mets($metsXml);
353
            return $mets->getLastModDate();
354
        }
355
356
        return NULL;
357
    }
358
359
}
360