Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Support;
4
 
5
use ReflectionClass;
6
use ReflectionEnum;
7
use ReflectionMethod;
8
use ReflectionNamedType;
9
use ReflectionUnionType;
10
 
11
class Reflector
12
{
13
    /**
14
     * This is a PHP 7.4 compatible implementation of is_callable.
15
     *
16
     * @param  mixed  $var
17
     * @param  bool  $syntaxOnly
18
     * @return bool
19
     */
20
    public static function isCallable($var, $syntaxOnly = false)
21
    {
22
        if (! is_array($var)) {
23
            return is_callable($var, $syntaxOnly);
24
        }
25
 
26
        if (! isset($var[0], $var[1]) || ! is_string($var[1] ?? null)) {
27
            return false;
28
        }
29
 
30
        if ($syntaxOnly &&
31
            (is_string($var[0]) || is_object($var[0])) &&
32
            is_string($var[1])) {
33
            return true;
34
        }
35
 
36
        $class = is_object($var[0]) ? get_class($var[0]) : $var[0];
37
 
38
        $method = $var[1];
39
 
40
        if (! class_exists($class)) {
41
            return false;
42
        }
43
 
44
        if (method_exists($class, $method)) {
45
            return (new ReflectionMethod($class, $method))->isPublic();
46
        }
47
 
48
        if (is_object($var[0]) && method_exists($class, '__call')) {
49
            return (new ReflectionMethod($class, '__call'))->isPublic();
50
        }
51
 
52
        if (! is_object($var[0]) && method_exists($class, '__callStatic')) {
53
            return (new ReflectionMethod($class, '__callStatic'))->isPublic();
54
        }
55
 
56
        return false;
57
    }
58
 
59
    /**
60
     * Get the class name of the given parameter's type, if possible.
61
     *
62
     * @param  \ReflectionParameter  $parameter
63
     * @return string|null
64
     */
65
    public static function getParameterClassName($parameter)
66
    {
67
        $type = $parameter->getType();
68
 
69
        if (! $type instanceof ReflectionNamedType || $type->isBuiltin()) {
70
            return;
71
        }
72
 
73
        return static::getTypeName($parameter, $type);
74
    }
75
 
76
    /**
77
     * Get the class names of the given parameter's type, including union types.
78
     *
79
     * @param  \ReflectionParameter  $parameter
80
     * @return array
81
     */
82
    public static function getParameterClassNames($parameter)
83
    {
84
        $type = $parameter->getType();
85
 
86
        if (! $type instanceof ReflectionUnionType) {
87
            return array_filter([static::getParameterClassName($parameter)]);
88
        }
89
 
90
        $unionTypes = [];
91
 
92
        foreach ($type->getTypes() as $listedType) {
93
            if (! $listedType instanceof ReflectionNamedType || $listedType->isBuiltin()) {
94
                continue;
95
            }
96
 
97
            $unionTypes[] = static::getTypeName($parameter, $listedType);
98
        }
99
 
100
        return array_filter($unionTypes);
101
    }
102
 
103
    /**
104
     * Get the given type's class name.
105
     *
106
     * @param  \ReflectionParameter  $parameter
107
     * @param  \ReflectionNamedType  $type
108
     * @return string
109
     */
110
    protected static function getTypeName($parameter, $type)
111
    {
112
        $name = $type->getName();
113
 
114
        if (! is_null($class = $parameter->getDeclaringClass())) {
115
            if ($name === 'self') {
116
                return $class->getName();
117
            }
118
 
119
            if ($name === 'parent' && $parent = $class->getParentClass()) {
120
                return $parent->getName();
121
            }
122
        }
123
 
124
        return $name;
125
    }
126
 
127
    /**
128
     * Determine if the parameter's type is a subclass of the given type.
129
     *
130
     * @param  \ReflectionParameter  $parameter
131
     * @param  string  $className
132
     * @return bool
133
     */
134
    public static function isParameterSubclassOf($parameter, $className)
135
    {
136
        $paramClassName = static::getParameterClassName($parameter);
137
 
138
        return $paramClassName
139
            && (class_exists($paramClassName) || interface_exists($paramClassName))
140
            && (new ReflectionClass($paramClassName))->isSubclassOf($className);
141
    }
142
 
143
    /**
144
     * Determine if the parameter's type is a Backed Enum with a string backing type.
145
     *
146
     * @param  \ReflectionParameter  $parameter
147
     * @return bool
148
     */
149
    public static function isParameterBackedEnumWithStringBackingType($parameter)
150
    {
151
        $backedEnumClass = (string) $parameter->getType();
152
 
153
        if (function_exists('enum_exists') && enum_exists($backedEnumClass)) {
154
            $reflectionBackedEnum = new ReflectionEnum($backedEnumClass);
155
 
156
            return $reflectionBackedEnum->isBacked()
157
                && $reflectionBackedEnum->getBackingType()->getName() == 'string';
158
        }
159
 
160
        return false;
161
    }
162
}