Completed
Push — master ( 23f69a...13261c )
by Nikola
03:25
created

ClassUtils::isWithinNamespace()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 19
ccs 10
cts 10
cp 1
rs 9.2
c 1
b 0
f 1
cc 4
eloc 10
nc 6
nop 2
crap 4
1
<?php
2
/*
3
 * This file is part of the  TraitorBundle, an RunOpenCode project.
4
 *
5
 * (c) 2017 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace RunOpenCode\Bundle\Traitor\Utils;
11
12
use RunOpenCode\Bundle\Traitor\Exception\InvalidArgumentException;
13
use RunOpenCode\Bundle\Traitor\Exception\RuntimeException;
14
15
final class ClassUtils
16
{
17
    final private function __construct() { /** noop */ }
0 ignored issues
show
Coding Style introduced by
Unnecessary FINAL modifier in FINAL class
Loading history...
18
19
    /**
20
     * Check if class uses trait.
21
     *
22
     * @param object|string $objectOrClass Instance of class or FQCN
23
     * @param string $trait FQCN trait
24
     * @param bool $autoload Weather to autoload class.
25
     *
26
     * @return bool TRUE if class uses trait.
27
     *
28
     * @throws \RunOpenCode\Bundle\Traitor\Exception\InvalidArgumentException
29
     * @throws \RunOpenCode\Bundle\Traitor\Exception\RuntimeException
30
     */
31 10
    public static function usesTrait($objectOrClass, $trait, $autoload = true)
32
    {
33 10
        if (is_object($objectOrClass)) {
34 1
            $objectOrClass = get_class($objectOrClass);
35
        }
36
37 10
        if (!is_string($objectOrClass)) {
38 1
            throw new InvalidArgumentException(sprintf('Full qualified class name expected, got: "%s".', gettype($objectOrClass)));
39
        }
40
41 9
        if (!class_exists($objectOrClass)) {
42 1
            throw new RuntimeException(sprintf('Class "%s" does not exists or it can not be autoloaded.', $objectOrClass));
43
        }
44
45 8
        if (in_array(ltrim($trait, '\\'), self::getTraits($objectOrClass, $autoload), false)) {
46 8
            return true;
47
        }
48
49 2
        return false;
50
    }
51
52
    /**
53
     * Get ALL traits used by one class.
54
     *
55
     * @param object|string $objectOrClass Instance of class or FQCN
56
     * @param bool $autoload Weather to autoload class.
57
     *
58
     * @throws \RunOpenCode\Bundle\Traitor\Exception\InvalidArgumentException
59
     * @throws \RunOpenCode\Bundle\Traitor\Exception\RuntimeException
60
     *
61
     * @return array Used traits.
62
     */
63 11
    public static function getTraits($objectOrClass, $autoload = true)
64
    {
65 11
        if (is_object($objectOrClass)) {
66 1
            $objectOrClass = get_class($objectOrClass);
67
        }
68
69 11
        if (!is_string($objectOrClass)) {
70 1
            throw new InvalidArgumentException(sprintf('Full qualified class name expected, got: "%s".', gettype($objectOrClass)));
71
        }
72
73 10
        if (!class_exists($objectOrClass)) {
74 1
            throw new RuntimeException(sprintf('Class "%s" does not exists or it can not be autoloaded.', $objectOrClass));
75
        }
76
77 9
        $traits = [];
78
79
        // Get traits of all parent classes
80
        do {
81 9
            $traits = array_merge(class_uses($objectOrClass, $autoload), $traits);
82 9
        } while ($objectOrClass = get_parent_class($objectOrClass));
83
84
        // Get traits of all parent traits
85 9
        $traitsToSearch = $traits;
86
87 9
        while (count($traitsToSearch) > 0) {
88 9
            $newTraits = class_uses(array_pop($traitsToSearch), $autoload);
89 9
            $traits = array_merge($newTraits, $traits);
90 9
            $traitsToSearch = array_merge($newTraits, $traitsToSearch);
91
        };
92
93 9
        foreach ($traits as $trait => $same) {
94 9
            $traits = array_merge(class_uses($trait, $autoload), $traits);
95
        }
96
97 9
        return array_unique(array_map(function ($fqcn) {
98 9
            return ltrim($fqcn, '\\');
99 9
        }, $traits));
100
    }
101
102
    /**
103
     * Check if class is within certain namespace.
104
     *
105
     * @param string|object $objectOrClass Class to check.
106
     * @param string $namespacePrefix Namespace prefix
107
     *
108
     * @return bool
109
     *
110
     * @throws \RunOpenCode\Bundle\Traitor\Exception\InvalidArgumentException
111
     * @throws \RunOpenCode\Bundle\Traitor\Exception\RuntimeException
112
     */
113 4
    public static function isWithinNamespace($objectOrClass, $namespacePrefix)
114
    {
115 4
        if (is_object($objectOrClass)) {
116 1
            $objectOrClass = get_class($objectOrClass);
117
        }
118
119 4
        if (!is_string($objectOrClass)) {
120 1
            throw new InvalidArgumentException(sprintf('Full qualified class name string expected, got: "%s".', gettype($objectOrClass)));
121
        }
122
123 3
        if (!class_exists($objectOrClass)) {
124 1
            throw new RuntimeException(sprintf('Class "%s" does not exists or it can not be autoloaded.', $objectOrClass));
125
        }
126
127 2
        $objectOrClass = ltrim($objectOrClass, '\\');
128 2
        $namespacePrefix = rtrim(ltrim($namespacePrefix, '\\'), '\\').'\\';
129
130 2
        return strpos($objectOrClass, $namespacePrefix) === 0;
131
    }
132
}
133