Completed
Push — master ( 598fe1...4a905b )
by Michael
03:41
created

Creator::createEveApi()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 56
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 56
ccs 0
cts 54
cp 0
rs 7.7489
cc 7
eloc 46
nc 8
nop 3
crap 56

How to fix   Long Method   

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
declare(strict_types = 1);
3
/**
4
 * Contains Creator class.
5
 *
6
 * PHP version 7.0+
7
 *
8
 * LICENSE:
9
 * This file is part of Yet Another Php Eve Api Library also know as Yapeal
10
 * which can be used to access the Eve Online API data and place it into a
11
 * database.
12
 * Copyright (C) 2015-2016 Michael Cummings
13
 *
14
 * This program is free software: you can redistribute it and/or modify it
15
 * under the terms of the GNU Lesser General Public License as published by the
16
 * Free Software Foundation, either version 3 of the License, or (at your
17
 * option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful, but WITHOUT
20
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
22
 * for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public License
25
 * along with this program. If not, see
26
 * <http://spdx.org/licenses/LGPL-3.0.html>.
27
 *
28
 * You should be able to find a copy of this license in the COPYING-LESSER.md
29
 * file. A copy of the GNU GPL should also be available in the COPYING.md file.
30
 *
31
 * @copyright 2015-2016 Michael Cummings
32
 * @license   http://www.gnu.org/copyleft/lesser.html GNU LGPL
33
 * @author    Michael Cummings <[email protected]>
34
 */
35
namespace Yapeal\EveApi;
36
37
use Yapeal\Console\Command\EveApiCreatorTrait;
38
use Yapeal\Event\EveApiEventInterface;
39
use Yapeal\Event\MediatorInterface;
40
use Yapeal\FileSystem\RelativeFileSearchTrait;
41
use Yapeal\Log\Logger;
42
43
/**
44
 * Class Creator
45
 */
