Passed
Pull Request — master (#207)
by
unknown
14:14
created

DocumentTransferManager   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 286
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 23
eloc 126
dl 0
loc 286
rs 10
c 4
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A setRemoteRepository() 0 4 1
C retrieve() 0 99 10
A update() 0 17 2
A ingest() 0 23 2
A getNextDocumentId() 0 16 2
A getLastModDate() 0 10 2
A delete() 0 11 4
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;
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
     * @TYPO3\CMS\Extbase\Annotation\Inject
35
     */
36
    protected $documentRepository;
37
38
    /**
39
     * documenTypeRepository
40
     *
41
     * @var \EWW\Dpf\Domain\Repository\DocumentTypeRepository
42
     * @TYPO3\CMS\Extbase\Annotation\Inject
43
     */
44
    protected $documentTypeRepository;
45
46
    /**
47
     * fileRepository
48
     *
49
     * @var \EWW\Dpf\Domain\Repository\FileRepository
50
     * @TYPO3\CMS\Extbase\Annotation\Inject
51
     */
52
    protected $fileRepository;
53
54
    /**
55
     * objectManager
56
     *
57
     * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
58
     * @TYPO3\CMS\Extbase\Annotation\Inject
59
     */
60
    protected $objectManager;
61
62
    /**
63
     * persistence manager
64
     *
65
     * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
66
     * @TYPO3\CMS\Extbase\Annotation\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
        $document->setXmlData($internalFormat->getXml());
104
105
        $XSLTransformator = new XSLTransformator();
106
        $transformedXml = $XSLTransformator->getTransformedOutputXML($document);
107
108
        $remoteDocumentId = $this->remoteRepository->ingest($document, $transformedXml);
109
110
        if ($remoteDocumentId) {
111
            $document->setDateIssued($dateIssued);
112
            $document->setObjectIdentifier($remoteDocumentId);
113
            $this->documentRepository->update($document);
114
            return $document;
115
        } else {
116
            $this->documentRepository->update($document);
117
            return false;
118
        }
119
    }
120
121
    /**
122
     * Updates an existing document in the remote repository
123
     *
124
     * @param \EWW\Dpf\Domain\Model\Document $document
125
     * @return boolean
126
     */
127
    public function update($document)
128
    {
129
        $internalFormat = new \EWW\Dpf\Helper\InternalFormat($document->getXmlData());
130
        $internalFormat->setCreator($document->getCreator());
131
        $internalFormat->setCreationDate($document->getCreationDate());
132
        $document->setXmlData($internalFormat->getXml());
133
134
        $XSLTransformator = new XSLTransformator();
135
        $transformedXml = $XSLTransformator->getTransformedOutputXML($document);
136
137
        if ($this->remoteRepository->update($document, $transformedXml)) {
138
            $document->setTransferStatus(Document::TRANSFER_SENT);
139
            $this->documentRepository->update($document);
140
            $this->documentRepository->remove($document);
141
            return true;
142
        } else {
143
            return false;
144
        }
145
    }
146
147
    /**
148
     * Gets an existing document from the Fedora repository
149
     *
150
     * @param string $remoteId
151
     *
152
     * @return \EWW\Dpf\Domain\Model\Document|null
153
     * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
154
     */
155
    public function retrieve($remoteId)
156
    {
157
        $remoteXml = $this->remoteRepository->retrieve($remoteId);
158
159
        if ($remoteXml) {
160
161
            $XSLTransformator = new XSLTransformator();
162
            $inputTransformedXML = $XSLTransformator->transformInputXML($remoteXml);
163
164
            $internalFormat = new \EWW\Dpf\Helper\InternalFormat($inputTransformedXML);
165
166
            $title = $internalFormat->getTitle();
167
            $authors = $internalFormat->getPersons();
168
169
            $documentTypeName = $internalFormat->getDocumentType();
170
            $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

170
            /** @scrutinizer ignore-call */ 
171
            $documentType     = $this->documentTypeRepository->findOneByName($documentTypeName);
Loading history...
171
172
            if (empty($title) || empty($documentType)) {
173
                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...
174
            }
175
176
            $state = $internalFormat->getRepositoryState();
177
178
            /* @var $document \EWW\Dpf\Domain\Model\Document */
179
            $document = $this->objectManager->get(Document::class);
180
181
            switch ($state) {
182
                case "ACTIVE":
183
                    $document->setState(DocumentWorkflow::STATE_NONE_ACTIVE);
184
                    break;
185
                case "INACTIVE":
186
                    $document->setState(DocumentWorkflow::STATE_NONE_INACTIVE);
187
                    break;
188
                case "DELETED":
189
                    $document->setState(DocumentWorkflow::STATE_NONE_DELETED);
190
                    break;
191
                default:
192
                    throw new \Exception("Unknown object state: " . $state);
193
                    break;
194
            }
195
196
            $document->setRemoteLastModDate($internalFormat->getRepositoryLastModDate());
197
            $document->setObjectIdentifier($remoteId);
198
            $document->setTitle($title);
199
            $document->setAuthors($authors);
200
            $document->setDocumentType($documentType);
201
202
            $document->setXmlData($inputTransformedXML);
203
204
            $document->setDateIssued($internalFormat->getDateIssued());
205
206
            $document->setProcessNumber($internalFormat->getProcessNumber());
207
208
            $creationDate = $internalFormat->getCreationDate();
209
            if (empty($creationDate)) {
210
                $creationDate = $internalFormat->getRepositoryCreationDate();
211
            }
212
            $document->setCreationDate($creationDate);
213
            $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

213
            $document->setCreator(/** @scrutinizer ignore-type */ $internalFormat->getCreator());
Loading history...
214
215
            $document->setTemporary(TRUE);
216
217
            $this->documentRepository->add($document);
218
            $this->persistenceManager->persistAll();
219
220
            foreach ($internalFormat->getFiles() as $attachment) {
221
222
                /** @var File $file */
223
                $file = $this->objectManager->get(File::class);
224
                $file->setContentType($attachment['mimetype']);
225
                $file->setDatastreamIdentifier($attachment['id']);
226
                $file->setFileIdentifier($attachment['id']);
227
                $file->setLink($attachment['href']);
228
                $file->setTitle($attachment['title']);
229
                $file->setLabel($attachment['title']);
230
                $file->setDownload($attachment['download']);
231
                $file->setArchive($attachment['archive']);
232
                $file->setFileGroupDeleted($attachment['deleted']);
233
234
                if ($attachment['id'] == \EWW\Dpf\Domain\Model\File::PRIMARY_DATASTREAM_IDENTIFIER) {
235
                    $file->setPrimaryFile(true);
236
                }
237
238
                $file->setDocument($document);
239
240
                $this->fileRepository->add($file);
241
                $document->addFile($file);
242
            }
243
244
            $this->documentRepository->update($document);
245
            $this->persistenceManager->persistAll();
246
247
            return $document;
248
249
        } else {
250
            return NULL;
251
        }
252
253
        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...
254
    }
255
256
    /**
257
     * Removes an existing document from the Fedora repository
258
     *
259
     * @param \EWW\Dpf\Domain\Model\Document $document
260
     * @param string $state
261
     * @return boolean
262
     */
263
    public function delete($document, $state)
264
    {
265
        if ($state == self::REVERT || $state == self::INACTIVATE) {
266
            return $this->remoteRepository->delete($document, $state);
267
        }
268
269
        if ($state == self::DELETE) {
270
            return $this->remoteRepository->delete($document, $state);
271
        }
272
273
        return false;
274
    }
275
276
    public function getNextDocumentId()
277
    {
278
        $nextDocumentIdXML = $this->remoteRepository->getNextDocumentId();
279
280
        if (empty($nextDocumentIdXML)) {
281
            throw new \Exception("Couldn't get a valid document id from repository.");
282
        }
283
284
        $dom = new \DOMDocument();
285
        $dom->loadXML($nextDocumentIdXML);
286
        $xpath = new \DOMXpath($dom);
287
288
        $xpath->registerNamespace("management", "http://www.fedora.info/definitions/1/0/management/");
289
        $nextDocumentId = $xpath->query("/management:pidList/management:pid");
290
291
        return $nextDocumentId->item(0)->nodeValue;
292
    }
293
294
    /**
295
     * Gets the last modification date of the remote document (remoteId)
296
     *
297
     * @param string $remoteId
298
     * @return string
299
     */
300
    public function getLastModDate($remoteId) {
301
        $remoteXml = $this->remoteRepository->retrieve($remoteId);
302
        if ($remoteXml) {
303
            $XSLTransformator = new XSLTransformator();
304
            $inputTransformedXML = $XSLTransformator->transformInputXML($remoteXml);
305
            $internalFormat = new \EWW\Dpf\Helper\InternalFormat($inputTransformedXML);
306
            return $internalFormat->getRepositoryLastModDate();
307
        }
308
309
        return '';
310
    }
311
}
312