PassageDataParser   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 17
dl 0
loc 166
rs 10
c 0
b 0
f 0
ccs 63
cts 63
cp 1

6 Methods

Rating   Name   Duplication   Size   Complexity  
B startElement() 0 53 8
A __construct() 0 4 1
A setParserContext() 0 3 1
A endElement() 0 7 1
B getTwineId() 0 20 5
A createTextnode() 0 15 1
1
<?php
2
/* Copyright (C) 2017 Michael Giesler
3
 *
4
 * This file is part of Dembelo.
5
 *
6
 * Dembelo is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * Dembelo is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Affero General Public License 3 for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public License 3
17
 * along with Dembelo. If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
namespace AdminBundle\Service\TwineImport;
21
22
use DembeloMain\Document\Textnode;
23
use DembeloMain\Model\Repository\TextNodeRepositoryInterface;
24
use Doctrine\ODM\MongoDB\DocumentManager;
25
26
/**
27
 * Class PassageDataParser
28
 */
29
class PassageDataParser
30
{
31
    /**
32
     * @var ParserContext
33
     */
34
    private $parserContext;
35
36
    /**
37
     * @var TextNodeRepositoryInterface
38
     */
39
    private $textnodeRepository;
40
41
    /**
42
     * @var string
43
     */
44
    private $twineTextnodeName;
45
46
    /**
47
     * @var DocumentManager
48
     */
49
    private $documentManager;
50
51
    /**
52
     * PassageDataParser constructor.
53
     * @param TextNodeRepositoryInterface $textNodeRepository
54
     * @param DocumentManager             $documentManager
55
     */
56 10
    public function __construct(TextNodeRepositoryInterface $textNodeRepository, DocumentManager $documentManager)
57
    {
58 10
        $this->textnodeRepository = $textNodeRepository;
59 10
        $this->documentManager = $documentManager;
60 10
    }
61
62
    /**
63
     * @param ParserContext $parserContext
64
     *
65
     * @return void
66
     */
67 10
    public function setParserContext(ParserContext $parserContext): void
68
    {
69 10
        $this->parserContext = $parserContext;
70 10
    }
71
72
    /**
73
     * @param string $name
74
     * @param array  $attrs
75
     *
76
     * @throws \Exception
77
     */
78 9
    public function startElement(string $name, array $attrs): void
79
    {
80 9
        if ($this->parserContext->isTwineText()) {
81 1
            throw new \Exception(sprintf("Nested '%s' found in Twine archive file '%s'.", $name, $this->parserContext->getFilename()));
82
        }
83
84 8
        if (isset($attrs['pid']) !== true) {
85 1
            throw new \Exception(sprintf("There is a '%s' in the Twine archive file '%s' which is missing its 'pid' attribute.", $name, $this->parserContext->getFilename()));
86
        }
87
88 7
        if (is_numeric($attrs['pid']) !== true) {
89 1
            throw new \Exception(sprintf("There is a '%s' in the Twine archive file '%s' which hasn't a numeric value in its 'pid' attribute ('%s' was found instead).", $name, $this->parserContext->getFilename(), $attrs['pid']));
90
        }
91
92 6
        $twineId = $this->getTwineId($attrs['tags'], $attrs['name']);
93
94 4
        if (array_key_exists($twineId, $this->parserContext->getTextnodeMapping()) === true) {
95 1
            throw new \Exception(sprintf("There is a '%s' in the Twine archive file '%s' which has a non unique 'id' tag [%s], in node '%s'", $name, $this->parserContext->getFilename(), $twineId, $attrs['name']));
96
        }
97
98 3
        $textnode = $this->textnodeRepository->findByTwineId($this->parserContext->getImportfile(), $twineId);
99
100 3
        if (null === $textnode) {
101 1
            $textnode = $this->createTextnode($twineId);
102
        } else {
103 2
            $textnode->setText('');
104
            // @todo clear hitches
105
        }
106
107 3
        $this->twineTextnodeName = $attrs['name'];
108
109 3
        $textnode->setMetadata(
110
            [
111 3
                'Titel' => $this->twineTextnodeName,
112 3
                'Autor' => $this->parserContext->getImportfile()->getAuthor(),
113 3
                'Verlag' => $this->parserContext->getImportfile()->getPublisher(),
114
            ]
115
        );
116
117 3
        if ((int) $attrs['pid'] === $this->parserContext->getTwineStartnodeId()) {
118 1
            if (!$this->parserContext->isAccessSet()) {
119 1
                $textnode->setAccess(true);
120 1
                $this->parserContext->setAccessSet(true);
121
            } else {
122 1
                throw new \Exception(sprintf('There is more than one \'%s\' in the Twine archive file \'%s\' with the startnode value \'%s\' in its \'pid\' attribute.', $name, $this->parserContext->getFilename(), $attrs['pid']));
123
            }
124
        } else {
125 2
            $textnode->setAccess(false);
126
        }
127
128 3
        $this->parserContext->setCurrentTextnode($textnode);
129
130 3
        $this->parserContext->setTwineText(true);
131 3
    }
132
133
    /**
134
     * @return void
135
     */
136 1
    public function endElement(): void
137
    {
138 1
        $nodenameMapping = $this->parserContext->getNodenameMapping();
139 1
        $nodenameMapping[$this->twineTextnodeName] = $this->parserContext->getCurrentTextnode();
140 1
        $this->parserContext->setNodenameMapping($nodenameMapping);
141
142 1
        $this->parserContext->setTwineText(false);
143 1
    }
144
145
    /**
146
     * @param string $twineId
147
     *
148
     * @return Textnode
149
     */
150 1
    private function createTextnode(string $twineId): Textnode
151
    {
152 1
        $textnode = new Textnode();
153 1
        $textnode->setCreated(date('Y-m-d H:i:s'));
154 1
        $textnode->setTopicId($this->parserContext->getImportfile()->getTopicId());
155 1
        $textnode->setLicenseeId($this->parserContext->getImportfile()->getLicenseeId());
156 1
        $textnode->setImportfileId($this->parserContext->getImportfile()->getId());
157 1
        $textnode->setStatus(Textnode::STATUS_ACTIVE);
158 1
        $textnode->setTwineId($twineId);
159
160 1
        $this->textnodeRepository->decorateArbitraryId($textnode);
161
162 1
        $this->documentManager->persist($textnode);
163
164 1
        return $textnode;
165
    }
166
167
    /**
168
     * @param string $tagString
169
     * @param string $textnodeTitle
170
     *
171
     * @return string
172
     *
173
     * @throws \Exception
174
     */
175 6
    private function getTwineId(string $tagString, string $textnodeTitle): string
176
    {
177 6
        if (empty($tagString)) {
178 1
            throw new \Exception(sprintf('no ID given for Textnode "%s"', $textnodeTitle));
179
        }
180 5
        $tagArray = explode(' ', $tagString);
181
182 5
        $twineId = false;
183
184 5
        foreach ($tagArray as $tag) {
185 5
            if (0 === strpos($tag, 'ID:')) {
186 5
                $twineId = substr($tag, 3);
187
            }
188
        }
189
190 5
        if (false === $twineId) {
191 1
            throw new \Exception(sprintf('no ID given for Textnode "%s"', $textnodeTitle));
192
        }
193
194 4
        return $twineId;
195
    }
196
}
197