Passed
Pull Request — master (#5629)
by Angel Fernando Quiroz
10:06 queued 01:32
created

Cmi5Parser::generateToC()   C

Complexity

Conditions 12
Paths 4

Size

Total Lines 77
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 45
nc 4
nop 1
dl 0
loc 77
c 1
b 0
f 0
cc 12
rs 6.9666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\PluginBundle\XApi\Parser;
8
9
use Chamilo\CoreBundle\Entity\XApiCmi5Item;
10
use Chamilo\CoreBundle\Entity\XApiToolLaunch;
11
use Symfony\Component\DomCrawler\Crawler;
12
13
/**
14
 * Class Cmi5Parser.
15
 */
16
class Cmi5Parser extends PackageParser
17
{
18
    public function parse(): XApiToolLaunch
19
    {
20
        $content = file_get_contents($this->filePath);
21
        $xml = new Crawler($content);
22
23
        $courseNode = $xml->filterXPath('//courseStructure/course');
24
25
        $toolLaunch = new XApiToolLaunch();
26
        $toolLaunch
27
            ->setTitle(
28
                current(
29
                    $this->getLanguageStrings(
30
                        $courseNode->filterXPath('//title')
31
                    )
32
                )
33
            )
34
            ->setDescription(
35
                current(
36
                    $this->getLanguageStrings(
37
                        $courseNode->filterXPath('//description')
38
                    )
39
                )
40
            )
41
            ->setLaunchUrl('')
42
            ->setActivityId($courseNode->attr('id'))
43
            ->setActivityType('cmi5')
44
            ->setAllowMultipleAttempts(false)
45
            ->setCreatedAt(api_get_utc_datetime(null, false, true))
46
            ->setCourse($this->course)
47
            ->setSession($this->session)
48
        ;
49
50
        $toc = $this->generateToC($xml);
51
52
        foreach ($toc as $cmi5Item) {
53
            $toolLaunch->addItem($cmi5Item);
54
        }
55
56
        return $toolLaunch;
57
    }
58
59
    /**
60
     * @return array
61
     */
62
    private function getLanguageStrings(Crawler $node)
63
    {
64
        $map = [];
65
66
        foreach ($node->children() as $child) {
67
            $key = $child->attributes['lang']->value;
68
            $value = trim($child->textContent);
69
70
            $map[$key] = $value;
71
        }
72
73
        return $map;
74
    }
75
76
    /**
77
     * @return array<int, XApiCmi5Item>
78
     */
79
    private function generateToC(Crawler $xml): array
80
    {
81
        $blocksMap = [];
82
83
        /** @var array|XApiCmi5Item[] $items */
84
        $items = $xml
85
            ->filterXPath('//*')
86
            ->reduce(
87
                function (Crawler $node, $i) {
88
                    return \in_array($node->nodeName(), ['au', 'block']);
89
                }
90
            )
91
            ->each(
92
                function (Crawler $node, $i) use (&$blocksMap) {
93
                    $attributes = ['id', 'activityType', 'launchMethod', 'moveOn', 'masteryScore'];
94
95
                    list($id, $activityType, $launchMethod, $moveOn, $masteryMode) = $node->extract($attributes)[0];
96
97
                    $item = new XApiCmi5Item();
98
                    $item
99
                        ->setIdentifier($id)
100
                        ->setType($node->nodeName())
101
                        ->setTitle(
102
                            $this->getLanguageStrings(
103
                                $node->filterXPath('//title')
104
                            )
105
                        )
106
                        ->setDescription(
107
                            $this->getLanguageStrings(
108
                                $node->filterXPath('//description')
109
                            )
110
                        )
111
                    ;
112
113
                    if ('au' === $node->nodeName()) {
114
                        $launchParametersNode = $node->filterXPath('//launchParameters');
115
                        $entitlementKeyNode = $node->filterXPath('//entitlementKey');
116
                        $url
117
                            = $item
118
                                ->setUrl(
119
                                    $this->parseLaunchUrl(
120
                                        trim($node->filterXPath('//url')->text())
121
                                    )
122
                                )
123
                                ->setActivityType($activityType ?: null)
124
                                ->setLaunchMethod($launchMethod ?: null)
125
                                ->setMoveOn($moveOn ?: 'NotApplicable')
126
                                ->setMasteryScore((float) $masteryMode ?: null)
127
                                ->setLaunchParameters(
128
                                    $launchParametersNode->count() > 0 ? trim($launchParametersNode->text()) : null
129
                                )
130
                                ->setEntitlementKey(
131
                                    $entitlementKeyNode->count() > 0 ? trim($entitlementKeyNode->text()) : null
132
                                )
133
                        ;
134
                    }
135
136
                    $parentNode = $node->parents()->first();
137
138
                    if ('block' === $parentNode->nodeName()) {
139
                        $blocksMap[$i] = $parentNode->attr('id');
140
                    }
141
142
                    return $item;
143
                }
144
            )
145
        ;
146
147
        foreach ($blocksMap as $itemPos => $parentIdentifier) {
148
            foreach ($items as $item) {
149
                if ($parentIdentifier === $item->getIdentifier()) {
150
                    $items[$itemPos]->setParent($item);
151
                }
152
            }
153
        }
154
155
        return $items;
156
    }
157
158
    /**
159
     * @param string $url
160
     *
161
     * @return string
162
     */
163
    private function parseLaunchUrl($url)
164
    {
165
        $urlInfo = parse_url($url);
166
167
        if (empty($urlInfo['scheme'])) {
168
            $baseUrl = str_replace(
169
                api_get_path(SYS_COURSE_PATH),
0 ignored issues
show
Bug introduced by
The constant Chamilo\PluginBundle\XApi\Parser\SYS_COURSE_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
170
                api_get_path(WEB_COURSE_PATH),
171
                \dirname($this->filePath)
172
            );
173
174
            return "$baseUrl/$url";
175
        }
176
177
        return $url;
178
    }
179
}
180