%PDF- %PDF-
Direktori : /home/silvzytp/calling_code/vendor/laravel/serializable-closure/src/Serializers/ |
Current File : //home/silvzytp/calling_code/vendor/laravel/serializable-closure/src/Serializers/Native.php |
<?php namespace Laravel\SerializableClosure\Serializers; use Closure; use DateTimeInterface; use Laravel\SerializableClosure\Contracts\Serializable; use Laravel\SerializableClosure\SerializableClosure; use Laravel\SerializableClosure\Support\ClosureScope; use Laravel\SerializableClosure\Support\ClosureStream; use Laravel\SerializableClosure\Support\ReflectionClosure; use Laravel\SerializableClosure\Support\SelfReference; use ReflectionObject; use UnitEnum; class Native implements Serializable { /** * Transform the use variables before serialization. * * @var \Closure|null */ public static $transformUseVariables; /** * Resolve the use variables after unserialization. * * @var \Closure|null */ public static $resolveUseVariables; /** * The closure to be serialized/unserialized. * * @var \Closure */ protected $closure; /** * The closure's reflection. * * @var \Laravel\SerializableClosure\Support\ReflectionClosure|null */ protected $reflector; /** * The closure's code. * * @var array|null */ protected $code; /** * The closure's reference. * * @var string */ protected $reference; /** * The closure's scope. * * @var \Laravel\SerializableClosure\Support\ClosureScope|null */ protected $scope; /** * The "key" that marks an array as recursive. */ const ARRAY_RECURSIVE_KEY = 'LARAVEL_SERIALIZABLE_RECURSIVE_KEY'; /** * Creates a new serializable closure instance. * * @param \Closure $closure * @return void */ public function __construct(Closure $closure) { $this->closure = $closure; } /** * Resolve the closure with the given arguments. * * @return mixed */ public function __invoke() { return call_user_func_array($this->closure, func_get_args()); } /** * Gets the closure. * * @return \Closure */ public function getClosure() { return $this->closure; } /** * Get the serializable representation of the closure. * * @return array */ public function __serialize() { if ($this->scope === null) { $this->scope = new ClosureScope(); $this->scope->toSerialize++; } $this->scope->serializations++; $scope = $object = null; $reflector = $this->getReflector(); if ($reflector->isBindingRequired()) { $object = $reflector->getClosureThis(); static::wrapClosures($object, $this->scope); } if ($scope = $reflector->getClosureScopeClass()) { $scope = $scope->name; } $this->reference = spl_object_hash($this->closure); $this->scope[$this->closure] = $this; $use = $reflector->getUseVariables(); if (static::$transformUseVariables) { $use = call_user_func(static::$transformUseVariables, $reflector->getUseVariables()); } $code = $reflector->getCode(); $this->mapByReference($use); $data = [ 'use' => $use, 'function' => $code, 'scope' => $scope, 'this' => $object, 'self' => $this->reference, ]; if (! --$this->scope->serializations && ! --$this->scope->toSerialize) { $this->scope = null; } return $data; } /** * Restore the closure after serialization. * * @param array $data * @return void */ public function __unserialize($data) { ClosureStream::register(); $this->code = $data; unset($data); $this->code['objects'] = []; if ($this->code['use']) { $this->scope = new ClosureScope(); if (static::$resolveUseVariables) { $this->code['use'] = call_user_func(static::$resolveUseVariables, $this->code['use']); } $this->mapPointers($this->code['use']); extract($this->code['use'], EXTR_OVERWRITE | EXTR_REFS); $this->scope = null; } $this->closure = include ClosureStream::STREAM_PROTO.'://'.$this->code['function']; if ($this->code['this'] === $this) { $this->code['this'] = null; } $this->closure = $this->closure->bindTo($this->code['this'], $this->code['scope']); if (! empty($this->code['objects'])) { foreach ($this->code['objects'] as $item) { $item['property']->setValue($item['instance'], $item['object']->getClosure()); } } $this->code = $this->code['function']; } /** * Ensures the given closures are serializable. * * @param mixed $data * @param \Laravel\SerializableClosure\Support\ClosureScope $storage * @return void */ public static function wrapClosures(&$data, $storage) { if ($data instanceof Closure) { $data = new static($data); } elseif (is_array($data)) { if (isset($data[self::ARRAY_RECURSIVE_KEY])) { return; } $data[self::ARRAY_RECURSIVE_KEY] = true; foreach ($data as $key => &$value) { if ($key === self::ARRAY_RECURSIVE_KEY) { continue; } static::wrapClosures($value, $storage); } unset($value); unset($data[self::ARRAY_RECURSIVE_KEY]); } elseif ($data instanceof \stdClass) { if (isset($storage[$data])) { $data = $storage[$data]; return; } $data = $storage[$data] = clone $data; foreach ($data as &$value) { static::wrapClosures($value, $storage); } unset($value); } elseif (is_object($data) && ! $data instanceof static && ! $data instanceof UnitEnum) { if (isset($storage[$data])) { $data = $storage[$data]; return; } $instance = $data; $reflection = new ReflectionObject($instance); if (! $reflection->isUserDefined()) { $storage[$instance] = $data; return; } $storage[$instance] = $data = $reflection->newInstanceWithoutConstructor(); do { if (! $reflection->isUserDefined()) { break; } foreach ($reflection->getProperties() as $property) { if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined()) { continue; } $property->setAccessible(true); if (PHP_VERSION >= 7.4 && ! $property->isInitialized($instance)) { continue; } $value = $property->getValue($instance); if (is_array($value) || is_object($value)) { static::wrapClosures($value, $storage); } $property->setValue($data, $value); } } while ($reflection = $reflection->getParentClass()); } } /** * Gets the closure's reflector. * * @return \Laravel\SerializableClosure\Support\ReflectionClosure */ public function getReflector() { if ($this->reflector === null) { $this->code = null; $this->reflector = new ReflectionClosure($this->closure); } return $this->reflector; } /** * Internal method used to map closure pointers. * * @param mixed $data * @return void */ protected function mapPointers(&$data) { $scope = $this->scope; if ($data instanceof static) { $data = &$data->closure; } elseif (is_array($data)) { if (isset($data[self::ARRAY_RECURSIVE_KEY])) { return; } $data[self::ARRAY_RECURSIVE_KEY] = true; foreach ($data as $key => &$value) { if ($key === self::ARRAY_RECURSIVE_KEY) { continue; } elseif ($value instanceof static) { $data[$key] = &$value->closure; } elseif ($value instanceof SelfReference && $value->hash === $this->code['self']) { $data[$key] = &$this->closure; } else { $this->mapPointers($value); } } unset($value); unset($data[self::ARRAY_RECURSIVE_KEY]); } elseif ($data instanceof \stdClass) { if (isset($scope[$data])) { return; } $scope[$data] = true; foreach ($data as $key => &$value) { if ($value instanceof SelfReference && $value->hash === $this->code['self']) { $data->{$key} = &$this->closure; } elseif (is_array($value) || is_object($value)) { $this->mapPointers($value); } } unset($value); } elseif (is_object($data) && ! ($data instanceof Closure)) { if (isset($scope[$data])) { return; } $scope[$data] = true; $reflection = new ReflectionObject($data); do { if (! $reflection->isUserDefined()) { break; } foreach ($reflection->getProperties() as $property) { if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined()) { continue; } $property->setAccessible(true); if (PHP_VERSION >= 7.4 && ! $property->isInitialized($data)) { continue; } $item = $property->getValue($data); if ($item instanceof SerializableClosure || ($item instanceof SelfReference && $item->hash === $this->code['self'])) { $this->code['objects'][] = [ 'instance' => $data, 'property' => $property, 'object' => $item instanceof SelfReference ? $this : $item, ]; } elseif (is_array($item) || is_object($item)) { $this->mapPointers($item); $property->setValue($data, $item); } } } while ($reflection = $reflection->getParentClass()); } } /** * Internal method used to map closures by reference. * * @param mixed $data * @return void */ protected function mapByReference(&$data) { if ($data instanceof Closure) { if ($data === $this->closure) { $data = new SelfReference($this->reference); return; } if (isset($this->scope[$data])) { $data = $this->scope[$data]; return; } $instance = new static($data); $instance->scope = $this->scope; $data = $this->scope[$data] = $instance; } elseif (is_array($data)) { if (isset($data[self::ARRAY_RECURSIVE_KEY])) { return; } $data[self::ARRAY_RECURSIVE_KEY] = true; foreach ($data as $key => &$value) { if ($key === self::ARRAY_RECURSIVE_KEY) { continue; } $this->mapByReference($value); } unset($value); unset($data[self::ARRAY_RECURSIVE_KEY]); } elseif ($data instanceof \stdClass) { if (isset($this->scope[$data])) { $data = $this->scope[$data]; return; } $instance = $data; $this->scope[$instance] = $data = clone $data; foreach ($data as &$value) { $this->mapByReference($value); } unset($value); } elseif (is_object($data) && ! $data instanceof SerializableClosure) { if (isset($this->scope[$data])) { $data = $this->scope[$data]; return; } $instance = $data; if ($data instanceof DateTimeInterface) { $this->scope[$instance] = $data; return; } if ($data instanceof UnitEnum) { $this->scope[$instance] = $data; return; } $reflection = new ReflectionObject($data); if (! $reflection->isUserDefined()) { $this->scope[$instance] = $data; return; } $this->scope[$instance] = $data = $reflection->newInstanceWithoutConstructor(); do { if (! $reflection->isUserDefined()) { break; } foreach ($reflection->getProperties() as $property) { if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined()) { continue; } $property->setAccessible(true); if (PHP_VERSION >= 7.4 && ! $property->isInitialized($instance)) { continue; } $value = $property->getValue($instance); if (is_array($value) || is_object($value)) { $this->mapByReference($value); } $property->setValue($data, $value); } } while ($reflection = $reflection->getParentClass()); } } }