From 4ca4dbaabe1f411de04cf1d55768842b6c1ed1ad Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Mon, 8 Jan 2024 10:48:04 +0000 Subject: [PATCH] Issue #3328456 by xjm, dimitriskr, murilohp, smustgrave: Replace substr($a, 0, $i) with str_starts_with() --- core/includes/theme.inc | 2 +- core/lib/Drupal/Component/FileSystem/FileSystem.php | 2 +- core/lib/Drupal/Component/Utility/UserAgent.php | 2 +- core/lib/Drupal/Component/Utility/Xss.php | 8 ++++---- core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php | 2 +- core/lib/Drupal/Core/File/FileSystem.php | 8 ++++---- core/lib/Drupal/Core/Form/FormState.php | 2 +- .../lib/Drupal/Core/Password/PhpassHashedPasswordBase.php | 4 ++-- .../lib/Drupal/Core/Render/MainContent/DialogRenderer.php | 2 +- .../Core/Routing/Enhancer/ParamConversionEnhancer.php | 2 +- core/lib/Drupal/Core/Routing/RouteMatch.php | 2 +- core/lib/Drupal/Core/Test/PhpUnitTestRunner.php | 2 +- core/modules/ckeditor5/src/HTMLRestrictions.php | 2 +- .../field/tests/src/Kernel/FieldTypePluginManagerTest.php | 2 +- .../file/src/Plugin/migrate/process/d6/FileUri.php | 2 +- core/modules/filter/filter.module | 3 +-- .../src/Normalizer/JsonApiDocumentTopLevelNormalizer.php | 2 +- .../link/src/Plugin/Field/FieldWidget/LinkWidget.php | 2 +- core/modules/locale/locale.module | 2 +- .../src/Plugin/MigrateDestinationPluginManager.php | 2 +- .../EventSubscriber/EntityResourcePostRouteSubscriber.php | 2 +- .../migrate/process/SearchConfigurationRankings.php | 2 +- core/modules/system/system.install | 2 +- core/modules/user/src/Form/UserLoginForm.php | 2 +- .../Validation/Constraint/UserNameConstraintValidator.php | 2 +- core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php | 2 +- core/tests/Drupal/KernelTests/Core/File/FileTestBase.php | 4 ++-- .../KernelTests/Core/Theme/Stable9LibraryOverrideTest.php | 2 +- .../Tests/Listeners/DrupalComponentTestListenerTrait.php | 2 +- 29 files changed, 37 insertions(+), 38 deletions(-) diff --git a/core/includes/theme.inc b/core/includes/theme.inc index ca0564118d94..ba8f4ee7b7ea 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -449,7 +449,7 @@ function theme_settings_convert_to_config(array $theme_settings, Config $config) elseif ($key == 'favicon_mimetype') { $config->set('favicon.mimetype', $value); } - elseif (substr($key, 0, 7) == 'toggle_') { + elseif (str_starts_with($key, 'toggle_')) { $config->set('features.' . mb_substr($key, 7), $value); } elseif (!in_array($key, ['theme', 'logo_upload'])) { diff --git a/core/lib/Drupal/Component/FileSystem/FileSystem.php b/core/lib/Drupal/Component/FileSystem/FileSystem.php index 69bc993dca19..a0486604316d 100644 --- a/core/lib/Drupal/Component/FileSystem/FileSystem.php +++ b/core/lib/Drupal/Component/FileSystem/FileSystem.php @@ -25,7 +25,7 @@ public static function getOsTemporaryDirectory() { } // Operating system specific dirs. - if (substr(PHP_OS, 0, 3) == 'WIN') { + if (str_starts_with(PHP_OS, 'WIN')) { $directories[] = 'c:\\windows\\temp'; $directories[] = 'c:\\winnt\\temp'; } diff --git a/core/lib/Drupal/Component/Utility/UserAgent.php b/core/lib/Drupal/Component/Utility/UserAgent.php index f7403e2fdd57..360b2d954c40 100644 --- a/core/lib/Drupal/Component/Utility/UserAgent.php +++ b/core/lib/Drupal/Component/Utility/UserAgent.php @@ -88,7 +88,7 @@ public static function getBestMatchingLangcode($http_accept_language, $langcodes // first occurrence of '-' otherwise we get a non-existing language zh. // All other languages use a langcode without a '-', so we can safely // split on the first occurrence of it. - if (strlen($langcode) > 7 && (substr($langcode, 0, 7) == 'zh-hant' || substr($langcode, 0, 7) == 'zh-hans')) { + if (strlen($langcode) > 7 && (str_starts_with($langcode, 'zh-hant') || str_starts_with($langcode, 'zh-hans'))) { $generic_tag = substr($langcode, 0, 7); } else { diff --git a/core/lib/Drupal/Component/Utility/Xss.php b/core/lib/Drupal/Component/Utility/Xss.php index 7480c3793eeb..2c143cddf84b 100644 --- a/core/lib/Drupal/Component/Utility/Xss.php +++ b/core/lib/Drupal/Component/Utility/Xss.php @@ -141,7 +141,7 @@ public static function filterAdmin($string) { * version of the HTML element. */ protected static function split($string, array $html_tags, $class) { - if (substr($string, 0, 1) != '<') { + if (!str_starts_with($string, '<')) { // We matched a lone ">" character. return '>'; } @@ -217,8 +217,8 @@ protected static function attributes($attributes) { $attribute_name = strtolower($match[1]); $skip = ( $attribute_name == 'style' || - substr($attribute_name, 0, 2) == 'on' || - substr($attribute_name, 0, 1) == '-' || + str_starts_with($attribute_name, 'on') || + str_starts_with($attribute_name, '-') || // Ignore long attributes to avoid unnecessary processing // overhead. strlen($attribute_name) > 96 @@ -232,7 +232,7 @@ protected static function attributes($attributes) { // such attributes. // @see \Drupal\Component\Utility\UrlHelper::filterBadProtocol() // @see http://www.w3.org/TR/html4/index/attributes.html - $skip_protocol_filtering = substr($attribute_name, 0, 5) === 'data-' || in_array($attribute_name, [ + $skip_protocol_filtering = str_starts_with($attribute_name, 'data-') || in_array($attribute_name, [ 'title', 'alt', 'rel', diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php b/core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php index 03e00ef45102..3e3cb1e62dc7 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 (substr($alias, 0, 6) === 'field_' && substr($field, -6) !== '_value' && substr($alias, -6) === '_value') { + if (str_starts_with($alias, 'field_') && substr($field, -6) !== '_value' && substr($alias, -6) === '_value') { $alias = substr($alias, 0, -6); } return $alias; diff --git a/core/lib/Drupal/Core/File/FileSystem.php b/core/lib/Drupal/Core/File/FileSystem.php index c82d61fbe351..9d1e66b4bd4b 100644 --- a/core/lib/Drupal/Core/File/FileSystem.php +++ b/core/lib/Drupal/Core/File/FileSystem.php @@ -114,7 +114,7 @@ public function chmod($uri, $mode = NULL) { * {@inheritdoc} */ public function unlink($uri, $context = NULL) { - if (!$this->streamWrapperManager->isValidUri($uri) && (substr(PHP_OS, 0, 3) == 'WIN')) { + if (!$this->streamWrapperManager->isValidUri($uri) && str_starts_with(PHP_OS, 'WIN')) { chmod($uri, 0600); } if ($context) { @@ -257,7 +257,7 @@ protected function mkdirCall($uri, $mode, $recursive, $context) { * {@inheritdoc} */ public function rmdir($uri, $context = NULL) { - if (!$this->streamWrapperManager->isValidUri($uri) && (substr(PHP_OS, 0, 3) == 'WIN')) { + if (!$this->streamWrapperManager->isValidUri($uri) && str_starts_with(PHP_OS, 'WIN')) { chmod($uri, 0700); } if ($context) { @@ -383,7 +383,7 @@ public function move($source, $destination, $replace = self::EXISTS_RENAME) { // Ensure compatibility with Windows. // @see \Drupal\Core\File\FileSystemInterface::unlink(). - if (!$this->streamWrapperManager->isValidUri($source) && (substr(PHP_OS, 0, 3) == 'WIN')) { + if (!$this->streamWrapperManager->isValidUri($source) && str_starts_with(PHP_OS, 'WIN')) { chmod($source, 0600); } // Attempt to resolve the URIs. This is necessary in certain @@ -590,7 +590,7 @@ public function createFilename($basename, $directory) { if (preg_last_error() !== PREG_NO_ERROR) { throw new FileException(sprintf("Invalid filename '%s'", $original)); } - if (substr(PHP_OS, 0, 3) == 'WIN') { + if (str_starts_with(PHP_OS, 'WIN')) { // These characters are not allowed in Windows filenames. $basename = str_replace([':', '*', '?', '"', '<', '>', '|'], '_', $basename); } diff --git a/core/lib/Drupal/Core/Form/FormState.php b/core/lib/Drupal/Core/Form/FormState.php index 9c94c79d2c53..7e6d974cb73f 100644 --- a/core/lib/Drupal/Core/Form/FormState.php +++ b/core/lib/Drupal/Core/Form/FormState.php @@ -1192,7 +1192,7 @@ public function isRebuilding() { * {@inheritdoc} */ public function prepareCallback($callback) { - if (is_string($callback) && substr($callback, 0, 2) == '::') { + if (is_string($callback) && str_starts_with($callback, '::')) { $callback = [$this->getFormObject(), substr($callback, 2)]; } return $callback; diff --git a/core/lib/Drupal/Core/Password/PhpassHashedPasswordBase.php b/core/lib/Drupal/Core/Password/PhpassHashedPasswordBase.php index 7be8e393801f..ae9ae35d12fc 100644 --- a/core/lib/Drupal/Core/Password/PhpassHashedPasswordBase.php +++ b/core/lib/Drupal/Core/Password/PhpassHashedPasswordBase.php @@ -246,7 +246,7 @@ public function check(#[\SensitiveParameter] $password, #[\SensitiveParameter] $ if ($hash === NULL || $hash === '') { return FALSE; } - if (substr($hash, 0, 2) == 'U$') { + if (str_starts_with($hash, 'U$')) { // This may be an updated password from user_update_7000(). Such hashes // have 'U' added as the first character and need an extra md5() (see the // Drupal 7 documentation). @@ -293,7 +293,7 @@ public function needsRehash(#[\SensitiveParameter] $hash) { } // Check whether this was an updated password. - if ((substr($hash, 0, 3) != '$S$') || (strlen($hash) != static::HASH_LENGTH)) { + if (!str_starts_with($hash, '$S$') || (strlen($hash) != static::HASH_LENGTH)) { return TRUE; } // Ensure that $count_log2 is within set bounds. diff --git a/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php b/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php index 6468e02d17e7..1fec7345f5f1 100644 --- a/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php +++ b/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php @@ -86,7 +86,7 @@ protected function determineTargetSelector(array &$options, RouteMatchInterface // If the target was nominated in the incoming options, use that. $target = $options['target']; // Ensure the target includes the #. - if (substr($target, 0, 1) != '#') { + if (!str_starts_with($target, '#')) { $target = '#' . $target; } // This shouldn't be passed on to jQuery.ui.dialog. diff --git a/core/lib/Drupal/Core/Routing/Enhancer/ParamConversionEnhancer.php b/core/lib/Drupal/Core/Routing/Enhancer/ParamConversionEnhancer.php index 2ec558a36e05..9d089d890767 100644 --- a/core/lib/Drupal/Core/Routing/Enhancer/ParamConversionEnhancer.php +++ b/core/lib/Drupal/Core/Routing/Enhancer/ParamConversionEnhancer.php @@ -70,7 +70,7 @@ protected function copyRawVariables(array $defaults) { // Route defaults that do not start with a leading "_" are also // parameters, even if they are not included in path or host patterns. foreach ($route->getDefaults() as $name => $value) { - if (!isset($raw_variables[$name]) && substr($name, 0, 1) !== '_') { + if (!isset($raw_variables[$name]) && !str_starts_with($name, '_')) { $raw_variables[$name] = $value; } } diff --git a/core/lib/Drupal/Core/Routing/RouteMatch.php b/core/lib/Drupal/Core/Routing/RouteMatch.php index 63304fa25a01..175865993afb 100644 --- a/core/lib/Drupal/Core/Routing/RouteMatch.php +++ b/core/lib/Drupal/Core/Routing/RouteMatch.php @@ -149,7 +149,7 @@ protected function getParameterNames() { // Route defaults that do not start with a leading "_" are also // parameters, even if they are not included in path or host patterns. foreach ($route->getDefaults() as $name => $value) { - if (!isset($names[$name]) && substr($name, 0, 1) !== '_') { + if (!isset($names[$name]) && !str_starts_with($name, '_')) { $names[$name] = $name; } } diff --git a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php index 35d28ccf5dfd..425f125aa87c 100644 --- a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php +++ b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php @@ -82,7 +82,7 @@ public function phpUnitCommand(): string { // The file in Composer's bin dir is a *nix link, which does not work when // extracted from a tarball and generally not on Windows. $command = $vendor_dir . '/phpunit/phpunit/phpunit'; - if (substr(PHP_OS, 0, 3) == 'WIN') { + if (str_starts_with(PHP_OS, 'WIN')) { // On Windows it is necessary to run the script using the PHP executable. $php_executable_finder = new PhpExecutableFinder(); $php = $php_executable_finder->find(); diff --git a/core/modules/ckeditor5/src/HTMLRestrictions.php b/core/modules/ckeditor5/src/HTMLRestrictions.php index 09485d93a2b8..4924cf45f98c 100644 --- a/core/modules/ckeditor5/src/HTMLRestrictions.php +++ b/core/modules/ckeditor5/src/HTMLRestrictions.php @@ -1116,7 +1116,7 @@ public function extractPlainTagsSubset(): HTMLRestrictions { * TRUE if it is a wildcard, otherwise FALSE. */ private static function isWildcardTag(string $tag_name): bool { - return substr($tag_name, 0, 1) === '$' && array_key_exists($tag_name, self::WILDCARD_ELEMENT_METHODS); + return str_starts_with($tag_name, '$') && array_key_exists($tag_name, self::WILDCARD_ELEMENT_METHODS); } /** diff --git a/core/modules/field/tests/src/Kernel/FieldTypePluginManagerTest.php b/core/modules/field/tests/src/Kernel/FieldTypePluginManagerTest.php index 83aae5e2b4ce..677528acda27 100644 --- a/core/modules/field/tests/src/Kernel/FieldTypePluginManagerTest.php +++ b/core/modules/field/tests/src/Kernel/FieldTypePluginManagerTest.php @@ -131,7 +131,7 @@ protected function enableAllCoreModules() { /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ $module_handler = $this->container->get('module_handler'); $module_list = array_filter(array_keys($module_list), function ($module) use ($module_handler, $module_list) { - return !$module_handler->moduleExists($module) && substr($module_list[$module]->getPath(), 0, 4) === 'core'; + return !$module_handler->moduleExists($module) && str_starts_with($module_list[$module]->getPath(), 'core'); }); $this->enableModules($module_list); } diff --git a/core/modules/file/src/Plugin/migrate/process/d6/FileUri.php b/core/modules/file/src/Plugin/migrate/process/d6/FileUri.php index 2acf883f97d4..08eb189a3901 100644 --- a/core/modules/file/src/Plugin/migrate/process/d6/FileUri.php +++ b/core/modules/file/src/Plugin/migrate/process/d6/FileUri.php @@ -27,7 +27,7 @@ public function transform($value, MigrateExecutableInterface $migrate_executable [$filepath, $file_directory_path, $temp_directory_path, $is_public] = $value; // Specific handling using $temp_directory_path for temporary files. - if (substr($filepath, 0, strlen($temp_directory_path)) === $temp_directory_path) { + if (str_starts_with($filepath, $temp_directory_path)) { $uri = preg_replace('/^' . preg_quote($temp_directory_path, '/') . '/', '', $filepath); return 'temporary://' . ltrim($uri, '/'); } diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module index 8814e0d8ea02..32fc19fe377b 100644 --- a/core/modules/filter/filter.module +++ b/core/modules/filter/filter.module @@ -713,8 +713,7 @@ function _filter_autop($text) { $output = ''; foreach ($chunks as $i => $chunk) { if ($i % 2) { - $comment = (substr($chunk, 0, 4) == '<!--'); - if ($comment) { + if (str_starts_with($chunk, '<!--')) { // Nothing to do, this is a comment. $output .= $chunk; continue; diff --git a/core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php b/core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php index d12ec670f41e..6954c5b73ab5 100644 --- a/core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php +++ b/core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php @@ -146,7 +146,7 @@ public function denormalize($data, $class, $format = NULL, array $context = []): $reference_item += $relationship['data'][$delta]['meta']; } $canonical_ids[] = array_filter($reference_item, function ($key) { - return substr($key, 0, strlen('drupal_internal__')) !== 'drupal_internal__'; + return !str_starts_with($key, 'drupal_internal__'); }, ARRAY_FILTER_USE_KEY); } diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php index 7452a38eccf3..97015d5bef8f 100644 --- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php +++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php @@ -147,7 +147,7 @@ public static function validateUriElement($element, FormStateInterface $form_sta // URI , ensure the raw value begins with '/', '?' or '#'. // @todo '<front>' is valid input for BC reasons, may be removed by // https://www.drupal.org/node/2421941 - if (parse_url($uri, PHP_URL_SCHEME) === 'internal' && !in_array($element['#value'][0], ['/', '?', '#'], TRUE) && substr($element['#value'], 0, 7) !== '<front>') { + if (parse_url($uri, PHP_URL_SCHEME) === 'internal' && !in_array($element['#value'][0], ['/', '?', '#'], TRUE) && !str_starts_with($element['#value'], '<front>')) { $form_state->setError($element, new TranslatableMarkup('Manually entered paths should start with one of the following characters: / ? #')); return; } diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index 2075c37c0159..acbbaba12ea6 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -526,7 +526,7 @@ function locale_js_translate(array $files = [], $language_interface = NULL) { foreach ($files as $filepath) { if (!in_array($filepath, $parsed)) { // Don't parse our own translations files. - if (substr($filepath, 0, strlen($dir)) != $dir) { + if (!str_starts_with($filepath, $dir)) { _locale_parse_js_file($filepath); $parsed[] = $filepath; $new_files = TRUE; diff --git a/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php b/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php index 04de74954612..b65515c3afed 100644 --- a/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php +++ b/core/modules/migrate/src/Plugin/MigrateDestinationPluginManager.php @@ -55,7 +55,7 @@ public function __construct($type, \Traversable $namespaces, CacheBackendInterfa * A specific createInstance method is necessary to pass the migration on. */ public function createInstance($plugin_id, array $configuration = [], MigrationInterface $migration = NULL) { - if (substr($plugin_id, 0, 7) == 'entity:' && !$this->entityTypeManager->getDefinition(substr($plugin_id, 7), FALSE)) { + if (str_starts_with($plugin_id, 'entity:') && !$this->entityTypeManager->getDefinition(substr($plugin_id, 7), FALSE)) { $plugin_id = 'null'; } return parent::createInstance($plugin_id, $configuration, $migration); diff --git a/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php b/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php index 42830f66b2ed..02a4a14e3d6b 100644 --- a/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php +++ b/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php @@ -44,7 +44,7 @@ public function onDynamicRouteEvent(RouteBuildEvent $event) { // We only care about REST resource config entities for the // \Drupal\rest\Plugin\rest\resource\EntityResource plugin. $plugin_id = $resource_config->toArray()['plugin_id']; - if (substr($plugin_id, 0, 6) !== 'entity') { + if (!str_starts_with($plugin_id, 'entity')) { continue; } diff --git a/core/modules/search/src/Plugin/migrate/process/SearchConfigurationRankings.php b/core/modules/search/src/Plugin/migrate/process/SearchConfigurationRankings.php index 153161f9a91e..f35bdfe7bcd9 100644 --- a/core/modules/search/src/Plugin/migrate/process/SearchConfigurationRankings.php +++ b/core/modules/search/src/Plugin/migrate/process/SearchConfigurationRankings.php @@ -23,7 +23,7 @@ class SearchConfigurationRankings extends ProcessPluginBase { public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { $return = NULL; foreach ($row->getSource() as $name => $rank) { - if (substr($name, 0, 10) == 'node_rank_' && is_numeric($rank)) { + if (str_starts_with($name, 'node_rank_') && is_numeric($rank)) { $return[substr($name, 10)] = $rank; } } diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 8f557e9ac4d2..118125e60f9c 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -1426,7 +1426,7 @@ function system_requirements($phase) { // file names. There is no definite root directory depth below which Drupal is // guaranteed to function correctly on Windows. Since problems are likely // with more than 100 characters in the Drupal root path, show an error. - if (substr(PHP_OS, 0, 3) == 'WIN') { + if (str_starts_with(PHP_OS, 'WIN')) { $depth = strlen(realpath(DRUPAL_ROOT . '/' . PublicStream::basePath())); if ($depth > 120) { $requirements['max_path_on_windows'] = [ diff --git a/core/modules/user/src/Form/UserLoginForm.php b/core/modules/user/src/Form/UserLoginForm.php index 0c86edbee59d..54a3d4280fa0 100644 --- a/core/modules/user/src/Form/UserLoginForm.php +++ b/core/modules/user/src/Form/UserLoginForm.php @@ -217,7 +217,7 @@ public function validateAuthentication(array &$form, FormStateInterface $form_st // Now check the actual limit for the user. Default is to allow 5 // failed attempts every 6 hours. This means we check the flood table // twice if flood control has already been triggered by a previous - // login attempt, bu this should be the less common case. + // login attempt, but this should be the less common case. if (!$this->userFloodControl->isAllowed('user.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) { $form_state->set('flood_control_triggered', 'user'); return; diff --git a/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php b/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php index b775d09fa790..bbe7ea07809c 100644 --- a/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php +++ b/core/modules/user/src/Plugin/Validation/Constraint/UserNameConstraintValidator.php @@ -20,7 +20,7 @@ public function validate($items, Constraint $constraint) { return; } $name = $items->first()->value; - if (substr($name, 0, 1) == ' ') { + if (str_starts_with($name, ' ')) { $this->context->addViolation($constraint->spaceBeginMessage); } if (substr($name, -1) == ' ') { diff --git a/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php b/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php index 867dce7d031b..5530bba27b4f 100644 --- a/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php @@ -77,7 +77,7 @@ public function testFileCheckDirectoryHandling() { // Make sure directory actually exists. $this->assertDirectoryExists($directory); $file_system = \Drupal::service('file_system'); - if (substr(PHP_OS, 0, 3) != 'WIN') { + if (!str_starts_with(PHP_OS, 'WIN')) { // PHP on Windows doesn't support any kind of useful read-only mode for // directories. When executing a chmod() on a directory, PHP only sets the // read-only flag, which doesn't prevent files to actually be written diff --git a/core/tests/Drupal/KernelTests/Core/File/FileTestBase.php b/core/tests/Drupal/KernelTests/Core/File/FileTestBase.php index ac0376d69622..b41787f452ad 100644 --- a/core/tests/Drupal/KernelTests/Core/File/FileTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/File/FileTestBase.php @@ -98,7 +98,7 @@ public function assertFilePermissions($filepath, $expected_mode, $message = NULL // read/write/execute bits. On Windows, chmod() ignores the "group" and // "other" bits, and fileperms() returns the "user" bits in all three // positions. $expected_mode is updated to reflect this. - if (substr(PHP_OS, 0, 3) == 'WIN') { + if (str_starts_with(PHP_OS, 'WIN')) { // Reset the "group" and "other" bits. $expected_mode = $expected_mode & 0700; // Shift the "user" bits to the "group" and "other" positions also. @@ -134,7 +134,7 @@ public function assertDirectoryPermissions($directory, $expected_mode, $message // read/write/execute bits. On Windows, chmod() ignores the "group" and // "other" bits, and fileperms() returns the "user" bits in all three // positions. $expected_mode is updated to reflect this. - if (substr(PHP_OS, 0, 3) == 'WIN') { + if (str_starts_with(PHP_OS, 'WIN')) { // Reset the "group" and "other" bits. $expected_mode = $expected_mode & 0700; // Shift the "user" bits to the "group" and "other" positions also. diff --git a/core/tests/Drupal/KernelTests/Core/Theme/Stable9LibraryOverrideTest.php b/core/tests/Drupal/KernelTests/Core/Theme/Stable9LibraryOverrideTest.php index 2c2f0e6a0059..39ccd4038d53 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/Stable9LibraryOverrideTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/Stable9LibraryOverrideTest.php @@ -71,7 +71,7 @@ public function testStable9LibraryOverrides() { continue; } // Skip internal libraries. - if (substr($library_name, 0, 9) === 'internal.') { + if (str_starts_with($library_name, 'internal.')) { continue; } $library_after = $libraries_after[$extension][$library_name]; diff --git a/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php b/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php index 6428bae39c0e..9730c37dedd6 100644 --- a/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php +++ b/core/tests/Drupal/Tests/Listeners/DrupalComponentTestListenerTrait.php @@ -24,7 +24,7 @@ trait DrupalComponentTestListenerTrait { */ protected function componentEndTest($test, $time) { /** @var \PHPUnit\Framework\Test $test */ - if (substr($test->toString(), 0, 22) == 'Drupal\Tests\Component') { + if (str_starts_with($test->toString(), 'Drupal\Tests\Component')) { if ($test instanceof BrowserTestBase || $test instanceof KernelTestBase || $test instanceof UnitTestCase) { $error = new AssertionFailedError('Component tests should not extend a core test base class.'); $test->getTestResultObject()->addFailure($test, $error, $time); -- GitLab