Skip to content
Snippets Groups Projects
Commit 12933dcb authored by Youri van Koppen's avatar Youri van Koppen
Browse files

Issue #3390530 by MegaChriz, sarwan_verma, jnicola, HeikkiY, maskedjellybean:...

Issue #3390530 by MegaChriz, sarwan_verma, jnicola, HeikkiY, maskedjellybean: Fixed Call to a member function unlink() on null in Drupal\feeds\Result\HttpFetcherResult->cleanUp().
parent 01ad8b07
No related branches found
No related tags found
1 merge request!147Resolve #3390530 "Fix"
Pipeline #64673 failed
......@@ -10,7 +10,9 @@ use Drupal\Core\File\FileSystemInterface;
*/
class HttpFetcherResult extends FetcherResult implements HttpFetcherResultInterface {
use DependencySerializationTrait;
use DependencySerializationTrait {
__wakeup as traitWakeUp;
}
/**
* The HTTP headers.
......@@ -45,6 +47,23 @@ class HttpFetcherResult extends FetcherResult implements HttpFetcherResultInterf
$this->fileSystem = $file_system;
}
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function __wakeup() {
$this->traitWakeUp();
// In Feeds 8.x-3.0-beta3 and earlier, the $fileSystem property did not
// exist in this class yet, but when updating to Feeds 8.x-3.0-beta4 or
// later, it is possible that serialized objects from an older version of
// this class still exist. Therefore, we need to ensure that the $fileSystem
// property gets set.
if (!isset($this->fileSystem)) {
$this->fileSystem = \Drupal::service('file_system');
}
}
/**
* {@inheritdoc}
*/
......
......@@ -45,6 +45,24 @@ trait FeedsReflectionTrait {
$property->setValue($object, $value);
}
/**
* Returns the value of a protected property.
*
* @param object $object
* The object on which to get a value from.
* @param string $property_name
* The property whose value to get.
*
* @return mixed
* The value of the property.
*/
protected function getProtectedProperty($object, $property_name) {
$ref_object = new ReflectionObject($object);
$property = $ref_object->getProperty($property_name);
$property->setAccessible(TRUE);
return $property->getValue($object);
}
/**
* Returns a dynamically created closure for the object's method.
*
......
<?php
namespace Drupal\Tests\feeds\Unit\Result;
use Drupal\Component\DependencyInjection\ReverseContainer;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\File\FileSystemInterface;
use Drupal\feeds\Result\HttpFetcherResult;
use Drupal\Tests\feeds\Unit\FeedsUnitTestCase;
/**
* @coversDefaultClass \Drupal\feeds\Result\HttpFetcherResult
* @group feeds
*/
class HttpFetcherResultTest extends FeedsUnitTestCase {
/**
* {@inheritdoc}
*/
public function setUp(): void {
parent::setUp();
// Set a mock for the file_system service.
$file_system = $this->prophesize(FileSystemInterface::class);
$container = new ContainerBuilder();
$container->set(ReverseContainer::class, new ReverseContainer($container));
$container->set('file_system', $file_system->reveal());
\Drupal::setContainer($container);
}
/**
* Tests unserializing.
*/
public function testUnserialize() {
$result = new HttpFetcherResult('public://foo', []);
// Serialize and unserialize it again.
$serialized = serialize($result);
$unserialized = unserialize($serialized);
// Call cleanUp(), which uses the file_system service.
$unserialized->cleanUp();
// And assert that the property $fileSystem is still set.
$this->assertInstanceof(FileSystemInterface::class, $this->getProtectedProperty($unserialized, 'fileSystem'));
}
/**
* Tests unserializing without a file_system service.
*
* It is possible that there exists a HttpFetcherResult object that was
* serialized before the $file_system property was added to the class.
*/
public function testUnserializeWithoutFileSystemService() {
// Create an instance of HttpFetcherResult without calling the constructor.
$class = new \ReflectionClass(HttpFetcherResult::class);
$result = $class->newInstanceWithoutConstructor();
// Set some properties.
$this->setProtectedProperty($result, 'filePath', 'public://foo');
$this->setProtectedProperty($result, 'headers', []);
// Serialize and unserialize it again.
$serialized = serialize($result);
$unserialized = unserialize($serialized);
// Call cleanUp(), which uses the file_system service.
$unserialized->cleanUp();
// And assert that the property $fileSystem is now set.
$this->assertInstanceof(FileSystemInterface::class, $this->getProtectedProperty($unserialized, 'fileSystem'));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment