264 lines
6.0 KiB
PHP
Executable File
264 lines
6.0 KiB
PHP
Executable File
<?php
|
|
|
|
namespace Illuminate\Support\Facades;
|
|
|
|
use Closure;
|
|
use Mockery;
|
|
use Mockery\MockInterface;
|
|
use RuntimeException;
|
|
|
|
abstract class Facade
|
|
{
|
|
/**
|
|
* The application instance being facaded.
|
|
*
|
|
* @var \Illuminate\Contracts\Foundation\Application
|
|
*/
|
|
protected static $app;
|
|
|
|
/**
|
|
* The resolved object instances.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected static $resolvedInstance;
|
|
|
|
/**
|
|
* Run a Closure when the facade has been resolved.
|
|
*
|
|
* @param \Closure $callback
|
|
* @return void
|
|
*/
|
|
public static function resolved(Closure $callback)
|
|
{
|
|
$accessor = static::getFacadeAccessor();
|
|
|
|
if (static::$app->resolved($accessor) === true) {
|
|
$callback(static::getFacadeRoot());
|
|
}
|
|
|
|
static::$app->afterResolving($accessor, function ($service) use ($callback) {
|
|
$callback($service);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Convert the facade into a Mockery spy.
|
|
*
|
|
* @return \Mockery\MockInterface
|
|
*/
|
|
public static function spy()
|
|
{
|
|
if (! static::isMock()) {
|
|
$class = static::getMockableClass();
|
|
|
|
return tap($class ? Mockery::spy($class) : Mockery::spy(), function ($spy) {
|
|
static::swap($spy);
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initiate a partial mock on the facade.
|
|
*
|
|
* @return \Mockery\MockInterface
|
|
*/
|
|
public static function partialMock()
|
|
{
|
|
$name = static::getFacadeAccessor();
|
|
|
|
$mock = static::isMock()
|
|
? static::$resolvedInstance[$name]
|
|
: static::createFreshMockInstance();
|
|
|
|
return $mock->makePartial();
|
|
}
|
|
|
|
/**
|
|
* Initiate a mock expectation on the facade.
|
|
*
|
|
* @return \Mockery\Expectation
|
|
*/
|
|
public static function shouldReceive()
|
|
{
|
|
$name = static::getFacadeAccessor();
|
|
|
|
$mock = static::isMock()
|
|
? static::$resolvedInstance[$name]
|
|
: static::createFreshMockInstance();
|
|
|
|
return $mock->shouldReceive(...func_get_args());
|
|
}
|
|
|
|
/**
|
|
* Create a fresh mock instance for the given class.
|
|
*
|
|
* @return \Mockery\MockInterface
|
|
*/
|
|
protected static function createFreshMockInstance()
|
|
{
|
|
return tap(static::createMock(), function ($mock) {
|
|
static::swap($mock);
|
|
|
|
$mock->shouldAllowMockingProtectedMethods();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Create a fresh mock instance for the given class.
|
|
*
|
|
* @return \Mockery\MockInterface
|
|
*/
|
|
protected static function createMock()
|
|
{
|
|
$class = static::getMockableClass();
|
|
|
|
return $class ? Mockery::mock($class) : Mockery::mock();
|
|
}
|
|
|
|
/**
|
|
* Determines whether a mock is set as the instance of the facade.
|
|
*
|
|
* @return bool
|
|
*/
|
|
protected static function isMock()
|
|
{
|
|
$name = static::getFacadeAccessor();
|
|
|
|
return isset(static::$resolvedInstance[$name]) &&
|
|
static::$resolvedInstance[$name] instanceof MockInterface;
|
|
}
|
|
|
|
/**
|
|
* Get the mockable class for the bound instance.
|
|
*
|
|
* @return string|null
|
|
*/
|
|
protected static function getMockableClass()
|
|
{
|
|
if ($root = static::getFacadeRoot()) {
|
|
return get_class($root);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hotswap the underlying instance behind the facade.
|
|
*
|
|
* @param mixed $instance
|
|
* @return void
|
|
*/
|
|
public static function swap($instance)
|
|
{
|
|
static::$resolvedInstance[static::getFacadeAccessor()] = $instance;
|
|
|
|
if (isset(static::$app)) {
|
|
static::$app->instance(static::getFacadeAccessor(), $instance);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the root object behind the facade.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public static function getFacadeRoot()
|
|
{
|
|
return static::resolveFacadeInstance(static::getFacadeAccessor());
|
|
}
|
|
|
|
/**
|
|
* Get the registered name of the component.
|
|
*
|
|
* @return string
|
|
*
|
|
* @throws \RuntimeException
|
|
*/
|
|
protected static function getFacadeAccessor()
|
|
{
|
|
throw new RuntimeException('Facade does not implement getFacadeAccessor method.');
|
|
}
|
|
|
|
/**
|
|
* Resolve the facade root instance from the container.
|
|
*
|
|
* @param object|string $name
|
|
* @return mixed
|
|
*/
|
|
protected static function resolveFacadeInstance($name)
|
|
{
|
|
if (is_object($name)) {
|
|
return $name;
|
|
}
|
|
|
|
if (isset(static::$resolvedInstance[$name])) {
|
|
return static::$resolvedInstance[$name];
|
|
}
|
|
|
|
if (static::$app) {
|
|
return static::$resolvedInstance[$name] = static::$app[$name];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear a resolved facade instance.
|
|
*
|
|
* @param string $name
|
|
* @return void
|
|
*/
|
|
public static function clearResolvedInstance($name)
|
|
{
|
|
unset(static::$resolvedInstance[$name]);
|
|
}
|
|
|
|
/**
|
|
* Clear all of the resolved instances.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function clearResolvedInstances()
|
|
{
|
|
static::$resolvedInstance = [];
|
|
}
|
|
|
|
/**
|
|
* Get the application instance behind the facade.
|
|
*
|
|
* @return \Illuminate\Contracts\Foundation\Application
|
|
*/
|
|
public static function getFacadeApplication()
|
|
{
|
|
return static::$app;
|
|
}
|
|
|
|
/**
|
|
* Set the application instance.
|
|
*
|
|
* @param \Illuminate\Contracts\Foundation\Application $app
|
|
* @return void
|
|
*/
|
|
public static function setFacadeApplication($app)
|
|
{
|
|
static::$app = $app;
|
|
}
|
|
|
|
/**
|
|
* Handle dynamic, static calls to the object.
|
|
*
|
|
* @param string $method
|
|
* @param array $args
|
|
* @return mixed
|
|
*
|
|
* @throws \RuntimeException
|
|
*/
|
|
public static function __callStatic($method, $args)
|
|
{
|
|
$instance = static::getFacadeRoot();
|
|
|
|
if (! $instance) {
|
|
throw new RuntimeException('A facade root has not been set.');
|
|
}
|
|
|
|
return $instance->$method(...$args);
|
|
}
|
|
}
|