103 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace Illuminate\Support;
 | 
						|
 | 
						|
use ReflectionClass;
 | 
						|
use ReflectionMethod;
 | 
						|
use ReflectionNamedType;
 | 
						|
 | 
						|
class Reflector
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * This is a PHP 7.4 compatible implementation of is_callable.
 | 
						|
     *
 | 
						|
     * @param  mixed  $var
 | 
						|
     * @param  bool  $syntaxOnly
 | 
						|
     * @return bool
 | 
						|
     */
 | 
						|
    public static function isCallable($var, $syntaxOnly = false)
 | 
						|
    {
 | 
						|
        if (! is_array($var)) {
 | 
						|
            return is_callable($var, $syntaxOnly);
 | 
						|
        }
 | 
						|
 | 
						|
        if ((! isset($var[0]) || ! isset($var[1])) ||
 | 
						|
            ! is_string($var[1] ?? null)) {
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
        if ($syntaxOnly &&
 | 
						|
            (is_string($var[0]) || is_object($var[0])) &&
 | 
						|
            is_string($var[1])) {
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
 | 
						|
        $class = is_object($var[0]) ? get_class($var[0]) : $var[0];
 | 
						|
 | 
						|
        $method = $var[1];
 | 
						|
 | 
						|
        if (! class_exists($class)) {
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
        if (method_exists($class, $method)) {
 | 
						|
            return (new ReflectionMethod($class, $method))->isPublic();
 | 
						|
        }
 | 
						|
 | 
						|
        if (is_object($var[0]) && method_exists($class, '__call')) {
 | 
						|
            return (new ReflectionMethod($class, '__call'))->isPublic();
 | 
						|
        }
 | 
						|
 | 
						|
        if (! is_object($var[0]) && method_exists($class, '__callStatic')) {
 | 
						|
            return (new ReflectionMethod($class, '__callStatic'))->isPublic();
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Get the class name of the given parameter's type, if possible.
 | 
						|
     *
 | 
						|
     * @param  \ReflectionParameter  $parameter
 | 
						|
     * @return string|null
 | 
						|
     */
 | 
						|
    public static function getParameterClassName($parameter)
 | 
						|
    {
 | 
						|
        $type = $parameter->getType();
 | 
						|
 | 
						|
        if (! $type instanceof ReflectionNamedType || $type->isBuiltin()) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        $name = $type->getName();
 | 
						|
 | 
						|
        if (! is_null($class = $parameter->getDeclaringClass())) {
 | 
						|
            if ($name === 'self') {
 | 
						|
                return $class->getName();
 | 
						|
            }
 | 
						|
 | 
						|
            if ($name === 'parent' && $parent = $class->getParentClass()) {
 | 
						|
                return $parent->getName();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return $name;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Determine if the parameter's type is a subclass of the given type.
 | 
						|
     *
 | 
						|
     * @param  \ReflectionParameter  $parameter
 | 
						|
     * @param  string  $className
 | 
						|
     * @return bool
 | 
						|
     */
 | 
						|
    public static function isParameterSubclassOf($parameter, $className)
 | 
						|
    {
 | 
						|
        $paramClassName = static::getParameterClassName($parameter);
 | 
						|
 | 
						|
        return ($paramClassName && class_exists($paramClassName))
 | 
						|
            ? (new ReflectionClass($paramClassName))->isSubclassOf($className)
 | 
						|
            : false;
 | 
						|
    }
 | 
						|
}
 |