Passed
Pull Request — main (#22)
by Andrey
14:27
created

Instance::of()   B

Complexity

Conditions 8
Paths 5

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 14
c 1
b 0
f 0
nc 5
nop 2
dl 0
loc 25
rs 8.4444
1
<?php
2
3
namespace Helldar\Support\Helpers;
4
5
use Helldar\Support\Facades\Helpers\Arr;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Helldar\Support\Helpers\Arr. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use Helldar\Support\Facades\Helpers\Is;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Helldar\Support\Helpers\Is. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
7
use Helldar\Support\Facades\Helpers\Reflection;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Helldar\Support\Helpers\Reflection. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
8
use ReflectionClass;
9
10
final class Instance
11
{
12
    public function of($haystack, $needles): bool
13
    {
14
        if (! $this->exists($haystack)) {
15
            return false;
16
        }
17
18
        $reflection = $this->resolve($haystack);
19
        $classname  = $this->classname($haystack);
20
21
        foreach (Arr::wrap($needles) as $needle) {
22
            if (! $this->exists($needle)) {
23
                continue;
24
            }
25
26
            if (
27
                $haystack instanceof $needle ||
28
                $classname === $this->classname($needle) ||
29
                $reflection->isSubclassOf($needle) ||
30
                $reflection->implementsInterface($needle)
31
            ) {
32
                return true;
33
            }
34
        }
35
36
        return false;
37
    }
38
39
    public function basename($class): string
40
    {
41
        $class = $this->classname($class);
42
43
        return basename(str_replace('\\', '/', $class));
44
    }
45
46
    public function classname($class = null): ?string
47
    {
48
        return Is::object($class) ? get_class($class) : $class;
49
    }
50
51
    public function exists($haystack): bool
52
    {
53
        if (Is::object($haystack)) {
54
            return true;
55
        }
56
57
        if (Is::string($haystack)) {
58
            return class_exists($haystack) || interface_exists($haystack);
59
        }
60
61
        return false;
62
    }
63
64
    public function call($object, string $method, $default = null)
65
    {
66
        if (Is::object($object) && method_exists($object, $method)) {
67
            return call_user_func([$object, $method]);
68
        }
69
70
        return $default;
71
    }
72
73
    public function callsWhenNotEmpty($object, $methods, $default = null)
74
    {
75
        foreach (Arr::wrap($methods) as $method) {
76
            if ($value = $this->call($object, $method)) {
77
                return $value;
78
            }
79
        }
80
81
        return $default;
82
    }
83
84
    public function callOf(array $map, $value, $default = null)
85
    {
86
        foreach ($map as $class => $method) {
87
            if ($this->of($value, $class)) {
88
                return $value->$method();
89
            }
90
        }
91
92
        return $default;
93
    }
94
95
    protected function resolve($class): ReflectionClass
96
    {
97
        return Reflection::resolve($class);
98
    }
99
}
100