Passed
Pull Request — master (#195)
by
unknown
19:02
created

AbstractImporter   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 283
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 82
c 1
b 0
f 0
dl 0
loc 283
rs 10
wmc 30

8 Methods

Rating   Name   Duplication   Size   Complexity  
A typeItems() 0 11 2
A getXsltFilePath() 0 16 3
A createDocument() 0 26 2
A __construct() 0 4 1
A import() 0 19 3
A transformToInternalXml() 0 30 4
B determineIdentifierType() 0 35 11
A determineDocumentType() 0 25 4
1
<?php
2
namespace EWW\Dpf\Services\ImportExternalMetadata;
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
\Httpful\Bootstrap::init();
18
19
use EWW\Dpf\Domain\Model\ExternalMetadata;
20
use EWW\Dpf\Services\Transformer\DocumentTransformer;
21
use EWW\Dpf\Services\ProcessNumber\ProcessNumberGenerator;
22
use EWW\Dpf\Domain\Model\Document;
23
use EWW\Dpf\Domain\Model\DocumentType;
24
use EWW\Dpf\Domain\Workflow\DocumentWorkflow;
25
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
26
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
use TYPO3\CMS\Core\Log\LogManager;
29
30
31
abstract class AbstractImporter
32
{
33
    /**
34
     * objectManager
35
     *
36
     * @var \TYPO3\CMS\Extbase\Object\ObjectManager
37
     * @inject
38
     */
39
    protected $objectManager = null;
40
41
    /**
42
     * clientRepository
43
     *
44
     * @var \EWW\Dpf\Domain\Repository\ClientRepository
45
     * @inject
46
     */
47
    protected $clientRepository = null;
48
49
    /**
50
     * documentTypeRepository
51
     *
52
     * @var \EWW\Dpf\Domain\Repository\DocumentTypeRepository
53
     * @inject
54
     */
55
    protected $documentTypeRepository = null;
56
57
    /**
58
     * clientConfigurationManager
59
     *
60
     * @var \EWW\Dpf\Configuration\ClientConfigurationManager
61
     * @inject
62
     */
63
    protected $clientConfigurationManager;
64
65
    /**
66
     * security
67
     *
68
     * @var \EWW\Dpf\Security\Security
69
     * @inject
70
     */
71
    protected $security = null;
72
73
    /**
74
     * logger
75
     *
76
     * @var \TYPO3\CMS\Core\Log\Logger
77
     */
78
    protected $logger = null;
79
80
81
    public function __construct()
82
    {
83
        /** @var $logger \TYPO3\CMS\Core\Log\Logger */
84
        $this->logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__);
85
    }
86
87
    /**
88
     * Returns the list of publication types: ( ['type','"type"'] ).
89
     * @param array $types
90
     * @return array
91
     */
92
    public static function typeItems($types)
93
    {
94
        $items = [];
95
96
        foreach ($types as $type) {
97
            $items[] = [
98
                $type, '"'.$type.'"'
99
            ];
100
        }
101
102
        return $items;
103
    }
104
105
    /**
106
     * @param ExternalMetadata $metadata
107
     * @param DocumentType $documentType
108
     * @return Document
109
     * @throws \EWW\Dpf\Exceptions\DocumentMaxSizeErrorException
110
     */
111
    public function import($metadata, $documentType = null)
112
    {
113
        $publicationType = $metadata->getPublicationType();
114
115
        if (empty($documentType)) {
116
            $documentType = $this->determineDocumentType($publicationType);
117
        }
118
119
        $xml = $this->transformToInternalXml($metadata->getData(), $documentType);
120
121
        if ($xml) {
122
            /** @var Document $document */
123
            $document = $this->createDocument($xml, $documentType);
124
            $document->setDocumentType($documentType);
0 ignored issues
show
Bug introduced by
It seems like $documentType can also be of type null; however, parameter $documentType of EWW\Dpf\Domain\Model\Document::setDocumentType() does only seem to accept EWW\Dpf\Domain\Model\DocumentType, maybe add an additional type check? ( Ignorable by Annotation )

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

124
            $document->setDocumentType(/** @scrutinizer ignore-type */ $documentType);
Loading history...
125
126
            return $document;
127
        }
128
129
        return null;
130
    }
131
132
    /**
133
     * @param string $xml
134
     * @param DocumentType $documentType
135
     * @return string|null $metadataXml
136
     */
137
    public function transformToInternalXml($xml, $documentType)
138
    {
139
        /** @var DocumentTransformer $documentTransformer */
140
        $documentTransformer = new DocumentTransformer();
141
142
        $internalXml = '';
143
144
        if ($xml && $documentType instanceof DocumentType) {
145
146
            // $ownerId is currently not needed for the purpose of importing new documents
147
            //$ownerId = $this->clientConfigurationManager->getOwnerId();
148
149
            $transformParams = [
150
                'document_type' => $documentType->getName(),
151
                // Currently not needed parameters for the purpose of importing new documents
152
                //'record_state' => $remoteState,
153
                //'owner_id' => $ownerId,
154
                //'process_number' => $processNumber,
155
            ];
156
157
            $xsltFilePath = $this->getXsltFilePath($documentType);
158
159
            if ($xsltFilePath) {
160
                $internalXml = $documentTransformer->transform($xsltFilePath, $xml, $transformParams);
161
            }
162
163
            return($internalXml);
164
        }
165
166
        return null;
167
    }
168
169
    /**
170
     * @param string $xmlData
171
     * @param DocumentType $documentType
172
     * @return Document
173
     * @throws \EWW\Dpf\Exceptions\DocumentMaxSizeErrorException
174
     */
175
    protected function createDocument($xmlData, $documentType)
176
    {
177
        /* @var $newDocument \EWW\Dpf\Domain\Model\Document */
178
        $newDocument    =  $this->objectManager->get(Document::class);
179
180
        $internalFormat = new \EWW\Dpf\Helper\InternalFormat($xmlData);
181
182
        // xml data fields are limited to 64 KB
183
        if (strlen($internalFormat->getXml()) >= 64 * 1024) {
184
            throw new \EWW\Dpf\Exceptions\DocumentMaxSizeErrorException("Maximum document size exceeded.");
185
        }
186
187
        $newDocument->setTitle($internalFormat->getTitle());
188
        $newDocument->setAuthors($internalFormat->getAuthors());
189
        $newDocument->setDocumentType($documentType);
190
191
        $newDocument->setXmlData($internalFormat->getXml());
192
        $newDocument->setCreator($this->security->getUser()->getUid());
193
194
        $newDocument->setState(DocumentWorkflow::STATE_NEW_NONE);
195
196
        $processNumberGenerator = $this->objectManager->get(ProcessNumberGenerator::class);
197
        $processNumber = $processNumberGenerator->getProcessNumber();
198
        $newDocument->setProcessNumber($processNumber);
199
200
        return $newDocument;
201
    }
202
203
    /**
204
     * @return \EWW\Dpf\Domain\Model\TransformationFile
205
     */
206
    protected abstract function getDefaultXsltTransformation();
207
208
    /**
209
     * @return string
210
     */
211
    protected abstract function getDefaultXsltFilePath();
212
213
    /**
214
     * @param DocumentType $documentType
215
     * @return string
216
     */
217
    protected function getXsltFilePath(DocumentType $documentType)
218
    {
219
        /** @var \EWW\Dpf\Domain\Model\TransformationFile $xsltTransformationFile */
220
        $xsltTransformationFile = $documentType->getCrossrefTransformation()->current();
221
222
        if (empty($xsltTransformationFile)) {
223
            $xsltTransformationFile = $this->getDefaultXsltTransformation();
224
        }
225
226
        if ($xsltTransformationFile) {
0 ignored issues
show
introduced by
$xsltTransformationFile is of type EWW\Dpf\Domain\Model\TransformationFile, thus it always evaluated to true.
Loading history...
227
            return PATH_site . 'fileadmin' . $xsltTransformationFile->getFile()->getOriginalResource()->getIdentifier();
228
        } else {
229
            return $this->getDefaultXsltFilePath();
230
        }
231
232
        return '';
0 ignored issues
show
Unused Code introduced by
return '' 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...
233
    }
234
235
    /**
236
     * @return string
237
     */
238
    protected abstract function getImporterName();
239
240
241
    /**
242
     * @param string $publicationType
243
     * @return DocumentType|null
244
     */
245
    protected function determineDocumentType($publicationType) : ?DocumentType
246
    {
247
        $documentType = null;
248
249
        // Get the target document type.
250
        if ($publicationType) {
251
            $documentType = $this->documentTypeRepository->findOneByExternalType(
252
                $publicationType, $this->getImporterName().'_types'
253
            );
254
        }
255
256
        if (!$documentType) {
257
            $configurationManager = $this->objectManager->get(ConfigurationManager::class);
258
            $settings = $configurationManager->getConfiguration(
259
                ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS
260
            );
261
262
            if (array_key_exists('defaultImportDocumentType', $settings)) {
263
                $documentType = $this->documentTypeRepository->findByUid(
264
                    $settings['defaultImportDocumentType'][$this->getImporterName()]
265
                );
266
            }
267
        }
268
        
269
        return $documentType;
270
    }
271
272
273
    /**
274
     * Determines whether the identifier is a DOI, ISBN or PMID.
275
     *
276
     * @param $identifier
277
     * @return null|string
278
     */
279
    static function determineIdentifierType($identifier)
280
    {
281
        // DOI
282
        if (strpos($identifier,'10.') === 0) {
283
            return 'DOI';
284
        }
285
286
        // ISBN
287
        $length = strlen(str_replace(['-',' '], '', $identifier));
288
289
        if ($length === 13) {
290
            if (strpos($identifier, '978') === 0 ||  strpos($identifier, '979') === 0) {
291
                return 'ISBN';
292
            }
293
        }
294
295
        if ($length === 10) {
296
            return 'ISBN';
297
        }
298
299
        $length = strlen(trim($identifier));
300
        if ($length === 9) {
301
            if (strpos($identifier, '-') === 4) {
302
                return 'ISSN';
303
            }
304
        }
305
306
        // PMID
307
        if (is_numeric($identifier) && intval($identifier) == $identifier) {
308
            if (strlen($identifier) < 10) {
309
                return 'PMID';
310
            }
311
        }
312
313
        return null;
314
    }
315
316
317
}
318