Completed
Push — master ( df4948...3b59f8 )
by Michael
02:51
created

Creator::createEveApi()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 70
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 2
Metric Value
c 4
b 0
f 2
dl 0
loc 70
rs 6.8519
cc 7
eloc 56
nc 8
nop 3

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

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $b. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
255
            $a = strtolower($a);
256
            $b = strtolower($b);
257
            if ($a < $b) {
258
                return -1;
259
            } elseif ($a > $b) {
260
                return 1;
261
            }
262
            return 0;
263
        });
264
        $this->tables[$tableName] = ['values' => $values];
265
    }
266
    /**
267
     * @var string $sectionName
268
     */
269
    protected $sectionName;
270
    /**
271
     * @var array $tables
272
     */
273
    protected $tables;
274
}
275