UrlXrefResolver::resolve()   C
last analyzed

Complexity

Conditions 12
Paths 35

Size

Total Lines 77
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 77
ccs 0
cts 66
cp 0
rs 5.2291
cc 12
eloc 58
nc 35
nop 2
crap 156

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
namespace ConfigToken\TreeCompiler\XrefResolver\Types;
4
5
use ConfigToken\Event;
6
use ConfigToken\EventManager;
7
use ConfigToken\TreeCompiler\XrefResolver\Exception\UnknownXrefTypeException;
8
use ConfigToken\TreeCompiler\XrefResolver\Exception\XrefResolverFetchException;
9
use ConfigToken\TreeCompiler\Xref;
10
use ConfigToken\TreeSerializer\TreeSerializerFactory;
11
12
13
class UrlXrefResolver extends AbstractXrefResolver
14
{
15
    const EVENT_ID_RESOLVE_URL = 'resolve-url';
16
    const EVENT_URL = 'url';
17
    const EVENT_DATA = 'data';
18
    const EVENT_CONTENT_TYPE = 'content-type';
19
20
    /**
21
     * Get the resolver type identifier string.
22
     *
23
     * @return string
24
     */
25 1
    public static function getType()
26
    {
27 1
        return 'url';
28
    }
29
30
    /**
31
     * Fetch the data from the specified location of the Xref.
32
     *
33
     * @param Xref $xref
34
     * @param boolean $force If true and Xref already fetched, force the resolver to fetch the data again.
35
     * @throws UnknownXrefTypeException
36
     * @throws XrefResolverFetchException
37
     * @throws \ConfigToken\TreeCompiler\XrefResolver\Exception\InvalidXrefTypeException
38
     * @throws \ConfigToken\TreeSerializer\Exception\UnknownContentTypeException
39
     * @throws \ConfigToken\TreeSerializer\Exception\UnknownFileExtensionException
40
     */
41
    public static function resolve(Xref $xref, $force = false)
42
    {
43
        if ($xref->isResolved() && (!$force)) {
44
            return;
45
        }
46
        static::matchType($xref);
47
        if (!$xref->hasLocation()) {
48
            throw new XrefResolverFetchException($xref);
49
        }
50
        $data = null;
51
        $httpCode = null;
52
        $contentType = null;
53
        $eventManager = EventManager::getInstance();
54
        if ($eventManager->hasListeners()) {
55
            $event = new Event(self::EVENT_ID_RESOLVE_URL);
56
            $event->data[self::EVENT_URL] = $xref->getLocation();
57
            $event->data[Event::RESULT] = false;
58
            $eventManager->dispatch($event);
59
            if (isset($event->data[Event::RESULT])) {
60
                if ($event->data[Event::RESULT] === true) {
61
                    $data = $event->data[self::EVENT_DATA];
62
                    $contentType = $event->data[self::EVENT_CONTENT_TYPE];
63
                    $httpCode = 200;
64
                } else if ($event->data[Event::RESULT] !== false) {
65
                    throw new XrefResolverFetchException(
66
                        $xref,
67
                        sprintf(
68
                            'Got error message from listener: %s',
69
                            $event->data[Event::RESULT]
70
                        )
71
                    );
72
                }
73
            }
74
        }
75
        if (!isset($data)) {
76
            $ch = curl_init();
77
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
78
            curl_setopt($ch, CURLOPT_URL, $xref->getLocation());
79
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
80
            curl_setopt($ch, CURLOPT_TIMEOUT, 60);
81
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
82
            curl_setopt($ch, CURLOPT_HEADER, false);
83
            $data = curl_exec($ch);
84
85
            $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
86
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
87
88
            curl_close($ch);
89
        }
90
91
        if ($httpCode != 200) {
92
            throw new XrefResolverFetchException($xref, sprintf('Got response code %d', $httpCode));
93
        }
94
        if (TreeSerializerFactory::isRegisteredByContentType($contentType)) {
95
            $serializer = TreeSerializerFactory::getByContentType($contentType);
96
            $xref->setContentType($contentType);
97
        } else {
98
            $path = parse_url($xref->getLocation(), PHP_URL_PATH);
99
            $fileExtension = pathinfo($path, PATHINFO_EXTENSION);
100
            if (!TreeSerializerFactory::isRegisteredByFileExtension($fileExtension)) {
101
                throw new UnknownXrefTypeException(
102
                    sprintf(
103
                        'Unable to find resolver for Xref content type "%s" or file extension "%s" for location "%s".',
104
                        $contentType,
105
                        $fileExtension,
106
                        $xref->getLocation()
107
                    )
108
                );
109
            }
110
            $serializer = TreeSerializerFactory::getByFileExtension($fileExtension);
111
            $xref->setContentType($serializer::getContentType());
112
        }
113
        // TODO: catch exception, show xref location in error message
114
        $data = $serializer::deserialize($data);
115
        $xref->setData($data);
116
        $xref->setResolved(true);
117
    }
118
}