From 16552b02a3d1d66d224bd5888408017a5d93bf58 Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Thu, 11 Jan 2024 21:45:16 +0000 Subject: [PATCH] Issue #3328457 by xjm, dimitriskr: Replace most substr($a, $i) where $i is negative with str_ends_with() --- composer/Plugin/Scaffold/ManageGitIgnore.php | 2 +- core/includes/errors.inc | 2 +- .../PhpStorage/MTimeProtectedFastFileStorage.php | 2 +- core/lib/Drupal/Core/Command/DbImportCommand.php | 2 +- core/lib/Drupal/Core/Config/Entity/Query/QueryFactory.php | 2 +- core/lib/Drupal/Core/Database/Connection.php | 2 +- .../Drupal/Core/DependencyInjection/YamlFileLoader.php | 2 +- .../Core/Entity/EntityLastInstalledSchemaRepository.php | 2 +- core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php | 2 +- .../Discovery/RecursiveExtensionFilterIterator.php | 4 ++-- core/lib/Drupal/Core/Extension/ExtensionVersion.php | 2 +- core/lib/Drupal/Core/File/FileSystem.php | 4 ++-- core/lib/Drupal/Core/FileTransfer/FileTransfer.php | 2 +- core/lib/Drupal/Core/Render/Element/ImageButton.php | 2 +- core/lib/Drupal/Core/Routing/UrlGenerator.php | 4 ++-- core/lib/Drupal/Core/Test/TestDiscovery.php | 8 ++++---- .../lib/Drupal/Core/TypedData/DataReferenceDefinition.php | 2 +- core/modules/file/src/Upload/FileUploadHandler.php | 2 +- core/modules/filter/src/Plugin/Filter/FilterHtml.php | 4 ++-- core/modules/jsonapi/src/Routing/Routes.php | 2 +- .../migrate/src/Plugin/migrate/process/FileCopy.php | 2 +- .../tests/src/Kernel/MigrateDrupalTestBase.php | 2 +- .../tests/src/Functional/MigrateUpgradeTestBase.php | 2 +- .../Composer/Template/ComposerProjectTemplatesTest.php | 2 +- .../Drupal/FunctionalTests/Update/UpdatePathTestBase.php | 2 +- .../PhpStorage/MTimeProtectedFileStorageBase.php | 2 +- 26 files changed, 33 insertions(+), 33 deletions(-) diff --git a/composer/Plugin/Scaffold/ManageGitIgnore.php b/composer/Plugin/Scaffold/ManageGitIgnore.php index 078cb3357862..6f2eb09fb009 100644 --- a/composer/Plugin/Scaffold/ManageGitIgnore.php +++ b/composer/Plugin/Scaffold/ManageGitIgnore.php @@ -115,7 +115,7 @@ protected function addToGitIgnore($dir, array $entries) { // Appending to existing .gitignore files. if (file_exists($git_ignore_path)) { $contents = file_get_contents($git_ignore_path); - if (!empty($contents) && substr($contents, -1) != "\n") { + if (!empty($contents) && !str_ends_with($contents, "\n")) { $contents .= "\n"; } } diff --git a/core/includes/errors.inc b/core/includes/errors.inc index 9820f9fe2ac6..6ec930dd3460 100644 --- a/core/includes/errors.inc +++ b/core/includes/errors.inc @@ -67,7 +67,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line) { // As __toString() methods must not throw exceptions (recoverable errors) // in PHP, we allow them to trigger a fatal error by emitting a user error // using trigger_error(). - $to_string = $error_level == E_USER_ERROR && substr($caller['function'], -strlen('__toString()')) == '__toString()'; + $to_string = $error_level == E_USER_ERROR && str_ends_with($caller['function'], '__toString()'); _drupal_log_error([ '%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error', // The standard PHP error handler considers that the error messages diff --git a/core/lib/Drupal/Component/PhpStorage/MTimeProtectedFastFileStorage.php b/core/lib/Drupal/Component/PhpStorage/MTimeProtectedFastFileStorage.php index be287f99bfc8..415079376fbf 100644 --- a/core/lib/Drupal/Component/PhpStorage/MTimeProtectedFastFileStorage.php +++ b/core/lib/Drupal/Component/PhpStorage/MTimeProtectedFastFileStorage.php @@ -200,7 +200,7 @@ protected function getContainingDirectoryFullPath($name) { // file. Thus, when switching between MTimeProtectedFastFileStorage and // FileStorage, the subdirectory or the file cannot be created in case the // other file type exists already. - if (substr($name, -4) === '.php') { + if (str_ends_with($name, '.php')) { $name = substr($name, 0, -4); } return $this->directory . '/' . str_replace('/', '#', $name); diff --git a/core/lib/Drupal/Core/Command/DbImportCommand.php b/core/lib/Drupal/Core/Command/DbImportCommand.php index cf461df7346f..6da8b5739d1d 100644 --- a/core/lib/Drupal/Core/Command/DbImportCommand.php +++ b/core/lib/Drupal/Core/Command/DbImportCommand.php @@ -56,7 +56,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int protected function runScript(Connection $connection, $script) { $old_key = Database::setActiveConnection($connection->getKey()); - if (substr($script, -3) == '.gz') { + if (str_ends_with($script, '.gz')) { $script = "compress.zlib://$script"; } try { diff --git a/core/lib/Drupal/Core/Config/Entity/Query/QueryFactory.php b/core/lib/Drupal/Core/Config/Entity/Query/QueryFactory.php index 3322287c6e28..064e5b4e9f57 100644 --- a/core/lib/Drupal/Core/Config/Entity/Query/QueryFactory.php +++ b/core/lib/Drupal/Core/Config/Entity/Query/QueryFactory.php @@ -162,7 +162,7 @@ protected function deleteConfigKeyStore(ConfigEntityTypeInterface $entity_type, * you cannot do fast lookups against this. */ protected function getKeys(Config $config, $key, $get_method, ConfigEntityTypeInterface $entity_type) { - if (substr($key, -1) == '*') { + if (str_ends_with($key, '*')) { throw new InvalidLookupKeyException(strtr('%entity_type lookup key %key ends with a wildcard this can not be used as a lookup', ['%entity_type' => $entity_type->id(), '%key' => $key])); } $parts = explode('.*', $key); diff --git a/core/lib/Drupal/Core/Database/Connection.php b/core/lib/Drupal/Core/Database/Connection.php index cdaf0d19ddd5..9f98b00a2785 100644 --- a/core/lib/Drupal/Core/Database/Connection.php +++ b/core/lib/Drupal/Core/Database/Connection.php @@ -886,7 +886,7 @@ protected function expandArguments(&$query, &$args) { // If the placeholder indicated the value to use is an array, we need to // expand it out into a comma-delimited set of placeholders. foreach ($args as $key => $data) { - $is_bracket_placeholder = substr($key, -2) === '[]'; + $is_bracket_placeholder = str_ends_with($key, '[]'); $is_array_data = is_array($data); if ($is_bracket_placeholder && !$is_array_data) { throw new \InvalidArgumentException('Placeholders with a trailing [] can only be expanded with an array of values.'); diff --git a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php index f42b6115f8ae..d165ace48a80 100644 --- a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php +++ b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php @@ -484,7 +484,7 @@ private function resolveServices($value) $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; } - if ('=' === substr($value, -1)) { + if (str_ends_with($value, '=')) { $value = substr($value, 0, -1); } diff --git a/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepository.php b/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepository.php index 1b3c096126ce..9f75e2d9aa9f 100644 --- a/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepository.php +++ b/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepository.php @@ -69,7 +69,7 @@ public function getLastInstalledDefinitions() { // Filter out field storage definitions. $filtered_keys = array_filter(array_keys($all_definitions), function ($key) { - return substr($key, -12) === '.entity_type'; + return str_ends_with($key, '.entity_type'); }); $entity_type_definitions = array_intersect_key($all_definitions, array_flip($filtered_keys)); diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php b/core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php index 3e3cb1e62dc7..fd257ab69390 100644 --- a/core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php +++ b/core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php @@ -154,7 +154,7 @@ protected function finish() { public function createSqlAlias($field, $sql_field) { $alias = str_replace('.', '_', $sql_field); // If the alias contains of field_*_value remove the _value at the end. - if (str_starts_with($alias, 'field_') && substr($field, -6) !== '_value' && substr($alias, -6) === '_value') { + if (str_starts_with($alias, 'field_') && !str_ends_with($field, '_value') && str_ends_with($alias, '_value')) { $alias = substr($alias, 0, -6); } return $alias; diff --git a/core/lib/Drupal/Core/Extension/Discovery/RecursiveExtensionFilterIterator.php b/core/lib/Drupal/Core/Extension/Discovery/RecursiveExtensionFilterIterator.php index af8d2d464bfd..f4964c94c38c 100644 --- a/core/lib/Drupal/Core/Extension/Discovery/RecursiveExtensionFilterIterator.php +++ b/core/lib/Drupal/Core/Extension/Discovery/RecursiveExtensionFilterIterator.php @@ -156,14 +156,14 @@ public function accept() { // config module to be overridden/replaced in a profile/site directory // (whereas it must be located directly in a modules directory). if ($name == 'config') { - return substr($this->current()->getPathname(), -14) == 'modules/config'; + return str_ends_with($this->current()->getPathname(), 'modules/config'); } // Accept the directory unless the folder is skipped. return !in_array($name, $this->skippedFolders, TRUE); } else { // Only accept extension info files. - return substr($name, -9) == '.info.yml'; + return str_ends_with($name, '.info.yml'); } } diff --git a/core/lib/Drupal/Core/Extension/ExtensionVersion.php b/core/lib/Drupal/Core/Extension/ExtensionVersion.php index a5c064b49f27..589774cfec3f 100644 --- a/core/lib/Drupal/Core/Extension/ExtensionVersion.php +++ b/core/lib/Drupal/Core/Extension/ExtensionVersion.php @@ -119,7 +119,7 @@ private function __construct(string $major_version, ?string $minor_version, ?str * The ExtensionVersion instance. */ public static function createFromSupportBranch(string $branch): ExtensionVersion { - if (substr($branch, -1) !== '.') { + if (!str_ends_with($branch, '.')) { throw new \UnexpectedValueException("Invalid support branch: $branch"); } return static::createFromVersionString($branch . '0'); diff --git a/core/lib/Drupal/Core/File/FileSystem.php b/core/lib/Drupal/Core/File/FileSystem.php index 9d1e66b4bd4b..f88ba9d8f54c 100644 --- a/core/lib/Drupal/Core/File/FileSystem.php +++ b/core/lib/Drupal/Core/File/FileSystem.php @@ -596,7 +596,7 @@ public function createFilename($basename, $directory) { } // A URI or path may already have a trailing slash or look like "public://". - if (substr($directory, -1) == '/') { + if (str_ends_with($directory, '/')) { $separator = ''; } else { @@ -711,7 +711,7 @@ protected function doScanDirectory($dir, $mask, array $options = [], $depth = 0) while (FALSE !== ($filename = readdir($handle))) { // Skip this file if it matches the nomask or starts with a dot. if ($filename[0] != '.' && !(preg_match($options['nomask'], $filename))) { - if (substr($dir, -1) == '/') { + if (str_ends_with($dir, '/')) { $uri = "$dir$filename"; } else { diff --git a/core/lib/Drupal/Core/FileTransfer/FileTransfer.php b/core/lib/Drupal/Core/FileTransfer/FileTransfer.php index 2724b0d792ac..f22cfde50328 100644 --- a/core/lib/Drupal/Core/FileTransfer/FileTransfer.php +++ b/core/lib/Drupal/Core/FileTransfer/FileTransfer.php @@ -312,7 +312,7 @@ final protected function fixRemotePath($path, $strip_chroot = TRUE) { public function sanitizePath($path) { // Windows path sanitization. $path = str_replace('\\', '/', $path); - if (substr($path, -1) == '/') { + if (str_ends_with($path, '/')) { $path = substr($path, 0, -1); } return $path; diff --git a/core/lib/Drupal/Core/Render/Element/ImageButton.php b/core/lib/Drupal/Core/Render/Element/ImageButton.php index 6f345ece40b7..7289cadafc81 100644 --- a/core/lib/Drupal/Core/Render/Element/ImageButton.php +++ b/core/lib/Drupal/Core/Render/Element/ImageButton.php @@ -46,7 +46,7 @@ public static function valueCallback(&$element, $input, FormStateInterface $form $input = $form_state->getUserInput(); foreach (explode('[', $element['#name']) as $element_name) { // chop off the ] that may exist. - if (substr($element_name, -1) == ']') { + if (str_ends_with($element_name, ']')) { $element_name = substr($element_name, 0, -1); } diff --git a/core/lib/Drupal/Core/Routing/UrlGenerator.php b/core/lib/Drupal/Core/Routing/UrlGenerator.php index e41fe77d407b..d7d0a2032170 100644 --- a/core/lib/Drupal/Core/Routing/UrlGenerator.php +++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php @@ -321,10 +321,10 @@ public function generateFromRoute($name, $parameters = [], $options = [], $colle // otherwise we would generate a URI that, when followed by a user agent // (e.g. browser), does not match this route $path = strtr($path, ['/../' => '/%2E%2E/', '/./' => '/%2E/']); - if ('/..' === substr($path, -3)) { + if (str_ends_with($path, '/..')) { $path = substr($path, 0, -2) . '%2E%2E'; } - elseif ('/.' === substr($path, -2)) { + elseif (str_ends_with($path, '/.')) { $path = substr($path, 0, -1) . '%2E'; } } diff --git a/core/lib/Drupal/Core/Test/TestDiscovery.php b/core/lib/Drupal/Core/Test/TestDiscovery.php index 9e394a4342e8..d6e2336375f8 100644 --- a/core/lib/Drupal/Core/Test/TestDiscovery.php +++ b/core/lib/Drupal/Core/Test/TestDiscovery.php @@ -273,10 +273,10 @@ public static function scanDirectory($namespace_prefix, $path) { // We don't want to discover abstract TestBase classes, traits or // interfaces. They can be deprecated and will call @trigger_error() // during discovery. - return substr($file_name, -4) === '.php' && - substr($file_name, -12) !== 'TestBase.php' && - substr($file_name, -9) !== 'Trait.php' && - substr($file_name, -13) !== 'Interface.php'; + return str_ends_with($file_name, '.php') && + !str_ends_with($file_name, 'TestBase.php') && + !str_ends_with($file_name, 'Trait.php') && + !str_ends_with($file_name, 'Interface.php'); }); $files = new \RecursiveIteratorIterator($filter); $classes = []; diff --git a/core/lib/Drupal/Core/TypedData/DataReferenceDefinition.php b/core/lib/Drupal/Core/TypedData/DataReferenceDefinition.php index 3a2a66861c61..fc84856a2765 100644 --- a/core/lib/Drupal/Core/TypedData/DataReferenceDefinition.php +++ b/core/lib/Drupal/Core/TypedData/DataReferenceDefinition.php @@ -35,7 +35,7 @@ public static function create($target_data_type) { * {@inheritdoc} */ public static function createFromDataType($data_type) { - if (substr($data_type, -strlen('_reference')) != '_reference') { + if (!str_ends_with($data_type, '_reference')) { throw new \InvalidArgumentException('Data type must be of the form "{TARGET_TYPE}_reference"'); } // Cut of the _reference suffix. diff --git a/core/modules/file/src/Upload/FileUploadHandler.php b/core/modules/file/src/Upload/FileUploadHandler.php index a2c07911fdb8..835c513e1ef5 100644 --- a/core/modules/file/src/Upload/FileUploadHandler.php +++ b/core/modules/file/src/Upload/FileUploadHandler.php @@ -220,7 +220,7 @@ public function handleFileUpload(UploadedFileInterface $uploadedFile, array $val } // A file URI may already have a trailing slash or look like "public://". - if (substr($destination, -1) != '/') { + if (!str_ends_with($destination, '/')) { $destination .= '/'; } diff --git a/core/modules/filter/src/Plugin/Filter/FilterHtml.php b/core/modules/filter/src/Plugin/Filter/FilterHtml.php index 0718b73092e0..b24aa06ab5a7 100644 --- a/core/modules/filter/src/Plugin/Filter/FilterHtml.php +++ b/core/modules/filter/src/Plugin/Filter/FilterHtml.php @@ -124,7 +124,7 @@ public function filterAttributes($text) { $allowed_attributes = ['exact' => [], 'prefix' => []]; foreach (($global_allowed_attributes + $tag_attributes) as $name => $values) { // A trailing * indicates wildcard, but it must have some prefix. - if (substr($name, -1) === '*' && $name[0] !== '*') { + if (str_ends_with($name, '*') && $name[0] !== '*') { $allowed_attributes['prefix'][str_replace('*', '', $name)] = $this->prepareAttributeValues($values); } else { @@ -231,7 +231,7 @@ protected function prepareAttributeValues($attribute_values) { $result = ['exact' => [], 'prefix' => []]; foreach ($attribute_values as $name => $allowed) { // A trailing * indicates wildcard, but it must have some prefix. - if (substr($name, -1) === '*' && $name[0] !== '*') { + if (str_ends_with($name, '*') && $name[0] !== '*') { $result['prefix'][str_replace('*', '', $name)] = $allowed; } else { diff --git a/core/modules/jsonapi/src/Routing/Routes.php b/core/modules/jsonapi/src/Routing/Routes.php index f4766f5a875b..6a3ab0d90641 100644 --- a/core/modules/jsonapi/src/Routing/Routes.php +++ b/core/modules/jsonapi/src/Routing/Routes.php @@ -87,7 +87,7 @@ public function __construct(ResourceTypeRepositoryInterface $resource_type_repos sprintf('The provided base path should contain a leading slash "/". Given: "%s".', $jsonapi_base_path) ); assert( - substr($jsonapi_base_path, -1) !== '/', + !str_ends_with($jsonapi_base_path, '/'), sprintf('The provided base path should not contain a trailing slash "/". Given: "%s".', $jsonapi_base_path) ); $this->jsonApiBasePath = $jsonapi_base_path; diff --git a/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php b/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php index f4d006c09190..f7701ea27c5b 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php +++ b/core/modules/migrate/src/Plugin/migrate/process/FileCopy.php @@ -210,7 +210,7 @@ protected function writeFile($source, $destination, $replace = FileSystemInterfa */ protected function getDirectory($uri) { $dir = $this->fileSystem->dirname($uri); - if (substr($dir, -3) == '://') { + if (str_ends_with($dir, '://')) { return $this->fileSystem->realpath($dir); } return $dir; diff --git a/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php b/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php index 5cb4a954237e..f7d3b0898f6d 100644 --- a/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrateDrupalTestBase.php @@ -57,7 +57,7 @@ protected function loadFixture($path) { $default_db = Database::getConnection()->getKey(); Database::setActiveConnection($this->sourceDatabase->getKey()); - if (substr($path, -3) == '.gz') { + if (str_ends_with($path, '.gz')) { $path = 'compress.zlib://' . $path; } require $path; diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php index e9485aa3a739..f11e78c6d900 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php @@ -82,7 +82,7 @@ protected function loadFixture($path) { $default_db = Database::getConnection()->getKey(); Database::setActiveConnection($this->sourceDatabase->getKey()); - if (substr($path, -3) == '.gz') { + if (str_ends_with($path, '.gz')) { $path = 'compress.zlib://' . $path; } require $path; diff --git a/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php b/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php index cfa493233af0..dc0285bf9f11 100644 --- a/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php +++ b/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php @@ -425,7 +425,7 @@ protected function getCoreStability() { // Strip off "-dev"; $version_towards = substr($version, 0, -4); - if (substr($version_towards, -2) !== '.0') { + if (!str_ends_with($version_towards, '.0')) { // If the current version is developing towards an x.y.z release where // z is not 0, it means that the x.y.0 has already been released, and // only stable changes are permitted on the branch. diff --git a/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php index 35ffe3ad464b..1a57e5539a22 100644 --- a/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php +++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php @@ -144,7 +144,7 @@ protected function doInstall() { // Load the database(s). foreach ($this->databaseDumpFiles as $file) { - if (substr($file, -3) == '.gz') { + if (str_ends_with($file, '.gz')) { $file = "compress.zlib://$file"; } require $file; diff --git a/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageBase.php b/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageBase.php index d38cdefba60e..0056c4477cfc 100644 --- a/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageBase.php +++ b/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFileStorageBase.php @@ -81,7 +81,7 @@ public function testSecurity() { $name = 'test.php'; $php->save($name, '<?php'); $expected_root_directory = $this->directory . '/test'; - if (substr($name, -4) === '.php') { + if (str_ends_with($name, '.php')) { $expected_directory = $expected_root_directory . '/' . substr($name, 0, -4); } else { -- GitLab