Completed
Pull Request — master (#28)
by Samuel
04:31
created

ReactFactory::buildHttpClient05()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 18
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 18
loc 18
ccs 0
cts 8
cp 0
rs 9.2
cc 4
eloc 9
nc 4
nop 2
crap 20
1
<?php
2
3
namespace Http\Adapter\React;
4
5
use React\EventLoop\LoopInterface;
6
use React\EventLoop\Factory as EventLoopFactory;
7
use React\Dns\Resolver\Resolver as DnsResolver;
8
use React\Dns\Resolver\Factory as DnsResolverFactory;
9
use React\HttpClient\Client as HttpClient;
10
use React\HttpClient\Factory as HttpClientFactory;
11
use React\Socket\Connector;
12
use React\Socket\ConnectorInterface;
13
14
/**
15
 * Factory wrapper for React instances.
16
 *
17
 * @author Stéphane Hulard <[email protected]>
18
 */
19
class ReactFactory
20
{
21
    /**
22
     * Build a react Event Loop.
23
     *
24
     * @return LoopInterface
25
     */
26 109
    public static function buildEventLoop()
27
    {
28 109
        return EventLoopFactory::create();
29 1
    }
30
31
    /**
32
     * Build a React Dns Resolver.
33
     *
34
     * @param LoopInterface $loop
35
     * @param string        $dns
36
     *
37
     * @return DnsResolver
38
     */
39 109
    public static function buildDnsResolver(
40
        LoopInterface $loop,
41
        $dns = '8.8.8.8'
42
    ) {
43 109
        $factory = new DnsResolverFactory();
44
45 109
        return $factory->createCached($dns, $loop);
46
    }
47
48
    /**
49
     * @param LoopInterface    $loop
50
     * @param DnsResolver|null $dns
51
     *
52
     * @return ConnectorInterface
53
     */
54
    public static function buildConnector(
55
        LoopInterface $loop,
56
        DnsResolver $dns = null
57
    ) {
58
        return null !== $dns
59
            ? new Connector($loop, ['dns' => $dns])
60
            : new Connector($loop);
61
    }
62
63
    /**
64
     * Build a React Http Client.
65
     *
66
     * @param LoopInterface                       $loop
67
     * @param ConnectorInterface|DnsResolver|null $connector Passing a DnsResolver instance is deprecated. Should pass a
68
     *                                                       ConnectorInterface instance.
69
     *
70
     * @return HttpClient
71
     */
72 111
    public static function buildHttpClient(
73
        LoopInterface $loop,
74
        $connector = null
75
    ) {
76 111
        if (class_exists(HttpClientFactory::class)) {
77
            // if HttpClientFactory class exists, use old behavior for backwards compatibility
78 111
            return static::buildHttpClient04($loop, $connector);
0 ignored issues
show
Bug introduced by
Since buildHttpClient04() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of buildHttpClient04() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
Bug introduced by
It seems like $connector defined by parameter $connector on line 74 can also be of type object<React\Socket\ConnectorInterface>; however, Http\Adapter\React\React...ry::buildHttpClient04() does only seem to accept object<React\Dns\Resolver\Resolver>|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
79
        } else {
80
            return static::buildHttpClient05($loop, $connector);
0 ignored issues
show
Bug introduced by
Since buildHttpClient05() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of buildHttpClient05() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
81
        }
82
    }
83
84
    /**
85
     * Builds a React Http client v0.4 style
86
     *
87
     * @param LoopInterface    $loop
88
     * @param DnsResolver|null $dns
89
     *
90
     * @return HttpClient
91
     */
92 111 View Code Duplication
    private static function buildHttpClient04(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
93
        LoopInterface $loop,
94
        $dns = null
95
    ) {
96
        // create dns resolver if one isn't provided
97 111
        if (null === $dns) {
98 109
            $dns = static::buildDnsResolver($loop);
99 109
        }
100
101
        // validate connector instance for proper error reporting
102 111
        if (!$dns instanceof DnsResolver) {
103 1
            throw new \InvalidArgumentException('$connector must be an instance of DnsResolver');
104
        }
105
106 110
        $factory = new HttpClientFactory();
107
108 110
        return $factory->create($loop, $dns);
109
    }
110
111
    /**
112
     * Builds a React Http client v0.5 style
113
     *
114
     * @param LoopInterface                       $loop
115
     * @param DnsResolver|ConnectorInterface|null $connector
116
     *
117
     * @return HttpClient
118
     */
119 View Code Duplication
    private static function buildHttpClient05(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
120
        LoopInterface $loop,
121
        $connector = null
122
    ) {
123
        // build a connector with given DnsResolver if provided (old deprecated behavior)
124
        if ($connector instanceof DnsResolver) {
125
            $connector = static::buildConnector($loop, $connector);
126
        }
127
128
        // validate connector instance for proper error reporting
129
        if (null !== $connector && !$connector instanceof ConnectorInterface) {
130
            throw new \InvalidArgumentException(
131
                '$connector must be an instance of DnsResolver or ConnectorInterface'
132
            );
133
        }
134
135
        return new HttpClient($loop, $connector);
136
    }
137
}
138