46
class Creator
47
{
48
    use EveApiCreatorTrait, RelativeFileSearchTrait;
49
    /**
50
     * Creator constructor.
51
     *
52
     * @param \Twig_Environment $twig
53
     * @param string            $dir
54
     */
55
    public function __construct(\Twig_Environment $twig, string $dir = __DIR__)
56
    {
57
        $this->setRelativeBaseDir($dir);
58
        $this->setTwig($twig);
59
    }
60
    /**
61
     * @param EveApiEventInterface $event
62
     * @param string               $eventName
63
     * @param MediatorInterface    $yem
64
     *
65
     * @return EveApiEventInterface
66
     * @throws \DomainException
67
     * @throws \InvalidArgumentException
68
     * @throws \LogicException
69
     */
70
    public function createEveApi(
71
        EveApiEventInterface $event,
72
        string $eventName,
73
        MediatorInterface $yem
74
    ): EveApiEventInterface
75
    {
76
        $this->setYem($yem);
77
        $data = $event->getData();
78
        $yem->triggerLogEvent('Yapeal.Log.log',
79
            Logger::DEBUG,
80
            $this->getReceivedEventMessage($data, $eventName, __CLASS__));
81
        // Only work with raw unaltered XML data.
82
        if (false !== strpos($data->getEveApiXml(), '<?yapeal.parameters.json')) {
83
            return $event->setHandledSufficiently();
84
        }
85
        $this->sectionName = $data->getEveApiSectionName();
86
        $this->apiName = $data->getEveApiName();
87
        $outputFile = sprintf('%1$s%2$s/%3$s.php',
88
            $this->getRelativeBaseDir(),
89
            ucfirst($this->sectionName),
90
            ucfirst($this->apiName));
91
        // Nothing to do if NOT overwriting and file exists.
92
        if (false === $this->isOverwrite() && is_file($outputFile)) {
93
            return $event;
94
        }
95
        $sxi = new \SimpleXMLIterator($data->getEveApiXml());
96
        $this->tables = [];
97
        $this->processValueOnly($sxi, $this->apiName);
98
        $this->processRowset($sxi, $this->apiName);
99
        $tCount = count($this->tables);
100
        if (0 === $tCount) {
101
            $mess = 'No SQL tables to create for';
102
            $yem->triggerLogEvent('Yapeal.Log.log', Logger::NOTICE, $this->createEveApiMessage($mess, $data));
103
        }
104
        ksort($this->tables);
105
        $context = [
106
            'className' => ucfirst($this->apiName),
107
            'tables' => $this->tables,
108
            'hasOwner' => $this->hasOwner(),
109
            'mask' => $data->getEveApiArgument('mask'),
110
            'namespace' => $this->getNamespace(),
111
            'sectionName' => $this->sectionName,
112
            'tableNames' => array_keys($this->tables)
113
        ];
114
        $contents = $this->getContentsFromTwig($eventName, $data, $context);
115
        if (false === $contents) {
116
            return $event;
117
        }
118
        if (false === $this->safeFileWrite($contents, $outputFile)) {
119
            $yem->triggerLogEvent($eventName,
120
                Logger::WARNING,
121
                $this->getFailedToWriteFileMessage($data, $eventName, $outputFile));
122
            return $event;
123
        }
124
        return $event->setHandledSufficiently();
125
    }
126
    /**
127
     * @param \SimpleXMLIterator $sxi
128
     * @param string             $apiName
129
     * @param string             $xPath
130
     */
131
    protected function processRowset(\SimpleXMLIterator $sxi, $apiName, $xPath = '//result/rowset')
132
    {
133
        $items = $sxi->xpath($xPath);
134
        if (0 === count($items)) {
135
            return;
136
        }
137
        foreach ($items as $ele) {
138
            $rsName = ucfirst((string)$ele['name']);
139
            $colNames = explode(',', (string)$ele['columns']);
140
            $keyNames = explode(',', (string)$ele['key']);
141
            $attributes = [];
142
            foreach ($keyNames as $keyName) {
143
                $attributes[$keyName] = $this->inferDefaultFromName($keyName);
144
            }
145
            foreach ($colNames as $colName) {
146
                $attributes[$colName] = $this->inferDefaultFromName($colName);
147
            }
148
            if ($this->hasOwner()) {
149
                $attributes['ownerID'] = '$ownerID';
150
            }
151
            uksort($attributes,
152
                function ($alpha, $beta) {
153
                    return strtolower($alpha) <=> strtolower($beta);
154
                });
155
            if (0 === count($this->tables)) {
156
                $this->tables[$apiName] = ['attributes' => $attributes, 'xpath' => $rsName];
157
            } else {
158
                $this->tables[$rsName] = ['attributes' => $attributes, 'xpath' => $rsName];
159
            }
160
        }
161
    }
162
    /**
163
     * @param \SimpleXMLIterator $sxi
164
     * @param string             $tableName
165
     * @param string             $xpath
166
     */
167
    protected function processValueOnly(
168
        \SimpleXMLIterator $sxi,
169
        string $tableName,
170
        string $xpath = '//result/child::*[not(*|@*|self::dataTime)]'
171
    ) {
172
        $items = $sxi->xpath($xpath);
173
        if (0 === count($items)) {
174
            return;
175
        }
176
        $values = [];
177
        /**
178
         * @var \SimpleXMLElement $ele
179
         */
180
        foreach ($items as $ele) {
181
            $name = (string)$ele->getName();
182
            $values[$name] = $this->inferDefaultFromName($name);
183
        }
184
        if ($this->hasOwner()) {
185
            $values['ownerID'] = '$ownerID';
186
        }
187
        uksort($values,
188
            function ($alpha, $beta) {
189
                return strtolower($alpha) <=> strtolower($beta);
190
            });
191
        $this->tables[$tableName] = ['values' => $values];
192
    }
193
    /**
194
     * @var string $twigExtension
195
     */
196
    protected $twigExtension = 'php.twig';
197
    /**
198
     * @return string
199
     */
200
    private function getNamespace(): string
201
    {
202
        return 'Yapeal\EveApi\\' . ucfirst($this->sectionName);
203
    }
204
    /**
205
     * Used to determine if API is in section that has an owner.
206
     *
207
     * @return bool
208
     */
209
    private function hasOwner(): bool
210
    {
211
        return in_array(strtolower($this->sectionName), ['account', 'char', 'corp'], true);
212
    }
213
    /**
214
     * Used to infer(choose) default value from element or attribute's name.
215
     *
216
     * @param string $name Name of the element or attribute.
217
     *
218
     * @return string Returns the inferred value from the name.
219
     */
220
    private function inferDefaultFromName(string $name): string
221
    {
222
        $name = strtolower($name);
223
        $column = 'null';
224
        foreach ([
225
                     'descr' => '\'\'',
226
                     'name' => '\'\'',
227
                     'balance' => '\'0.0\'',
228
                     'isk' => '\'0.0\'',
229
                     'tax' => '\'0.0\'',
230
                     'timeefficiency' => 'null',
231
                     'date' => '\'1970-01-01 00:00:01\'',
232
                     'time' => '\'1970-01-01 00:00:01\'',
233
                     'until' => '\'1970-01-01 00:00:01\''
234
                 ] as $search => $replace) {
235
            if (false !== strpos($name, $search)) {
236
                return $replace;
237
            }
238
        }
239
        return $column;
240
    }
241
    /**
242
     * @var string $apiName
243
     */
244
    private $apiName;
245
    /**
246
     * @var string $sectionName
247
     */
248
    private $sectionName;
249
    /**
250
     * @var array $tables
251
     */
252
    private $tables;
253
}
254