diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index a8df08f2df..6b2158ecfa 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -2292,7 +2292,12 @@ function install_config_import_batch() { // Match up the site UUIDs, the install_base_system install task will have // installed the system module and created a new UUID. $system_site = $sync->read('system.site'); - \Drupal::configFactory()->getEditable('system.site')->set('uuid', $system_site['uuid'])->save(); + // When installing from configuration it is possible that system.site + // configuration is not present. If this occurs then the error will cause + // a ConfigImporterException and configuration import will fail. + if ($system_site !== FALSE) { + \Drupal::configFactory()->getEditable('system.site')->set('uuid', $system_site['uuid'])->save(); + } // Create the storage comparer and the config importer. $storage_comparer = new StorageComparer($sync, \Drupal::service('config.storage')); diff --git a/core/includes/theme.inc b/core/includes/theme.inc index b4b64474a6..75311c488e 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1153,7 +1153,7 @@ function template_preprocess_item_list(&$variables) { // \Drupal\Core\Render\Element::children(), which cannot be used // here, since it triggers an error on string values. foreach ($child as $child_key => $child_value) { - if ($child_key[0] !== '#') { + if (is_int($child_key) || $child_key === '' || $child_key[0] !== '#') { $child['#items'][$child_key] = $child_value; unset($child[$child_key]); } diff --git a/core/lib/Drupal/Component/Annotation/Doctrine/DocParser.php b/core/lib/Drupal/Component/Annotation/Doctrine/DocParser.php index 1d8cf2fbc3..5083ed7568 100644 --- a/core/lib/Drupal/Component/Annotation/Doctrine/DocParser.php +++ b/core/lib/Drupal/Component/Annotation/Doctrine/DocParser.php @@ -966,13 +966,16 @@ private function Identifier() $className = $this->lexer->token['value']; - while ($this->lexer->lookahead['position'] === ($this->lexer->token['position'] + strlen($this->lexer->token['value'])) + $position = $this->lexer->lookahead['position'] ?? NULL; + while ($position === ($this->lexer->token['position'] + strlen($this->lexer->token['value'])) && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { $this->match(DocLexer::T_NAMESPACE_SEPARATOR); $this->matchAny(self::$classIdentifiers); $className .= '\\' . $this->lexer->token['value']; + + $position = $this->lexer->lookahead['position'] ?? NULL; } return $className; @@ -987,7 +990,7 @@ private function Value() { $peek = $this->lexer->glimpse(); - if (DocLexer::T_EQUALS === $peek['type']) { + if ($peek !== NULL && DocLexer::T_EQUALS === $peek['type']) { return $this->FieldAssignment(); } diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php index a9308fdb78..99328413da 100644 --- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php @@ -131,7 +131,7 @@ public function buildByExtension($extension) { $library['version'] = \Drupal::VERSION; } // Remove 'v' prefix from external library versions. - elseif ($library['version'][0] === 'v') { + elseif (is_string($library['version']) && $library['version'][0] === 'v') { $library['version'] = substr($library['version'], 1); } } diff --git a/core/lib/Drupal/Core/Config/StorageComparer.php b/core/lib/Drupal/Core/Config/StorageComparer.php index e362493ac3..03a904bea7 100644 --- a/core/lib/Drupal/Core/Config/StorageComparer.php +++ b/core/lib/Drupal/Core/Config/StorageComparer.php @@ -388,7 +388,7 @@ public function hasChanges() { public function validateSiteUuid() { $source = $this->sourceStorage->read('system.site'); $target = $this->targetStorage->read('system.site'); - return $source['uuid'] === $target['uuid']; + return $source && $target && $source['uuid'] === $target['uuid']; } /** diff --git a/core/lib/Drupal/Core/Database/Install/Tasks.php b/core/lib/Drupal/Core/Database/Install/Tasks.php index 7dfe5d0288..6ba3ba733c 100644 --- a/core/lib/Drupal/Core/Database/Install/Tasks.php +++ b/core/lib/Drupal/Core/Database/Install/Tasks.php @@ -243,7 +243,9 @@ public function getFormOptions(array $database) { ]; global $install_state; - $profile = $install_state['parameters']['profile']; + // @todo https://www.drupal.org/project/drupal/issues/3110839 remove PHP 7.4 + // work around and add a better message for the migrate UI. + $profile = $install_state['parameters']['profile'] ?? NULL; $db_prefix = ($profile == 'standard') ? 'drupal_' : $profile . '_'; $form['advanced_options']['prefix'] = [ '#type' => 'textfield', diff --git a/core/lib/Drupal/Core/Form/FormSubmitter.php b/core/lib/Drupal/Core/Form/FormSubmitter.php index 8591edaa2b..4a6a34c807 100644 --- a/core/lib/Drupal/Core/Form/FormSubmitter.php +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php @@ -61,7 +61,9 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) { $batch['progressive'] = !$form_state->isProgrammed(); $response = batch_process(); - if ($batch['progressive']) { + // If the batch has been completed and _batch_finished() called then + // $batch will be NULL. + if ($batch && $batch['progressive']) { return $response; } diff --git a/core/lib/Drupal/Core/Render/Element.php b/core/lib/Drupal/Core/Render/Element.php index 682f236163..f27304cde8 100644 --- a/core/lib/Drupal/Core/Render/Element.php +++ b/core/lib/Drupal/Core/Render/Element.php @@ -78,7 +78,7 @@ public static function children(array &$elements, $sort = FALSE) { $i = 0; $sortable = FALSE; foreach ($elements as $key => $value) { - if ($key === '' || $key[0] !== '#') { + if (is_int($key) || $key === '' || $key[0] !== '#') { if (is_array($value)) { if (isset($value['#weight'])) { $weight = $value['#weight']; diff --git a/core/lib/Drupal/Core/Routing/CompiledRoute.php b/core/lib/Drupal/Core/Routing/CompiledRoute.php index 652acc5bb4..58498ce455 100644 --- a/core/lib/Drupal/Core/Routing/CompiledRoute.php +++ b/core/lib/Drupal/Core/Routing/CompiledRoute.php @@ -143,23 +143,22 @@ public function getRequirements() { /** * {@inheritdoc} */ - public function serialize() { + public function __serialize(): array { // Calling the parent method is safer than trying to optimize out the extra // function calls. - $data = unserialize(parent::serialize()); + $data = parent::__serialize(); $data['fit'] = $this->fit; $data['patternOutline'] = $this->patternOutline; $data['numParts'] = $this->numParts; - return serialize($data); + return $data; } /** * {@inheritdoc} */ - public function unserialize($serialized) { - parent::unserialize($serialized); - $data = unserialize($serialized); + public function __unserialize(array $data): void { + parent::__unserialize($data); $this->fit = $data['fit']; $this->patternOutline = $data['patternOutline']; diff --git a/core/lib/Drupal/Core/Security/RequestSanitizer.php b/core/lib/Drupal/Core/Security/RequestSanitizer.php index e1626ed383..a778e4be4e 100644 --- a/core/lib/Drupal/Core/Security/RequestSanitizer.php +++ b/core/lib/Drupal/Core/Security/RequestSanitizer.php @@ -153,7 +153,7 @@ protected static function checkDestination($destination, array $whitelist) { protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) { if (is_array($input)) { foreach ($input as $key => $value) { - if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) { + if ($key !== '' && ((string) $key)[0] === '#' && !in_array($key, $whitelist, TRUE)) { unset($input[$key]); $sanitized_keys[] = $key; } diff --git a/core/modules/color/color.module b/core/modules/color/color.module index eb36f30caf..d6399276a8 100644 --- a/core/modules/color/color.module +++ b/core/modules/color/color.module @@ -751,8 +751,9 @@ function _color_blend($img, $hex1, $hex2, $alpha) { * Converts a hex color into an RGB triplet. */ function _color_unpack($hex, $normalize = FALSE) { - if (strlen($hex) == 4) { - $hex = $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3]; + $hex = substr($hex, 1); + if (strlen($hex) == 3) { + $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } $c = hexdec($hex); for ($i = 16; $i >= 0; $i -= 8) { diff --git a/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php index a695760dfc..ed7a026b79 100644 --- a/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php +++ b/core/modules/field/src/Plugin/migrate/process/d7/FieldInstanceSettings.php @@ -21,7 +21,6 @@ public function transform($value, MigrateExecutableInterface $migrate_executable $widget_type = $widget_settings['type']; $field_data = unserialize($field_definition['data']); - $field_settings = $field_data['settings']; // Get taxonomy term reference handler settings from allowed values. if ($row->getSourceProperty('type') == 'taxonomy_term_reference') { @@ -38,6 +37,7 @@ public function transform($value, MigrateExecutableInterface $migrate_executable // Get entityreference handler settings from source field configuration. if ($row->getSourceProperty('type') == "entityreference") { + $field_settings = $field_data['settings']; $instance_settings['handler'] = 'default:' . $field_settings['target_type']; // Transform the sort settings to D8 structure. $sort = [ diff --git a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php index 74340884d2..e15fe7bdc6 100644 --- a/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php +++ b/core/modules/field/src/Plugin/migrate/source/d7/FieldInstance.php @@ -180,9 +180,6 @@ public function prepareRow(Row $row) { } } - $field_data = unserialize($row->getSourceProperty('field_data')); - $row->setSourceProperty('field_settings', $field_data['settings']); - return parent::prepareRow($row); } diff --git a/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php b/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php index 48dbb81b47..c2d65bfdbc 100644 --- a/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php +++ b/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php @@ -82,7 +82,10 @@ public function normalize($field_item, $format = NULL, array $context = []) { // Normalize the target entity. $embedded = $this->serializer->normalize($target_entity, $format, $context); - $link = $embedded['_links']['self']; + // @todo https://www.drupal.org/project/drupal/issues/3110815 $embedded will + // be NULL if the target entity does not exist. Use null coalescence + // operator to preserve behaviour in PHP 7.4. + $link = $embedded['_links']['self'] ?? NULL; // If the field is translatable, add the langcode to the link relation // object. This does not indicate the language of the target entity. if ($langcode) { diff --git a/core/modules/language/src/LanguageServiceProvider.php b/core/modules/language/src/LanguageServiceProvider.php index a7e934aab6..b463bb6ef6 100644 --- a/core/modules/language/src/LanguageServiceProvider.php +++ b/core/modules/language/src/LanguageServiceProvider.php @@ -87,9 +87,11 @@ protected function isMultilingual() { protected function getDefaultLanguageValues() { $config_storage = BootstrapConfigStorageFactory::get(); $system = $config_storage->read('system.site'); - $default_language = $config_storage->read(static::CONFIG_PREFIX . $system['default_langcode']); - if (is_array($default_language)) { - return $default_language; + if ($system) { + $default_language = $config_storage->read(static::CONFIG_PREFIX . $system['default_langcode']); + if (is_array($default_language)) { + return $default_language; + } } return FALSE; } diff --git a/core/modules/layout_builder/tests/src/Kernel/FieldBlockTest.php b/core/modules/layout_builder/tests/src/Kernel/FieldBlockTest.php index ebf19c53a4..d041e39689 100644 --- a/core/modules/layout_builder/tests/src/Kernel/FieldBlockTest.php +++ b/core/modules/layout_builder/tests/src/Kernel/FieldBlockTest.php @@ -281,13 +281,22 @@ public function providerTestBuild() { new ReturnPromise([[]]), '', ]; - $data['exception'] = [ - new ThrowPromise(new \Exception('The exception message')), + return $data; + } + + /** + * @covers ::build + */ + public function testBuildException() { + // In PHP 7.4 ReflectionClass cannot be serialized so this cannot be part of + // providerTestBuild(). + $promise = new ThrowPromise(new \Exception('The exception message')); + $this->testBuild( + $promise, '', 'The field "%field" failed to render with the error of "%error".', - ['%field' => 'the_field_name', '%error' => 'The exception message'], - ]; - return $data; + ['%field' => 'the_field_name', '%error' => 'The exception message'] + ); } /** diff --git a/core/modules/locale/locale.bulk.inc b/core/modules/locale/locale.bulk.inc index 37c4522092..a344a1b0e7 100644 --- a/core/modules/locale/locale.bulk.inc +++ b/core/modules/locale/locale.bulk.inc @@ -385,6 +385,11 @@ function locale_translate_batch_finished($success, array $results) { // file), simply do nothing. if ($results && isset($results['stats'])) { foreach ($results['stats'] as $filepath => $report) { + if ($filepath === 'config') { + // Ignore the config entry. It is processed in + // locale_config_batch_finished() below. + continue; + } $additions += $report['additions']; $updates += $report['updates']; $deletes += $report['deletes']; diff --git a/core/modules/migrate/tests/src/Kernel/MigrateConfigRollbackTest.php b/core/modules/migrate/tests/src/Kernel/MigrateConfigRollbackTest.php index 27aa45bcce..72abb0f287 100644 --- a/core/modules/migrate/tests/src/Kernel/MigrateConfigRollbackTest.php +++ b/core/modules/migrate/tests/src/Kernel/MigrateConfigRollbackTest.php @@ -78,8 +78,7 @@ public function testConfigRollback() { $this->assertSame('Some site', $config->get('name')); $this->assertSame('Awesome slogan', $config->get('slogan')); // Confirm the map row is deleted. - $map_row = $config_id_map->getRowBySource(['id' => $variable[0]['id']]); - $this->assertNull($map_row['destid1']); + $this->assertFalse($config_id_map->getRowBySource(['id' => $variable[0]['id']])); // We use system configuration to demonstrate importing and rolling back // configuration translations. diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 7347184d21..a43435648a 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -498,7 +498,7 @@ function template_preprocess_node(&$variables) { unset($variables['elements']['uid']); } - if (!$skip_custom_preprocessing || !$node->getFieldDefinition('title')->isDisplayConfigurable('view')) { + if (isset($variables['elements']['title']) && (!$skip_custom_preprocessing || !$node->getFieldDefinition('title')->isDisplayConfigurable('view'))) { $variables['label'] = $variables['elements']['title']; unset($variables['elements']['title']); } diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module index 6dced6adab..d09886bcbb 100644 --- a/core/modules/rdf/rdf.module +++ b/core/modules/rdf/rdf.module @@ -495,7 +495,7 @@ function rdf_preprocess_comment(&$variables) { } // Adds RDFa markup for the date of the comment. $created_mapping = $mapping->getPreparedFieldMapping('created'); - if (!empty($created_mapping)) { + if (!empty($created_mapping) && isset($comment->rdf_data)) { // The comment date is precomputed as part of the rdf_data so that it can be // cached as part of the entity. $date_attributes = $comment->rdf_data['date']; diff --git a/core/modules/rdf/src/Entity/RdfMapping.php b/core/modules/rdf/src/Entity/RdfMapping.php index e33f24a59a..c28f72cd79 100644 --- a/core/modules/rdf/src/Entity/RdfMapping.php +++ b/core/modules/rdf/src/Entity/RdfMapping.php @@ -148,7 +148,9 @@ public function calculateDependencies() { $entity_type = \Drupal::entityTypeManager()->getDefinition($this->targetEntityType); $this->addDependency('module', $entity_type->getProvider()); $bundle_config_dependency = $entity_type->getBundleConfigDependency($this->bundle); - $this->addDependency($bundle_config_dependency['type'], $bundle_config_dependency['name']); + if (!empty($bundle_config_dependency)) { + $this->addDependency($bundle_config_dependency['type'], $bundle_config_dependency['name']); + } return $this; } diff --git a/core/modules/rdf/tests/src/Traits/EasyRdf_ParsedUri.php b/core/modules/rdf/tests/src/Traits/EasyRdf_ParsedUri.php new file mode 100644 index 0000000000..54e3833a92 --- /dev/null +++ b/core/modules/rdf/tests/src/Traits/EasyRdf_ParsedUri.php @@ -0,0 +1,349 @@ +scheme = isset($matches[2]) ? $matches[2] : ''; + } + if (!empty($matches[3])) { + $this->authority = isset($matches[4]) ? $matches[4] : ''; + } + $this->path = isset($matches[5]) ? $matches[5] : ''; + if (!empty($matches[6])) { + $this->query = isset($matches[7]) ? $matches[7] : ''; + } + if (!empty($matches[8])) { + $this->fragment = isset($matches[9]) ? $matches[9] : ''; + } + } + } elseif (is_array($uri)) { + $this->scheme = isset($uri['scheme']) ? $uri['scheme'] : null; + $this->authority = isset($uri['authority']) ? $uri['authority'] : null; + $this->path = isset($uri['path']) ? $uri['path'] : null; + $this->query = isset($uri['query']) ? $uri['query'] : null; + $this->fragment = isset($uri['fragment']) ? $uri['fragment'] : null; + } + } + + + /** Returns true if this is an absolute (complete) URI + * @return boolean + */ + public function isAbsolute() + { + return $this->scheme !== null; + } + + /** Returns true if this is an relative (partial) URI + * @return boolean + */ + public function isRelative() + { + return $this->scheme === null; + } + + /** Returns the scheme of the URI (e.g. http) + * @return string + */ + public function getScheme() + { + return $this->scheme; + } + + /** Sets the scheme of the URI (e.g. http) + * @param string $scheme The new value for the scheme of the URI + */ + public function setScheme($scheme) + { + $this->scheme = $scheme; + } + + /** Returns the authority of the URI (e.g. www.example.com:8080) + * @return string + */ + public function getAuthority() + { + return $this->authority; + } + + /** Sets the authority of the URI (e.g. www.example.com:8080) + * @param string $authority The new value for the authority component of the URI + */ + public function setAuthority($authority) + { + $this->authority = $authority; + } + + /** Returns the path of the URI (e.g. /foo/bar) + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** Set the path of the URI (e.g. /foo/bar) + * @param string $path The new value for the path component of the URI + */ + public function setPath($path) + { + $this->path = $path; + } + + /** Returns the query string part of the URI (e.g. foo=bar) + * @return string + */ + public function getQuery() + { + return $this->query; + } + + /** Set the query string of the URI (e.g. foo=bar) + * @param string $query The new value for the query string component of the URI + */ + public function setQuery($query) + { + $this->query = $query; + } + + /** Returns the fragment part of the URI (i.e. after the #) + * @return string + */ + public function getFragment() + { + return $this->fragment; + } + + /** Set the fragment of the URI (i.e. after the #) + * @param string $fragment The new value for the fragment component of the URI + */ + public function setFragment($fragment) + { + $this->fragment = $fragment; + } + + + /** + * Normalises the path of this URI if it has one. Normalising a path means + * that any unnecessary '.' and '..' segments are removed. For example, the + * URI http://example.com/a/b/../c/./d would be normalised to + * http://example.com/a/c/d + * + * @return object EasyRdf_ParsedUri + */ + public function normalise() + { + if (empty($this->path)) { + return $this; + } + + // Remove ./ from the start + if (substr($this->path, 0, 2) == './') { + // Remove both characters + $this->path = substr($this->path, 2); + } + + // Remove /. from the end + if (substr($this->path, -2) == '/.') { + // Remove only the last dot, not the slash! + $this->path = substr($this->path, 0, -1); + } + + if (substr($this->path, -3) == '/..') { + $this->path .= '/'; + } + + // Split the path into its segments + $segments = explode('/', $this->path); + $newSegments = array(); + + // Remove all unnecessary '.' and '..' segments + foreach ($segments as $segment) { + if ($segment == '..') { + // Remove the previous part of the path + $count = count($newSegments); + if ($count > 0 && $newSegments[$count-1]) { + array_pop($newSegments); + } + } elseif ($segment == '.') { + // Ignore + continue; + } else { + array_push($newSegments, $segment); + } + } + + // Construct the new normalised path + $this->path = implode('/', $newSegments); + + // Allow easy chaining of methods + return $this; + } + + /** + * Resolves a relative URI using this URI as the base URI. + */ + public function resolve($relUri) + { + // If it is a string, then convert it to a parsed object + if (is_string($relUri)) { + $relUri = new EasyRdf_ParsedUri($relUri); + } + + // This code is based on the pseudocode in section 5.2.2 of RFC3986 + $target = new EasyRdf_ParsedUri(); + if ($relUri->scheme) { + $target->scheme = $relUri->scheme; + $target->authority = $relUri->authority; + $target->path = $relUri->path; + $target->query = $relUri->query; + } else { + if ($relUri->authority) { + $target->authority = $relUri->authority; + $target->path = $relUri->path; + $target->query = $relUri->query; + } else { + if (empty($relUri->path)) { + $target->path = $this->path; + if ($relUri->query) { + $target->query = $relUri->query; + } else { + $target->query = $this->query; + } + } else { + if (substr($relUri->path, 0, 1) == '/') { + $target->path = $relUri->path; + } else { + $path = $this->path; + $lastSlash = strrpos($path, '/'); + if ($lastSlash !== false) { + $path = substr($path, 0, $lastSlash + 1); + } else { + $path = '/'; + } + + $target->path .= $path . $relUri->path; + } + $target->query = $relUri->query; + } + $target->authority = $this->authority; + } + $target->scheme = $this->scheme; + } + + $target->fragment = $relUri->fragment; + + $target->normalise(); + + return $target; + } + + /** Convert the parsed URI back into a string + * + * @return string The URI as a string + */ + public function toString() + { + $str = ''; + if ($this->scheme !== null) { + $str .= $this->scheme . ':'; + } + if ($this->authority !== null) { + $str .= '//' . $this->authority; + } + $str .= $this->path; + if ($this->query !== null) { + $str .= '?' . $this->query; + } + if ($this->fragment !== null) { + $str .= '#' . $this->fragment; + } + return $str; + } + + /** Magic method to convert the URI, when casted, back to a string + * + * @return string The URI as a string + */ + public function __toString() + { + return $this->toString(); + } +} diff --git a/core/modules/rdf/tests/src/Traits/RdfParsingTrait.php b/core/modules/rdf/tests/src/Traits/RdfParsingTrait.php index a721a4ac63..01aebe369a 100644 --- a/core/modules/rdf/tests/src/Traits/RdfParsingTrait.php +++ b/core/modules/rdf/tests/src/Traits/RdfParsingTrait.php @@ -4,6 +4,11 @@ use Drupal\Core\Url; +/** + * Override \EasyRdf_ParsedUri for PHP 7.4 compatibilty. + */ +class_alias('\Drupal\Tests\rdf\Traits\EasyRdf_ParsedUri', '\EasyRdf_ParsedUri'); + /** * Defines a trait for parsing RDF properties from HTML. */ diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermLocalizedTranslation.php b/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermLocalizedTranslation.php index 844fb858b5..d8308c72b4 100644 --- a/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermLocalizedTranslation.php +++ b/core/modules/taxonomy/src/Plugin/migrate/source/d6/TermLocalizedTranslation.php @@ -70,7 +70,13 @@ public function prepareRow(Row $row) { $query->condition('lt.language', $language); $query->addField('lt', 'translation'); $results = $query->execute()->fetchAssoc(); - $row->setSourceProperty($other_property . '_translated', $results['translation']); + if ($results) { + $row->setSourceProperty($other_property . '_translated', $results['translation']); + } + else { + // The translation does not exist. + $row->setSourceProperty($other_property . '_translated', NULL); + } parent::prepareRow($row); } diff --git a/core/modules/taxonomy/tests/src/Kernel/Views/ArgumentValidatorTermTest.php b/core/modules/taxonomy/tests/src/Kernel/Views/ArgumentValidatorTermTest.php index aa4269afc5..07e3ea64b4 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Views/ArgumentValidatorTermTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Views/ArgumentValidatorTermTest.php @@ -61,7 +61,7 @@ public function testArgumentValidatorTerm() { $view->initHandlers(); // Test the single validator for term IDs. - $view->argument['tid']->validator->options['type'] = 'tid'; + $view->argument['tid']->options['validate_options']['multiple'] = 0; // Pass in a single valid term. foreach ($this->terms as $term) { @@ -78,7 +78,7 @@ public function testArgumentValidatorTerm() { $view->argument['tid']->argument_validated = NULL; // Test the multiple validator for term IDs. - $view->argument['tid']->validator->options['type'] = 'tids'; + $view->argument['tid']->options['validate_options']['multiple'] = 1; $view->argument['tid']->options['break_phrase'] = TRUE; // Pass in a single term. diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php index 87b574387b..a58d9fc951 100644 --- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php @@ -98,7 +98,7 @@ public function getPath() { protected function isDefaultTabPath() { $menu = $this->getOption('menu'); $tab_options = $this->getOption('tab_options'); - return $menu['type'] == 'default tab' && !empty($tab_options['type']) && $tab_options['type'] != 'none'; + return $menu && $menu['type'] == 'default tab' && !empty($tab_options['type']) && $tab_options['type'] != 'none'; } /** diff --git a/core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php b/core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php index e948273ec0..53003e3cba 100644 --- a/core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php +++ b/core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php @@ -5,6 +5,7 @@ use Drupal\Component\Render\FormattableMarkup; use Drupal\comment\Tests\CommentTestTrait; use Drupal\Tests\views\Functional\ViewTestBase; +use Drupal\views\Plugin\views\filter\NumericFilter; use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\HandlerBase; use Drupal\views\Plugin\views\filter\InOperator; @@ -83,7 +84,7 @@ public function testHandlers() { if ($type == 'filter') { $handler = $this->container->get("plugin.manager.views.$type")->getHandler($item); // Set the value to use for the filter based on the filter type. - if ($handler instanceof InOperator) { + if ($handler instanceof InOperator || $handler instanceof NumericFilter) { $options['value'] = [1]; } else { diff --git a/core/modules/views/tests/src/Kernel/Plugin/FieldOrLanguageJoinTest.php b/core/modules/views/tests/src/Kernel/Plugin/FieldOrLanguageJoinTest.php index 34e4f93000..76be7154df 100644 --- a/core/modules/views/tests/src/Kernel/Plugin/FieldOrLanguageJoinTest.php +++ b/core/modules/views/tests/src/Kernel/Plugin/FieldOrLanguageJoinTest.php @@ -137,7 +137,7 @@ public function testLanguageBundleConditions() { // condition. $configuration = [ 'table' => 'node__field_tags', - 'left_table' => 'node', + 'left_table' => 'views_test_data', 'left_field' => 'nid', 'field' => 'entity_id', 'extra' => [ @@ -148,7 +148,7 @@ public function testLanguageBundleConditions() { ], ]; $join_info = $this->buildJoin($view, $configuration, 'node__field_tags'); - $this->assertContains('AND (node__field_tags.langcode = .langcode)', $join_info['condition']); + $this->assertContains('AND (node__field_tags.langcode = views_test_data.langcode)', $join_info['condition']); array_unshift($configuration['extra'], [ 'field' => 'deleted', @@ -156,7 +156,7 @@ public function testLanguageBundleConditions() { 'numeric' => TRUE, ]); $join_info = $this->buildJoin($view, $configuration, 'node__field_tags'); - $this->assertContains('AND (node__field_tags.langcode = .langcode)', $join_info['condition']); + $this->assertContains('AND (node__field_tags.langcode = views_test_data.langcode)', $join_info['condition']); // Replace the language condition with a bundle condition. $configuration['extra'][1] = [ @@ -173,7 +173,7 @@ public function testLanguageBundleConditions() { 'field' => 'langcode', ]; $join_info = $this->buildJoin($view, $configuration, 'node__field_tags'); - $this->assertContains('AND (node__field_tags.bundle = :views_join_condition_1 OR node__field_tags.langcode = .langcode)', $join_info['condition']); + $this->assertContains('AND (node__field_tags.bundle = :views_join_condition_1 OR node__field_tags.langcode = views_test_data.langcode)', $join_info['condition']); } /** diff --git a/core/modules/views/tests/src/Unit/Plugin/field/FieldPluginBaseTest.php b/core/modules/views/tests/src/Unit/Plugin/field/FieldPluginBaseTest.php index 623436e6ba..b0b6850deb 100644 --- a/core/modules/views/tests/src/Unit/Plugin/field/FieldPluginBaseTest.php +++ b/core/modules/views/tests/src/Unit/Plugin/field/FieldPluginBaseTest.php @@ -136,6 +136,9 @@ protected function setUp() { $this->executable = $this->getMockBuilder('Drupal\views\ViewExecutable') ->disableOriginalConstructor() ->getMock(); + $this->executable->style_plugin = $this->getMockBuilder('Drupal\views\Plugin\views\style\StylePluginBase') + ->disableOriginalConstructor() + ->getMock(); $this->display = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase') ->disableOriginalConstructor() ->getMock(); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php b/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php index 2a8faf90e3..28766fd829 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/FieldSqlStorageTest.php @@ -148,7 +148,7 @@ public function testFieldLoad() { $this->assertEqual($entity->{$this->fieldName}[$delta]->value, $value); } else { - $this->assertFalse(array_key_exists($delta, $entity->{$this->fieldName})); + $this->assertArrayNotHasKey($delta, $entity->{$this->fieldName}); } } } @@ -160,7 +160,7 @@ public function testFieldLoad() { $this->assertEqual($entity->{$this->fieldName}[$delta]->value, $value); } else { - $this->assertFalse(array_key_exists($delta, $entity->{$this->fieldName})); + $this->assertArrayNotHasKey($delta, $entity->{$this->fieldName}); } } @@ -171,7 +171,7 @@ public function testFieldLoad() { $connection->insert($this->table)->fields($columns)->values($values)->execute(); $connection->insert($this->revisionTable)->fields($columns)->values($values)->execute(); $entity = $storage->load($entity->id()); - $this->assertFalse(array_key_exists($unavailable_langcode, $entity->{$this->fieldName})); + $this->assertArrayNotHasKey($unavailable_langcode, $entity->{$this->fieldName}); } /** diff --git a/core/tests/Drupal/KernelTests/Core/Test/Comparator/MarkupInterfaceComparatorTest.php b/core/tests/Drupal/KernelTests/Core/Test/Comparator/MarkupInterfaceComparatorTest.php index c02582c6f7..3c823be5d0 100644 --- a/core/tests/Drupal/KernelTests/Core/Test/Comparator/MarkupInterfaceComparatorTest.php +++ b/core/tests/Drupal/KernelTests/Core/Test/Comparator/MarkupInterfaceComparatorTest.php @@ -6,7 +6,6 @@ use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\KernelTests\KernelTestBase; use Drupal\TestTools\Comparator\MarkupInterfaceComparator; -use PHPUnit\Framework\Error\Error; use PHPUnit\Framework\Error\Notice; use SebastianBergmann\Comparator\Factory; use SebastianBergmann\Comparator\ComparisonFailure; @@ -51,8 +50,9 @@ protected function setUp() { * - test expected value, * - test actual value, * - a bool indicating the expected return value of ::accepts, - * - a value indicating the expected result of ::assertEquals, either TRUE - * or a class name of an object thrown. + * - a value indicating the expected result of ::assertEquals, TRUE if + * comparison should match, FALSE if error, or a class name of an object + * thrown. */ public function dataSetProvider() { return [ @@ -114,7 +114,7 @@ public function dataSetProvider() { (object) ['goldfinger'], new TranslatableMarkup('goldfinger'), FALSE, - Error::class, + FALSE, ], 'string vs string, equal' => [ 'goldfinger', @@ -148,7 +148,12 @@ public function testAssertEquals($expected, $actual, $accepts_result, $equals_re $this->assertTrue($equals_result); } catch (\Throwable $e) { - $this->assertInstanceOf($equals_result, $e); + if ($equals_result === FALSE) { + $this->assertNotNull($e->getMessage()); + } + else { + $this->assertInstanceOf($equals_result, $e); + } } } diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php index 17a6703ca7..a74c1cbbd0 100644 --- a/core/tests/Drupal/KernelTests/KernelTestBase.php +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php @@ -607,9 +607,9 @@ protected function tearDown() { // Remove all prefixed tables. $original_connection_info = Database::getConnectionInfo('simpletest_original_default'); - $original_prefix = $original_connection_info['default']['prefix']['default']; + $original_prefix = $original_connection_info['default']['prefix']['default'] ?? NULL; $test_connection_info = Database::getConnectionInfo('default'); - $test_prefix = $test_connection_info['default']['prefix']['default']; + $test_prefix = $test_connection_info['default']['prefix']['default'] ?? NULL; if ($original_prefix != $test_prefix) { $tables = Database::getConnection()->schema()->findTables('%'); foreach ($tables as $table) { diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php index 20aa53423b..e3028748bf 100644 --- a/core/tests/Drupal/Tests/BrowserTestBase.php +++ b/core/tests/Drupal/Tests/BrowserTestBase.php @@ -350,11 +350,15 @@ protected function getResponseLogHandler() { $html_output = 'Called from ' . $caller['function'] . ' line ' . $caller['line']; $html_output .= '
' . $request->getMethod() . ' request to: ' . $request->getUri(); + // Get the response body as a string. Any errors are silenced as + // tests should not fail if there is a problem. On PHP 7.4 + // \Drupal\Tests\migrate\Functional\process\DownloadFunctionalTest + // fails without the usage of a silence operator. + $body = @(string) $response->getBody(); // On redirect responses (status code starting with '3') we need // to remove the meta tag that would do a browser refresh. We // don't want to redirect developers away when they look at the // debug output file in their browser. - $body = $response->getBody(); $status_code = (string) $response->getStatusCode(); if ($status_code[0] === '3') { $body = preg_replace('##', '', $body, 1); diff --git a/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php b/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php index af30711717..d3f973dc39 100644 --- a/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Asset/CssCollectionRendererUnitTest.php @@ -290,7 +290,7 @@ public function testRenderInvalidType() { 'browsers' => [], 'data' => 'http://example.com/popular.js', ]; - $this->renderer->render($css_group); + $this->renderer->render([$css_group]); } } diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/YamlFileLoaderTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/YamlFileLoaderTest.php index 4093b6a2eb..26ffcd4b84 100644 --- a/core/tests/Drupal/Tests/Core/DependencyInjection/YamlFileLoaderTest.php +++ b/core/tests/Drupal/Tests/Core/DependencyInjection/YamlFileLoaderTest.php @@ -34,7 +34,11 @@ class: \Drupal\Core\ExampleClass YAML; vfsStream::setup('drupal', NULL, [ - 'modules/example/example.yml' => $yml, + 'modules' => [ + 'example' => [ + 'example.yml' => $yml, + ], + ], ]); $builder = new ContainerBuilder();