Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"icewind/streams": "^0.7.8",
"justinrainbow/json-schema": "^6.10",
"kornrunner/blurhash": "^1.2",
"laravel/serializable-closure": "^2.0.4",
"laravel/serializable-closure": "^2.0.15",
"mexitek/phpcolors": "^1.0",
"microsoft/azure-storage-blob": "^1.5.4",
"mlocati/ip-lib": "^1.22",
Expand Down
18 changes: 9 additions & 9 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -1358,7 +1358,6 @@
'Laravel\\SerializableClosure\\Contracts\\Signer' => $vendorDir . '/laravel/serializable-closure/src/Contracts/Signer.php',
'Laravel\\SerializableClosure\\Exceptions\\InvalidSignatureException' => $vendorDir . '/laravel/serializable-closure/src/Exceptions/InvalidSignatureException.php',
'Laravel\\SerializableClosure\\Exceptions\\MissingSecretKeyException' => $vendorDir . '/laravel/serializable-closure/src/Exceptions/MissingSecretKeyException.php',
'Laravel\\SerializableClosure\\Exceptions\\PhpVersionNotSupportedException' => $vendorDir . '/laravel/serializable-closure/src/Exceptions/PhpVersionNotSupportedException.php',
'Laravel\\SerializableClosure\\SerializableClosure' => $vendorDir . '/laravel/serializable-closure/src/SerializableClosure.php',
'Laravel\\SerializableClosure\\Serializers\\Native' => $vendorDir . '/laravel/serializable-closure/src/Serializers/Native.php',
'Laravel\\SerializableClosure\\Serializers\\Signed' => $vendorDir . '/laravel/serializable-closure/src/Serializers/Signed.php',
Expand Down
1 change: 0 additions & 1 deletion composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -1913,7 +1913,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Laravel\\SerializableClosure\\Contracts\\Signer' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Contracts/Signer.php',
'Laravel\\SerializableClosure\\Exceptions\\InvalidSignatureException' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Exceptions/InvalidSignatureException.php',
'Laravel\\SerializableClosure\\Exceptions\\MissingSecretKeyException' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Exceptions/MissingSecretKeyException.php',
'Laravel\\SerializableClosure\\Exceptions\\PhpVersionNotSupportedException' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Exceptions/PhpVersionNotSupportedException.php',
'Laravel\\SerializableClosure\\SerializableClosure' => __DIR__ . '/..' . '/laravel/serializable-closure/src/SerializableClosure.php',
'Laravel\\SerializableClosure\\Serializers\\Native' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Serializers/Native.php',
'Laravel\\SerializableClosure\\Serializers\\Signed' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Serializers/Signed.php',
Expand Down
18 changes: 9 additions & 9 deletions composer/installed.json
Original file line number Diff line number Diff line change
Expand Up @@ -1847,30 +1847,30 @@
},
{
"name": "laravel/serializable-closure",
"version": "v2.0.4",
"version_normalized": "2.0.4.0",
"version": "v2.0.15",
"version_normalized": "2.0.15.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/serializable-closure.git",
"reference": "b352cf0534aa1ae6b4d825d1e762e35d43f8a841"
"reference": "dccd8bcb851bb03fcc005df650b708b57cc52661"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b352cf0534aa1ae6b4d825d1e762e35d43f8a841",
"reference": "b352cf0534aa1ae6b4d825d1e762e35d43f8a841",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/dccd8bcb851bb03fcc005df650b708b57cc52661",
"reference": "dccd8bcb851bb03fcc005df650b708b57cc52661",
"shasum": ""
},
"require": {
"php": "^8.1"
},
"require-dev": {
"illuminate/support": "^10.0|^11.0|^12.0",
"illuminate/support": "^10.0|^11.0|^12.0|^13.0",
"nesbot/carbon": "^2.67|^3.0",
"pestphp/pest": "^2.36|^3.0",
"pestphp/pest": "^2.36|^3.0|^4.0",
"phpstan/phpstan": "^2.0",
"symfony/var-dumper": "^6.2.0|^7.0.0"
"symfony/var-dumper": "^6.2.0|^7.0.0|^8.0.0"
},
"time": "2025-03-19T13:51:03+00:00",
"time": "2026-07-21T16:49:22+00:00",
"type": "library",
"extra": {
"branch-alias": {
Expand Down
6 changes: 3 additions & 3 deletions composer/installed.php
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,9 @@
'dev_requirement' => false,
),
'laravel/serializable-closure' => array(
'pretty_version' => 'v2.0.4',
'version' => '2.0.4.0',
'reference' => 'b352cf0534aa1ae6b4d825d1e762e35d43f8a841',
'pretty_version' => 'v2.0.15',
'version' => '2.0.15.0',
'reference' => 'dccd8bcb851bb03fcc005df650b708b57cc52661',
'type' => 'library',
'install_path' => __DIR__ . '/../laravel/serializable-closure',
'aliases' => array(),
Expand Down

This file was deleted.

4 changes: 2 additions & 2 deletions laravel/serializable-closure/src/SerializableClosure.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static function setSecretKey($secret)
}

/**
* Sets the serializable closure secret key.
* Sets the transformer that should be used when serializing use variables.
*
* @param \Closure|null $transformer
* @return void
Expand All @@ -85,7 +85,7 @@ public static function transformUseVariablesUsing($transformer)
}

/**
* Sets the serializable closure secret key.
* Sets the resolver that should be used when unserializing use variables.
*
* @param \Closure|null $resolver
* @return void
Expand Down
114 changes: 96 additions & 18 deletions laravel/serializable-closure/src/Serializers/Native.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@ public function __serialize()
}

if ($scope = $reflector->getClosureScopeClass()) {
$scope = $scope->name;
if (! $scope->isAnonymous() || $reflector->isBindingRequired() || $reflector->isScopeRequired()) {
$scope = $scope->name;
} else {
$scope = null;
}
}

$this->reference = spl_object_hash($this->closure);
Expand Down Expand Up @@ -197,7 +201,13 @@ public function __unserialize($data)

if (! empty($this->code['objects'])) {
foreach ($this->code['objects'] as $item) {
$item['property']->setValue($item['instance'], $item['object']->getClosure());
static::setPropertyValue(
$item['property'],
$item['instance'],
$item['object'] instanceof SerializableClosure || $item['object'] instanceof UnsignedSerializableClosure
? $item['object']
: $item['object']->getClosure()
);
}
}

Expand Down Expand Up @@ -269,23 +279,27 @@ public static function wrapClosures(&$data, $storage)
}

foreach ($reflection->getProperties() as $property) {
if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined()) {
if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined() || static::isVirtualProperty($property)) {
continue;
}

$property->setAccessible(true);

if (! $property->isInitialized($instance)) {
continue;
}

$value = $property->getValue($instance);
$value = static::getPropertyValue($property, $instance);

if (static::isClosureTypedProperty($property)) {
static::setPropertyValue($property, $data, $value);

continue;
}

if (is_array($value) || is_object($value)) {
static::wrapClosures($value, $storage);
}

$property->setValue($data, $value);
static::setPropertyValue($property, $data, $value);
}
} while ($reflection = $reflection->getParentClass());
}
Expand Down Expand Up @@ -314,6 +328,10 @@ public function getReflector()
*/
protected function mapPointers(&$data)
{
if ($data instanceof SerializableClosure || $data instanceof UnsignedSerializableClosure) {
return;
}

$scope = $this->scope;

if ($data instanceof static) {
Expand Down Expand Up @@ -349,6 +367,8 @@ protected function mapPointers(&$data)
foreach ($data as $key => &$value) {
if ($value instanceof SelfReference && $value->hash === $this->code['self']) {
$data->{$key} = &$this->closure;
} elseif ($value instanceof static) {
$data->{$key} = &$value->closure;
} elseif (is_array($value) || is_object($value)) {
$this->mapPointers($value);
}
Expand All @@ -369,27 +389,27 @@ protected function mapPointers(&$data)
}

foreach ($reflection->getProperties() as $property) {
if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined()) {
if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined() || static::isVirtualProperty($property)) {
continue;
}

$property->setAccessible(true);

if (! $property->isInitialized($data) || $property->isReadOnly()) {
continue;
}

$item = $property->getValue($data);
$item = static::getPropertyValue($property, $data);

if ($item instanceof SerializableClosure || $item instanceof UnsignedSerializableClosure || ($item instanceof SelfReference && $item->hash === $this->code['self'])) {
$this->code['objects'][] = [
'instance' => $data,
'property' => $property,
'object' => $item instanceof SelfReference ? $this : $item,
];
} elseif ($item instanceof static) {
static::setPropertyValue($property, $data, $item->closure);
} elseif (is_array($item) || is_object($item)) {
$this->mapPointers($item);
$property->setValue($data, $item);
static::setPropertyValue($property, $data, $item);
}
}
} while ($reflection = $reflection->getParentClass());
Expand Down Expand Up @@ -491,36 +511,94 @@ protected function mapByReference(&$data)
}

