diff --git a/core/modules/file/file.services.yml b/core/modules/file/file.services.yml index 03eb7bccf7..037547cb1f 100644 --- a/core/modules/file/file.services.yml +++ b/core/modules/file/file.services.yml @@ -1,6 +1,6 @@ services: file.usage: class: Drupal\file\FileUsage\DatabaseFileUsageBackend - arguments: ['@database', 'file_usage', '@config.factory'] + arguments: ['@config.factory', '@database', 'file_usage'] tags: - { name: backend_overridable } diff --git a/core/modules/file/src/FileUsage/DatabaseFileUsageBackend.php b/core/modules/file/src/FileUsage/DatabaseFileUsageBackend.php index 2b1995437e..7004a59845 100644 --- a/core/modules/file/src/FileUsage/DatabaseFileUsageBackend.php +++ b/core/modules/file/src/FileUsage/DatabaseFileUsageBackend.php @@ -28,18 +28,40 @@ class DatabaseFileUsageBackend extends FileUsageBase { /** * Construct the DatabaseFileUsageBackend. * - * @param \Drupal\Core\Database\Connection $connection + * @param \Drupal\Core\Config\ConfigFactoryInterface|mixed $config_factory + * The config factory. + * @param \Drupal\Core\Database\Connection|mixed $connection * The database connection which will be used to store the file usage * information. - * @param string $table + * @param string|mixed $table * (optional) The table to store file usage info. Defaults to 'file_usage'. - * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * (optional) The config factory. + * + * @todo Remove |mixed from the docblock above and properly type-hint the + * constructor arguments in + * https://www.drupal.org/project/drupal/issues/3070114 when the + * drupal:9.0.x branch is opened. */ - public function __construct(Connection $connection, $table = 'file_usage', ConfigFactoryInterface $config_factory = NULL) { + public function __construct($config_factory, $connection = NULL, $table = 'file_usage') { + + // @todo Remove below conditional when the drupal:9.0.x branch is opened. + // @see https://www.drupal.org/project/drupal/issues/3070114 + if ($config_factory instanceof Connection) { + @trigger_error('Passing the database connection as the first argument to ' . __METHOD__ . ' is deprecated in drupal:8.8.0 and will throw a fatal error in drupal:9.0.0. Pass the config factory first. See https://www.drupal.org/node/3070148', E_USER_DEPRECATED); + $temp = $table; + $table = $connection; + $connection = $config_factory; + $config_factory = $temp; + if (NULL === $table) { + $table = 'file_usage'; + } + if (!$config_factory instanceof ConfigFactoryInterface) { + $config_factory = \Drupal::configFactory(); + } + } + parent::__construct($config_factory); - $this->connection = $connection; + $this->connection = $connection; $this->tableName = $table; } diff --git a/core/modules/file/src/FileUsage/FileUsageBase.php b/core/modules/file/src/FileUsage/FileUsageBase.php index 79e35be0fe..4918b4e481 100644 --- a/core/modules/file/src/FileUsage/FileUsageBase.php +++ b/core/modules/file/src/FileUsage/FileUsageBase.php @@ -21,14 +21,21 @@ abstract class FileUsageBase implements FileUsageInterface { * Creates a FileUsageBase object. * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * (optional) The config factory. Defaults to NULL and will use - * \Drupal::configFactory() instead. + * The config factory. This parameter is required as of drupal:8.4.0 and + * trigger a fatal error if not passed in drupal:9.0.0. + * + * @todo Update the docblock and make $config_factory required in + * https://www.drupal.org/project/drupal/issues/3070114 when the + * drupal:9.0.x branch is opened. */ public function __construct(ConfigFactoryInterface $config_factory = NULL) { + // @todo Remove below conditional when the drupal:9.0.x branch is opened. + // @see https://www.drupal.org/project/drupal/issues/3070114 if (empty($config_factory)) { - @trigger_error('Calling ' . __METHOD__ . ' without the $config_factory parameter is deprecated in drupal:8.4.0 and become required in drupal:9.0.0. See https://www.drupal.org/project/drupal/issues/2801777', E_USER_DEPRECATED); + @trigger_error('Not passing the $config_factory parameter to ' . __METHOD__ . ' is deprecated in drupal:8.4.0 and will trigger a fatal error in drupal:9.0.0. See https://www.drupal.org/project/drupal/issues/2801777', E_USER_DEPRECATED); $config_factory = \Drupal::configFactory(); } + $this->configFactory = $config_factory; } diff --git a/core/modules/file/tests/src/Kernel/FileLegacyTest.php b/core/modules/file/tests/src/Kernel/FileLegacyTest.php index c6249e6b23..6bbf3fc8f8 100644 --- a/core/modules/file/tests/src/Kernel/FileLegacyTest.php +++ b/core/modules/file/tests/src/Kernel/FileLegacyTest.php @@ -77,11 +77,4 @@ public function testEntityLegacyCode() { $this->assertFileNotExists('public://example.txt'); } - /** - * @expectedDeprecation Calling Drupal\file\FileUsage\FileUsageBase::__construct without the $config_factory parameter is deprecated in drupal:8.4.0 and become required in drupal:9.0.0. See https://www.drupal.org/project/drupal/issues/2801777 - */ - public function testConstructorConfigFactoryArgument() { - new \Drupal\file\FileUsage\DatabaseFileUsageBackend(\Drupal::database()); - } - } diff --git a/core/modules/file/tests/src/Unit/LegacyFileTest.php b/core/modules/file/tests/src/Unit/LegacyFileTest.php new file mode 100644 index 0000000000..3da63c614c --- /dev/null +++ b/core/modules/file/tests/src/Unit/LegacyFileTest.php @@ -0,0 +1,101 @@ +configFactory = $this->prophesize(ConfigFactoryInterface::class)->reveal(); + $container = new ContainerBuilder(); + $container->set('config.factory', $this->configFactory); + \Drupal::setContainer($container); + } + + /** + * Tests passing legacy arguments to FileUsageBase::__construct(). + * + * @expectedDeprecation Not passing the $config_factory parameter to Drupal\file\FileUsage\FileUsageBase::__construct is deprecated in drupal:8.4.0 and will trigger a fatal error in drupal:9.0.0. See https://www.drupal.org/project/drupal/issues/2801777 + * + * @throws \ReflectionException + */ + public function testFileUsageBaseConstruct() { + $test_file_usage = new TestFileUsage(); + $reflection = new \ReflectionObject($test_file_usage); + $config = $reflection->getProperty('configFactory'); + $config->setAccessible(TRUE); + $this->assertSame($this->configFactory, $config->getValue($test_file_usage)); + } + + /** + * Tests passing legacy arguments to DatabaseFileUsageBackend::__construct(). + * + * @expectedDeprecation Passing the database connection as the first argument to Drupal\file\FileUsage\DatabaseFileUsageBackend::__construct is deprecated in drupal:8.8.0 and will throw a fatal error in drupal:9.0.0. Pass the config factory first. See https://www.drupal.org/node/3070148 + * + * @throws \ReflectionException + */ + public function testDatabaseFileUsageBackendConstruct() { + $connection = $this->prophesize(Connection::class)->reveal(); + $database_file_usage = new DatabaseFileUsageBackend($connection); + $reflection = new \ReflectionObject($database_file_usage); + $reflection_config = $reflection->getProperty('configFactory'); + $reflection_config->setAccessible(TRUE); + $reflection_connection = $reflection->getProperty('connection'); + $reflection_connection->setAccessible(TRUE); + $reflection_table_name = $reflection->getProperty('tableName'); + $reflection_table_name->setAccessible(TRUE); + $this->assertSame($this->configFactory, $reflection_config->getValue($database_file_usage)); + $this->assertSame($connection, $reflection_connection->getValue($database_file_usage)); + $this->assertSame('file_usage', $reflection_table_name->getValue($database_file_usage)); + } + +} + +/** + * Provides a pass through to the abstract FileUsageBase() constructor. + */ +class TestFileUsage extends FileUsageBase { + + /** + * {@inheritdoc} + */ + public function add(FileInterface $file, $module, $type, $id, $count = 1) { + } + + /** + * {@inheritdoc} + */ + public function delete(FileInterface $file, $module, $type = NULL, $id = NULL, $count = 1) { + } + + /** + * {@inheritdoc} + */ + public function listUsage(FileInterface $file) { + } + +}