Passed
Pull Request — master (#195)
by
unknown
09:41 queued 02:26
created

overrideFilePathIfEmbargo()   A

Complexity

Conditions 6
Paths 2

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 9
nc 2
nop 2
dl 0
loc 17
rs 9.2222
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\Domain\Workflow\DocumentWorkflow;
19
use EWW\Dpf\Domain\Model\LocalDocumentStatus;
0 ignored issues
show
Bug introduced by
The type EWW\Dpf\Domain\Model\LocalDocumentStatus was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use EWW\Dpf\Domain\Model\RemoteDocumentStatus;
0 ignored issues
show
Bug introduced by
The type EWW\Dpf\Domain\Model\RemoteDocumentStatus was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use EWW\Dpf\Helper\XSLTransformator;
0 ignored issues
show
Bug introduced by
The type EWW\Dpf\Helper\XSLTransformator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use EWW\Dpf\Domain\Model\File;
23
24
class DocumentTransferManager
25
{
26
    const DELETE = "delete";
27
    const REVERT = "revert";
28
    const INACTIVATE = "inactivate";
29
30
    /**
31
     * documenRepository
32
     *
33
     * @var \EWW\Dpf\Domain\Repository\DocumentRepository
34
     * @inject
35
     */
36
    protected $documentRepository;
37
38
    /**
39
     * documenTypeRepository
40
     *
41
     * @var \EWW\Dpf\Domain\Repository\DocumentTypeRepository
42
     * @inject
43
     */
44
    protected $documentTypeRepository;
45
46
    /**
47
     * fileRepository
48
     *
49
     * @var \EWW\Dpf\Domain\Repository\FileRepository
50
     * @inject
51
     */
52
    protected $fileRepository;
53
54
    /**
55
     * objectManager
56
     *
57
     * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
58
     * @inject
59
     */
60
    protected $objectManager;
61
62
    /**
63
     * persistence manager
64
     *
65
     * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
66
     * @inject
67
     */
68
    protected $persistenceManager;
69
70
    /**
71
     * remoteRepository
72
     *
73
     * @var \EWW\Dpf\Services\Transfer\Repository
74
     */
75
    protected $remoteRepository;
76
77
    /**
78
     * Sets the remote repository into which the documents will be stored
79
     *
80
     * @param \EWW\Dpf\Services\Transfer\Repository $remoteRepository
81
     */
82
    public function setRemoteRepository($remoteRepository)
83
    {
84
85
        $this->remoteRepository = $remoteRepository;
86
87
    }
88
89
    /**
90
     * Stores a document into the remote repository
91
     *
92
     * @param \EWW\Dpf\Domain\Model\Document $document
93
     * @return \EWW\Dpf\Domain\Model\Document|bool
94
     */
95
    public function ingest($document)
96
    {
97
        $internalFormat = new \EWW\Dpf\Helper\InternalFormat($document->getXmlData());
98
        // Set current date as publication date
99
        $dateIssued = (new \DateTime)->format(\DateTime::ISO8601);
100
        $internalFormat->setDateIssued($dateIssued);
101
        $internalFormat->setCreator($document->getCreator());
102
        $internalFormat->setCreationDate($document->getCreationDate());
103
104
        $exporter = new \EWW\Dpf\Services\ParserGenerator();
105
        $exporter->setXML($internalFormat->getXml());
106
        $fileData = $document->getFileData();
107
        $fileData = $this->overrideFilePathIfEmbargo($document, $fileData);
108
        $exporter->setFileData($fileData);
0 ignored issues
show
Bug introduced by
$fileData of type array is incompatible with the type string expected by parameter $value of EWW\Dpf\Services\ParserGenerator::setFileData(). ( Ignorable by Annotation )

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

108
        $exporter->setFileData(/** @scrutinizer ignore-type */ $fileData);
Loading history...
109
        $document->setXmlData($exporter->getXMLData());
110
111
        $XSLTransformator = new XSLTransformator();
112
        $transformedXml = $XSLTransformator->getTransformedOutputXML($document);
113
114
        $remoteDocumentId = $this->remoteRepository->ingest($document, $transformedXml);
115
116
        if ($remoteDocumentId) {
117
            $document->setDateIssued($dateIssued);
118
            $document->setObjectIdentifier($remoteDocumentId);
119
            $this->documentRepository->update($document);
120
            return $document;
121
        } else {
122
            $this->documentRepository->update($document);
123
            return false;
124
        }
125
    }
126
127
    /**
128
     * If embargo date is set, file path must not be published
129
     *
130
     * @param $document
131
     * @param $fileData
132
     * @return mixed
133
     * @throws \Exception
134
     */
135
    public function overrideFilePathIfEmbargo($document, $fileData) {
136
        $currentDate = new \DateTime('now');
137
138
        if ($currentDate < $document->getEmbargoDate()) {
139
            foreach ($fileData as $fileSection => $files) {
140
                foreach ($files as $fileId => $fileProperties) {
141
                    foreach ($fileProperties as $key => $value) {
142
                        if ($key == 'path') {
143
                            $fileData[$fileSection][$fileId][$key] = '#';
144
                        }
145
                    }
146
                    unset($fileData[$fileSection][$fileId]);
147
                }
148
            }
149
        }
150
151
        return $fileData;
152
    }
153
154
    /**
155
     * Updates an existing document in the remote repository
156
     *
157
     * @param \EWW\Dpf\Domain\Model\Document $document
158
     * @return boolean
159
     */
160
    public function update($document)
161
    {
162
        $internalFormat = new \EWW\Dpf\Helper\InternalFormat($document->getXmlData());
163
        $internalFormat->setCreator($document->getCreator());
164
        $internalFormat->setCreationDate($document->getCreationDate());
165
166
        $exporter = new \EWW\Dpf\Services\ParserGenerator();
167
        $exporter->setXML($internalFormat->getXml());
168
        $fileData = $document->getFileData();
169
        $fileData = $this->overrideFilePathIfEmbargo($document, $fileData);
170
        $exporter->setFileData($fileData);
0 ignored issues
show
Bug introduced by
$fileData of type array is incompatible with the type string expected by parameter $value of EWW\Dpf\Services\ParserGenerator::setFileData(). ( Ignorable by Annotation )

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

170
        $exporter->setFileData(/** @scrutinizer ignore-type */ $fileData);
Loading history...
171
        $document->setXmlData($exporter->getXMLData());
172
173
        $transformedXml = $exporter->getTransformedOutputXML($document);
174
175
        if ($this->remoteRepository->update($document, $transformedXml)) {
176
            $document->setTransferStatus(Document::TRANSFER_SENT);
177
            $this->documentRepository->update($document);
178
            $this->documentRepository->remove($document);
179
            return true;
180
        } else {
181
            return false;
182
        }
183
184
    }
185
186
    /**
187
     * Gets an existing document from the Fedora repository
188
     *
189
     * @param string $remoteId
190
     *
191
     * @return \EWW\Dpf\Domain\Model\Document|null
192
     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
193
     */
194
    public function retrieve($remoteId)
195
    {
196
        $remoteXml = $this->remoteRepository->retrieve($remoteId);
197
        
198
        if ($remoteXml) {
199
200
            $XSLTransformator = new XSLTransformator();
201
            $inputTransformedXML = $XSLTransformator->transformInputXML($remoteXml);
202
203
            $internalFormat = new \EWW\Dpf\Helper\InternalFormat($inputTransformedXML);
204
205
            $title = $internalFormat->getTitle();
206
            $authors = $internalFormat->getPersons();
207
208
            $documentTypeName = $internalFormat->getDocumentType();
209
            $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

209
            /** @scrutinizer ignore-call */ 
210
            $documentType     = $this->documentTypeRepository->findOneByName($documentTypeName);
Loading history...
210
211
            if (empty($title) || empty($documentType)) {
212
                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...
213
            }
214
215
            $state = $internalFormat->getRepositoryState();
216
217
            /* @var $document \EWW\Dpf\Domain\Model\Document */
218
            $document = $this->objectManager->get(Document::class);
219
220
            switch ($state) {
221
                case "ACTIVE":
222
                    $document->setState(DocumentWorkflow::STATE_NONE_ACTIVE);
223
                    break;
224
                case "INACTIVE":
225
                    $document->setState(DocumentWorkflow::STATE_NONE_INACTIVE);
226
                    break;
227
                case "DELETED":
228
                    $document->setState(DocumentWorkflow::STATE_NONE_DELETED);
229
                    break;
230
                default:
231
                    throw new \Exception("Unknown object state: " . $state);
232
                    break;
233
            }
234
235
            $document->setRemoteLastModDate($internalFormat->getRepositoryLastModDate());
236
            $document->setObjectIdentifier($remoteId);
237
            $document->setTitle($title);
238
            $document->setAuthors($authors);
239
            $document->setDocumentType($documentType);
240
241
            $document->setXmlData($inputTransformedXML);
242
243
            $document->setDateIssued($internalFormat->getDateIssued());
244
245
            $document->setProcessNumber($internalFormat->getProcessNumber());
246
247
            $creationDate = $internalFormat->getCreationDate();
248
            if (empty($creationDate)) {
249
                $creationDate = $internalFormat->getRepositoryCreationDate();
250
            }
251
            $document->setCreationDate($creationDate);
252
            $document->setCreator($internalFormat->getCreator());
0 ignored issues
show
Bug introduced by
$internalFormat->getCreator() of type string is incompatible with the type integer expected by parameter $creator of EWW\Dpf\Domain\Model\Document::setCreator(). ( Ignorable by Annotation )

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

252
            $document->setCreator(/** @scrutinizer ignore-type */ $internalFormat->getCreator());
Loading history...
253
254
            $document->setTemporary(TRUE);
255
256
            $this->documentRepository->add($document);
257
            $this->persistenceManager->persistAll();
258
259
            foreach ($internalFormat->getFiles() as $attachment) {
260
261
                $file = $this->objectManager->get(File::class);
262
                $file->setContentType($attachment['mimetype']);
263
                $file->setDatastreamIdentifier($attachment['id']);
264
                $file->setLink($attachment['href']);
265
                $file->setTitle($attachment['title']);
266
                $file->setLabel($attachment['title']);
267
                $file->setDownload($attachment['download']);
268
                $file->setArchive($attachment['archive']);
269
                $file->setFileGroupDeleted($attachment['deleted']);
270
271
                if ($attachment['id'] == \EWW\Dpf\Domain\Model\File::PRIMARY_DATASTREAM_IDENTIFIER) {
272
                    $file->setPrimaryFile(true);
273
                }
274
275
                $file->setDocument($document);
276
277
                $this->fileRepository->add($file);
278
                $document->addFile($file);
279
            }
280
281
            $this->documentRepository->update($document);
282
            $this->persistenceManager->persistAll();
283
284
            return $document;
285
286
        } else {
287
            return NULL;
288
        }
289
290
        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...
291
    }
292
293
    /**
294
     * Removes an existing document from the Fedora repository
295
     *
296
     * @param \EWW\Dpf\Domain\Model\Document $document
297
     * @param string $state
298
     * @return boolean
299
     */
300
    public function delete($document, $state)
301
    {
302
        if ($state == self::REVERT || $state == self::INACTIVATE) {
303
            return $this->remoteRepository->delete($document, $state);
304
        }
305
306
        if ($state == self::DELETE) {
307
            return $this->remoteRepository->delete($document, $state);
308
        }
309
310
        return false;
311
    }
312
313
    public function getNextDocumentId()
314
    {
315
        $nextDocumentIdXML = $this->remoteRepository->getNextDocumentId();
316
317
        if (empty($nextDocumentIdXML)) {
318
            throw new \Exception("Couldn't get a valid document id from repository.");
319
        }
320
321
        $dom = new \DOMDocument();
322
        $dom->loadXML($nextDocumentIdXML);
323
        $xpath = new \DOMXpath($dom);
324
325
        $xpath->registerNamespace("management", "http://www.fedora.info/definitions/1/0/management/");
326
        $nextDocumentId = $xpath->query("/management:pidList/management:pid");
327
328
        return $nextDocumentId->item(0)->nodeValue;
329
    }
330
331
    /**
332
     * Gets the last modification date of the remote document (remoteId)
333
     *
334
     * @param string $remoteId
335
     * @return string
336
     */
337
    public function getLastModDate($remoteId) {
338
        $remoteXml = $this->remoteRepository->retrieve($remoteId);
339
        if ($remoteXml) {
340
            $XSLTransformator = new XSLTransformator();
341
            $inputTransformedXML = $XSLTransformator->transformInputXML($remoteXml);
342
            $internalFormat = new \EWW\Dpf\Helper\InternalFormat($inputTransformedXML);
343
            return $internalFormat->getRepositoryLastModDate();
344
        }
345
346
        return '';
347
    }
348
}
349