foreach ($reflection->getProperties() as $property) {
if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined() || $this->isVirtualProperty($property)) {
if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined() || static::isVirtualProperty($property)) {
continue;
}

$property->setAccessible(true);

if (! $property->isInitialized($instance) || ($property->isReadOnly() && $property->class !== $reflection->name)) {
continue;
}

$value = $property->getValue($instance);
$value = static::getPropertyValue($property, $instance);

if (static::isClosureTypedProperty($property)) {
static::setPropertyValue($property, $data, $value);

continue;
}

if (is_array($value) || is_object($value)) {
$this->mapByReference($value);
}

$property->setValue($data, $value);
static::setPropertyValue($property, $data, $value);
}
} while ($reflection = $reflection->getParentClass());
}
}

/**
* Get the value of a property, bypassing hooks on PHP 8.4+.
*
* @param \ReflectionProperty $property
* @param object $object
* @return mixed
*/
protected static function getPropertyValue(ReflectionProperty $property, object $object): mixed
{
return PHP_VERSION_ID >= 80400
? $property->getRawValue($object)
: $property->getValue($object);
}

/**
* Set the value of a property, bypassing hooks on PHP 8.4+.
*
* @param \ReflectionProperty $property
* @param object $object
* @param mixed $value
* @return void
*/
protected static function setPropertyValue(ReflectionProperty $property, object $object, mixed $value): void
{
PHP_VERSION_ID >= 80400
? $property->setRawValue($object, $value)
: $property->setValue($object, $value);
}

/**
* Determine is virtual property.
*
* @param \ReflectionProperty $property
* @return bool
*/
protected function isVirtualProperty(ReflectionProperty $property): bool
protected static function isVirtualProperty(ReflectionProperty $property): bool
{
return method_exists($property, 'isVirtual') && $property->isVirtual();
}

/**
* Determine if property is typed as Closure.
*
* @param \ReflectionProperty $property
* @return bool
*/
protected static function isClosureTypedProperty(ReflectionProperty $property): bool
{
$type = $property->getType();

if ($type instanceof \ReflectionNamedType) {
return $type->getName() === 'Closure';
}

if ($type instanceof \ReflectionUnionType || $type instanceof \ReflectionIntersectionType) {
foreach ($type->getTypes() as $t) {
if ($t instanceof \ReflectionNamedType && $t->getName() === 'Closure') {
return true;
}
}
}

return false;
}
}
Loading