Completed
Push — master ( eef492...cef1d4 )
by Michael
04:41
created

Validator::setDir()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
/**
3
 * Contains Validator 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\Xsd;
35
36
use DOMDocument;
37
use SimpleXMLElement;
38
use Yapeal\Event\EveApiEventEmitterTrait;
39
use Yapeal\Event\EveApiEventInterface;
40
use Yapeal\Event\MediatorInterface;
41
use Yapeal\FileSystem\RelativeFileSearchTrait;
42
use Yapeal\Log\Logger;
43
use Yapeal\Xml\EveApiReadWriteInterface;
44
45
/**
46
 * Class Validator
47
 */
48
class Validator
49
{
50
    use EveApiEventEmitterTrait, RelativeFileSearchTrait;
51
    /**
52
     * Constructor.
53
     *
54
     * @param string $dir Base directory where Eve API XSD files can be found.
55
     */
56
    public function __construct($dir = __DIR__)
57
    {
58
        $this->setRelativeBaseDir($dir . '/');
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 validateEveApi(EveApiEventInterface $event, $eventName, MediatorInterface $yem)
71
    {
72
        $this->setYem($yem);
73
        $data = $event->getData();
74
        $this->getYem()
75
            ->triggerLogEvent(
76
                'Yapeal.Log.log',
77
                Logger::DEBUG,
78
                $this->getReceivedEventMessage($data, $eventName, __CLASS__)
79
            );
80
        $fileName = $this->findEveApiFile($data->getEveApiSectionName(), $data->getEveApiName(), 'xsd');
81
        if ('' === $fileName) {
82
            return $event;
83
        }
84
        $oldErrors = libxml_use_internal_errors(true);
85
        libxml_clear_errors();
86
        $dom = new DOMDocument();
87
        $dom->loadXML($data->getEveApiXml());
88
        if (!$dom->schemaValidate($fileName)) {
89
            /**
90
             * @type array $errors
91
             */
92
            $errors = libxml_get_errors();
93
            if (0 !== count($errors)) {
94
                foreach ($errors as $error) {
95
                    $this->getYem()
96
                        ->triggerLogEvent('Yapeal.Log.log', Logger::NOTICE, $error->message);
97
                }
98
            }
99
            libxml_clear_errors();
100
            libxml_use_internal_errors($oldErrors);
101
            return $event;
102
        }
103
        libxml_clear_errors();
104
        libxml_use_internal_errors($oldErrors);
105
        if (false !== strpos($data->getEveApiXml(), '<error ')) {
106
            $data = $this->processEveApiXmlError($data, $yem);
107
            $event->setData($data);
108
            $this->emitEvents($data, 'error', 'Yapeal.Xml');
109
        }
110
        return $event->eventHandled();
111
    }
112
    /**
113
     * @param EveApiReadWriteInterface $data
114
     * @param MediatorInterface        $yem
115
     *
116
     * @return EveApiReadWriteInterface
117
     * @throws \DomainException
118
     * @throws \InvalidArgumentException
119
     * @throws \LogicException
120
     */
121
    protected function processEveApiXmlError(
122
        EveApiReadWriteInterface $data,
123
        MediatorInterface $yem
124
    ) {
125
        $simple = new SimpleXMLElement($data->getEveApiXml());
126
        /** @noinspection PhpUndefinedFieldInspection */
127
        if (empty($simple->error[0]['code'])) {
128
            return $data;
129
        }
130
        /** @noinspection PhpUndefinedFieldInspection */
131
        $code = (int)$simple->error[0]['code'];
132
        /** @noinspection PhpUndefinedFieldInspection */
133
        $mess = sprintf('Received XML error (%1$s) - %2$s from', $code, (string)$simple->error[0]);
134
        if ($code < 200) {
135
            if (strpos($mess, 'retry after') !== false) {
136
                $data->setCacheInterval(strtotime(substr($mess, -19) . '+00:00') - time());
137
            }
138
            $yem->triggerLogEvent('Yapeal.Log.log', Logger::WARNING, $this->createEveApiMessage($mess, $data));
139
            return $data;
140
        }
141
        if ($code < 300) {
142
            $yem->triggerLogEvent('Yapeal.Log.log', Logger::ERROR, $this->createEveApiMessage($mess, $data));
143
            return $data->setCacheInterval(86400);
144
        }
145
        if ($code > 903 && $code < 905) {
146
            // Major application or Yapeal error.
147
            $yem->triggerLogEvent('Yapeal.Log.log', Logger::ALERT, $this->createEveApiMessage($mess, $data));
148
            return $data->setCacheInterval(86400);
149
        }
150
        $yem->triggerLogEvent('Yapeal.Log.log', Logger::WARNING, $this->createEveApiMessage($mess, $data));
151
        return $data->setCacheInterval(300);
152
    }
153
}
154