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

CommonEveApiTrait   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 284
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 6
Bugs 0 Features 1
Metric Value
wmc 39
c 6
b 0
f 1
lcom 1
cbo 6
dl 0
loc 284
rs 8.2857

8 Methods

Rating   Name   Duplication   Size   Complexity  
D oneShot() 0 35 9
C startEveApi() 0 36 8
B cachedUntilIsNotExpired() 0 43 6
A extractOwnerID() 0 9 3
A getMask() 0 4 1
A gotApiLock() 0 20 3
A releaseApiLock() 0 20 3
B updateCachedUntil() 0 41 6
1
<?php
2
/**
3
 * Contains CommonEveApiTrait trait.
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 Monolog\Logger;
37
use Yapeal\CommonToolsTrait;
38
use Yapeal\Event\EveApiEventEmitterTrait;
39
use Yapeal\Event\EveApiEventInterface;
40
use Yapeal\Event\MediatorInterface;
41
use Yapeal\Xml\EveApiReadWriteInterface;
42
43
/**
44
 * Trait CommonEveApiTrait
45
 */
46
trait CommonEveApiTrait
47
{
48
    use CommonToolsTrait, EveApiEventEmitterTrait;
49
    /**
50
     * @param EveApiReadWriteInterface $data
51
     *
52
     * @return bool
53
     * @throws \DomainException
54
     * @throws \InvalidArgumentException
55
     * @throws \LogicException
56
     * @throws \Yapeal\Exception\YapealDatabaseException
57
     */
58
    public function oneShot(EveApiReadWriteInterface $data)
0 ignored issues
show
Coding Style introduced by
function oneShot() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
59
    {
60
        if (!$this->gotApiLock($data)) {
61
            return false;
62
        }
63
        $result = true;
64
        $eventSuffixes = ['retrieve', 'transform', 'validate', 'cache', 'preserve'];
65
        foreach ($eventSuffixes as $eventSuffix) {
66
            if (false === $this->emitEvents($data, $eventSuffix)) {
67
                $result = false;
68
                break;
69
            }
70
            if (false === $data->getEveApiXml()) {
71
                if ($data->hasEveApiArgument('accountKey') && '10000' === $data->getEveApiArgument('accountKey')
72
                    && 'corp' === strtolower($data->getEveApiSectionName())
73
                ) {
74
                    $mess = 'No faction warfare account data in';
75
                    $this->getYem()
76
                        ->triggerLogEvent('Yapeal.Log.log', Logger::INFO, $this->createEveApiMessage($mess, $data));
77
                    break;
78
                }
79
                $this->getYem()
80
                    ->triggerLogEvent('Yapeal.Log.log', Logger::NOTICE,
81
                        $this->getEmptyXmlDataMessage($data, $eventSuffix));
82
                $result = false;
83
                break;
84
            }
85
        }
86
        if ($result) {
87
            $this->updateCachedUntil($data);
88
            $this->emitEvents($data, 'end');
89
        }
90
        $this->releaseApiLock($data);
91
        return $result;
92
    }
93
    /**
94
     * @param EveApiEventInterface $event
95
     * @param string               $eventName
96
     * @param MediatorInterface    $yem
97
     *
98
     * @return EveApiEventInterface
99
     * @throws \DomainException
100
     * @throws \InvalidArgumentException
101
     * @throws \LogicException
102
     * @throws \Yapeal\Exception\YapealDatabaseException
103
     */
104
    public function startEveApi(EveApiEventInterface $event, $eventName, MediatorInterface $yem)
105
    {
106
        $this->setYem($yem);
107
        $data = $event->getData();
108
        $yem->triggerLogEvent('Yapeal.Log.log', Logger::DEBUG,
109
            $this->getReceivedEventMessage($data, $eventName, __CLASS__));
110
        // If method doesn't exist still needs array with member for count but return '0' from extractOwnerID().
111
        $active = method_exists($this, 'getActive') ? $this->getActive($data) : [[null]];
112
        if (0 === count($active)) {
113
            $mess = 'No active owners found for';
114
            $yem->triggerLogEvent('Yapeal.Log.log', Logger::INFO, $this->createEveApiMessage($mess, $data));
115
            $this->emitEvents($data, 'end');
116
            return $event->setHandledSufficiently();
117
        }
118
        $untilInterval = $data->getCacheInterval();
119
        foreach ($active as $arguments) {
120
            // Set arguments, reset interval, and clear xml data.
121
            $data->setEveApiArguments($arguments)
122
                ->setCacheInterval($untilInterval)
123
                ->setEveApiXml();
124
            foreach ($this->accountKeys as $accountKey) {
125
                $data->addEveApiArgument('accountKey', $accountKey);
126
                if (0 === strpos(strtolower($data->getEveApiName()), 'wallet')) {
127
                    $data->addEveApiArgument('rowCount', '2560');
128
                }
129
                if ($this->cachedUntilIsNotExpired($data)) {
130
                    $event->setHandledSufficiently();
131
                    continue;
132
                }
133
                if ($this->oneShot($data)) {
134
                    $event->setHandledSufficiently();
135
                }
136
            }
137
        }
138
        return $event;
139
    }
140
    /**
141
     * @param EveApiReadWriteInterface $data
142
     *
143
     * @return bool
144
     * @throws \DomainException
145
     * @throws \InvalidArgumentException
146
     * @throws \LogicException
147
     * @throws \Yapeal\Exception\YapealDatabaseException
148
     */
149
    protected function cachedUntilIsNotExpired(EveApiReadWriteInterface $data)
0 ignored issues
show
Coding Style introduced by
function cachedUntilIsNotExpired() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
150
    {
151
        $columns = [
152
            'accountKey' => $data->hasEveApiArgument('accountKey') ? $data->getEveApiArgument('accountKey') : '0',
153
            'apiName' => $data->getEveApiName(),
154
            'ownerID' => $this->extractOwnerID($data->getEveApiArguments()),
155
            'sectionName' => $data->getEveApiSectionName()
156
        ];
157
        $sql = $this->getCsq()
158
            ->getUtilCachedUntilExpires($columns);
159
        $this->getYem()
160
            ->triggerLogEvent('Yapeal.Log.log', Logger::DEBUG, $sql);
161
        try {
162
            $expires = $this->getPdo()
163
                ->query($sql)
164
                ->fetchAll(\PDO::FETCH_ASSOC);
165
        } catch (\PDOException $exc) {
166
            $mess = 'Could NOT get cache expired for';
167
            $this->getYem()
168
                ->triggerLogEvent('Yapeal.Log.log', Logger::WARNING, $this->createEveApiMessage($mess, $data),
169
                    ['exception' => $exc]);
170
            return false;
171
        }
172
        if (0 === count($expires)) {
173
            $mess = 'No UtilCachedUntil record found for';
174
            $this->getYem()
175
                ->triggerLogEvent('Yapeal.Log.log', Logger::DEBUG, $this->createEveApiMessage($mess, $data));
176
            return false;
177
        }
178
        if (1 < count($expires)) {
179
            $mess = 'Multiple UtilCachedUntil records found for';
180
            $this->getYem()
181
                ->triggerLogEvent('Yapeal.Log.log', Logger::WARNING, $this->createEveApiMessage($mess, $data));
182
            return false;
183
        }
184
        if (strtotime($expires[0]['expires'] . '+00:00') < time()) {
185
            $mess = 'Expired UtilCachedUntil record found for';
186
            $this->getYem()
187
                ->triggerLogEvent('Yapeal.Log.log', Logger::DEBUG, $this->createEveApiMessage($mess, $data));
188
            return false;
189
        }
190
        return true;
191
    }
192
    /**
193
     * @param string[] $candidates
194
     *
195
     * @return string
196
     */
197
    protected function extractOwnerID(array $candidates)
198
    {
199
        foreach (['corporationID', 'characterID', 'keyID'] as $item) {
200
            if (array_key_exists($item, $candidates)) {
201
                return (string)$candidates[$item];
202
            }
203
        }
204
        return '0';
205
    }
206
    /**
207
     * @return int
208
     */
209
    protected function getMask()
210
    {
211
        return $this->mask;
212
    }
213
    /**
214
     * @param EveApiReadWriteInterface $data
215
     *
216
     * @return bool
217
     * @throws \DomainException
218
     * @throws \InvalidArgumentException
219
     * @throws \LogicException
220
     * @throws \Yapeal\Exception\YapealDatabaseException
221
     */
222
    protected function gotApiLock(EveApiReadWriteInterface $data)
0 ignored issues
show
Coding Style introduced by
function gotApiLock() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
223
    {
224
        $sql = $this->getCsq()
225
            ->getApiLock($data->getHash());
226
        $this->getYem()
227
            ->triggerLogEvent('Yapeal.Log.log', Logger::DEBUG, $sql);
228
        $context = [];
229
        $success = false;
230
        try {
231
            $success = (bool)$this->getPdo()
232
                ->query($sql)
233
                ->fetchColumn();
234
        } catch (\PDOException $exc) {
235
            $context = ['exception' => $exc];
236
        }
237
        $mess = $success ? 'Got lock for' : 'Could NOT get lock for';
238
        $this->getYem()
239
            ->triggerLogEvent('Yapeal.Log.log', Logger::INFO, $this->createEveApiMessage($mess, $data), $context);
240
        return $success;
241
    }
242
    /**
243
     * @param EveApiReadWriteInterface $data
244
     *
245
     * @return bool
246
     * @throws \DomainException
247
     * @throws \InvalidArgumentException
248
     * @throws \LogicException
249
     * @throws \Yapeal\Exception\YapealDatabaseException
250
     */
251
    protected function releaseApiLock(EveApiReadWriteInterface $data)
0 ignored issues
show
Coding Style introduced by
function releaseApiLock() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
252
    {
253
        $sql = $this->getCsq()
254
            ->getApiLockRelease($data->getHash());
255
        $this->getYem()
256
            ->triggerLogEvent('Yapeal.Log.log', Logger::DEBUG, $sql);
257
        $context = [];
258
        $success = false;
259
        try {
260
            $success = (bool)$this->getPdo()
261
                ->query($sql)
262
                ->fetchColumn();
263
        } catch (\PDOException $exc) {
264
            $context = ['exception' => $exc];
265
        }
266
        $mess = $success ? 'Released lock for' : 'Could NOT release lock for';
267
        $this->getYem()
268
            ->triggerLogEvent('Yapeal.Log.log', Logger::INFO, $this->createEveApiMessage($mess, $data), $context);
269
        return $success;
270
    }
271
    /**
272
     * @param EveApiReadWriteInterface $data
273
     *
274
     * @return self Fluent interface.
275
     * @throws \DomainException
276
     * @throws \InvalidArgumentException
277
     * @throws \LogicException
278
     * @throws \Yapeal\Exception\YapealDatabaseException
279
     */
280
    protected function updateCachedUntil(EveApiReadWriteInterface $data)
281
    {
282
        if (false === $data->getEveApiXml()) {
283
            return $this;
284
        }
285
        /** @noinspection PhpUndefinedFieldInspection */
286
        /** @noinspection UnnecessaryParenthesesInspection */
287
        $currentTime = (string)(new \SimpleXMLElement($data->getEveApiXml()))->currentTime[0];
288
        if ('' === $currentTime) {
289
            return $this;
290
        }
291
        $dateTime = gmdate('Y-m-d H:i:s', strtotime($currentTime . '+00:00') + $data->getCacheInterval());
292
        $row = [
293
            'accountKey' => $data->hasEveApiArgument('accountKey') ? $data->getEveApiArgument('accountKey') : '0',
294
            'apiName' => $data->getEveApiName(),
295
            'expires' => $dateTime,
296
            'ownerID' => $this->extractOwnerID($data->getEveApiArguments()),
297
            'sectionName' => $data->getEveApiSectionName()
298
        ];
299
        $sql = $this->getCsq()
300
            ->getUpsert('utilCachedUntil', array_keys($row), 1);
301
        $this->getYem()
302
            ->triggerLogEvent('Yapeal.Log.log', Logger::DEBUG, $sql);
303
        $pdo = $this->getPdo();
304
        $pdo->beginTransaction();
305
        $context = [];
306
        $success = false;
307
        try {
308
            $pdo->prepare($sql)
309
                ->execute(array_values($row));
310
            $pdo->commit();
311
            $success = true;
312
        } catch (\PDOException $exc) {
313
            $pdo->rollBack();
314
            $context = ['exception' => $exc];
315
        }
316
        $mess = $success ? 'Updated cached until date/time of' : 'Could NOT update cached until date/time of';
317
        $this->getYem()
318
            ->triggerLogEvent('Yapeal.Log.log', Logger::INFO, $this->createEveApiMessage($mess, $data), $context);
319
        return $this;
320
    }
321
    /**
322
     * @var int[] $accountKey
323
     */
324
    protected $accountKeys = [0];
325
    /**
326
     * @var int $mask
327
     */
328
    protected $mask;
329
}
330