Completed
Push — master ( dcd887...0edee5 )
by Delete
02:49
created

AdapterFactory::setDefaultAdapterClasses()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 4
Ratio 100 %
Metric Value
dl 4
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Crossjoin\Browscap\Parser\Sqlite\Adapter;
5
6
use Crossjoin\Browscap\Exception\BrowscapException;
7
use Crossjoin\Browscap\Exception\InvalidArgumentException;
8
use Crossjoin\Browscap\Exception\ParserConditionNotSatisfiedException;
9
use Crossjoin\Browscap\Exception\UnexpectedValueException;
10
11
/**
12
 * Class AdapterFactory
13
 *
14
 * @package Crossjoin\Browscap\Parser\Sqlite\Adapter
15
 * @author Christoph Ziegenberg <[email protected]>
16
 * @link https://github.com/crossjoin/browscap
17
 */
18
class AdapterFactory
19
{
20
    const DEFAULT_CLASSES = [
21
        '\Crossjoin\Browscap\Parser\Sqlite\Adapter\Pdo',
22
        '\Crossjoin\Browscap\Parser\Sqlite\Adapter\Sqlite3',
23
    ];
24
25
    protected static $adapterClasses = self::DEFAULT_CLASSES;
26
27
    /**
28
     * @param string $fileName
29
     *
30
     * @return AdapterInterface
31
     * @throws ParserConditionNotSatisfiedException
32
     * @throws UnexpectedValueException
33
     */
34
    public static function getInstance(string $fileName) : AdapterInterface
35
    {
36
        foreach (static::$adapterClasses as $className) {
37
            $instance = static::getInstanceByClassName($className, $fileName);
38
            if ($instance !== null) {
39
                return $instance;
40
            }
41
        }
42
43
        throw new ParserConditionNotSatisfiedException(
44
            "No Sqlite extension found. Either 'pdo_sqlite' or 'sqlite3' extension required."
45
        );
46
    }
47
48
    /**
49
     * @param array $fullyQualifiedClassNames
50
     *
51
     * @throws InvalidArgumentException
52
     */
53
    public static function setAdapterClasses(array $fullyQualifiedClassNames)
54
    {
55
        $rememberClasses = self::$adapterClasses;
56
57
        self::$adapterClasses = [];
58
        foreach ($fullyQualifiedClassNames as $className) {
59
            if (is_string($className)) {
60
                self::$adapterClasses[] = $className;
61
            } else {
62
                // Reset to previous value on error
63
                self::$adapterClasses = $rememberClasses;
64
65
                throw new InvalidArgumentException(
66
                    "A value in the class name array is of type '" . gettype($className) . "'. String expected."
67
                );
68
            }
69
        }
70
    }
71
72
    /**
73
     * @param string $className
74
     * @param string $fileName
75
     *
76
     * @return AdapterInterface|null
77
     * @throws UnexpectedValueException
78
     */
79
    protected static function getInstanceByClassName(string $className, string $fileName)
80
    {
81
        if (class_exists($className)) {
82
            $interface = '\Crossjoin\Browscap\Parser\Sqlite\Adapter\AdapterFactoryInterface';
83
            $interfaces = class_implements($className);
84
            if (array_key_exists(ltrim($interface, '\\'), $interfaces)) {
85
                try {
86
                    return new $className($fileName);
87
                } catch (BrowscapException $e) {
88
                    // Ignore exception, because we just return NULL on failure
89
                }
90
            } else {
91
                throw new UnexpectedValueException(
92
                    "Class '$className' has to implement the interface '$interface'.",
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $className instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $interface instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
93
                    1459000689
94
                );
95
            }
96
        } else {
97
            throw new UnexpectedValueException("Class '$className' doesn't exist.", 1459000690);
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $className instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
98
        }
99
100
        return null;
101
    }
102
}
103