From c15cf7d23406799893586553128523dcdcf5b766 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Sun, 25 Jan 2015 12:02:54 +0000 Subject: [PATCH] =?UTF-8?q?Revert=20"Issue=20#1916790=20by=20plach,=20YesC?= =?UTF-8?q?T,=20penyaskito,=20G=C3=A1bor=20Hojtsy,=20das-peter,=20herom,?= =?UTF-8?q?=20larowlan:=20Convert=20translation=20metadata=20into=20regula?= =?UTF-8?q?r=20entity=20fields"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 920382d4ea5885e43d19c107c9d6351021cbdbad. --- .../Tests/BlockContentTranslationUITest.php | 6 +- .../comment/src/CommentTranslationHandler.php | 29 --- .../src/Tests/CommentTranslationUITest.php | 63 ++---- .../content_translation.admin.inc | 4 +- .../content_translation.install | 72 ++++++ .../content_translation.module | 209 ++++++++++++------ .../content_translation.services.yml | 6 - .../src/ContentTranslationHandler.php | 192 ++++------------ .../ContentTranslationHandlerInterface.php | 7 - .../src/ContentTranslationManager.php | 19 -- .../ContentTranslationManagerInterface.php | 25 --- .../src/ContentTranslationMetadataWrapper.php | 145 ------------ ...entTranslationMetadataWrapperInterface.php | 122 ---------- .../src/ContentTranslationUpdatesManager.php | 89 -------- .../ContentTranslationController.php | 41 +--- .../ContentTranslationConfigImportTest.php | 111 ---------- .../Tests/ContentTranslationSyncImageTest.php | 7 +- .../src/Tests/ContentTranslationTestBase.php | 9 +- .../src/Tests/ContentTranslationUITest.php | 14 +- ...erenceFieldTranslatedReferenceViewTest.php | 1 - .../PrivateFileOnTranslatedEntityTest.php | 1 - .../node/src/Tests/NodeTranslationUITest.php | 12 +- .../path/src/Tests/PathLanguageTest.php | 1 - .../Tests/TaxonomyTranslationTestTrait.php | 3 +- .../src/Tests/TermTranslationUITest.php | 4 +- .../src/Tests/Views/TaxonomyTermViewTest.php | 2 - core/modules/user/src/Entity/User.php | 2 +- .../user/src/ProfileTranslationHandler.php | 19 +- .../src/Tests/SearchMultilingualTest.php | 1 - sites/default/default.settings.php | 5 - 30 files changed, 307 insertions(+), 914 deletions(-) delete mode 100644 core/modules/content_translation/src/ContentTranslationMetadataWrapper.php delete mode 100644 core/modules/content_translation/src/ContentTranslationMetadataWrapperInterface.php delete mode 100644 core/modules/content_translation/src/ContentTranslationUpdatesManager.php delete mode 100644 core/modules/content_translation/src/Tests/ContentTranslationConfigImportTest.php diff --git a/core/modules/block_content/src/Tests/BlockContentTranslationUITest.php b/core/modules/block_content/src/Tests/BlockContentTranslationUITest.php index 3d27fe60b89d..49acdf1588fe 100644 --- a/core/modules/block_content/src/Tests/BlockContentTranslationUITest.php +++ b/core/modules/block_content/src/Tests/BlockContentTranslationUITest.php @@ -158,9 +158,11 @@ public function testDisabledBundle() { $enabled_block_content = $this->createBlockContent(); $disabled_block_content = $this->createBlockContent(FALSE, $bundle->id()); - // Make sure that only a single row was inserted into the block table. - $rows = db_query('SELECT * FROM {block_content_field_data} WHERE id = :id', array(':id' => $enabled_block_content->id()))->fetchAll(); + // Make sure that only a single row was inserted into the + // {content_translation} table. + $rows = db_query('SELECT * FROM {content_translation}')->fetchAll(); $this->assertEqual(1, count($rows)); + $this->assertEqual($enabled_block_content->id(), reset($rows)->entity_id); } } diff --git a/core/modules/comment/src/CommentTranslationHandler.php b/core/modules/comment/src/CommentTranslationHandler.php index e9a538b29c9f..aa796b1085e7 100644 --- a/core/modules/comment/src/CommentTranslationHandler.php +++ b/core/modules/comment/src/CommentTranslationHandler.php @@ -9,28 +9,12 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\content_translation\ContentTranslationHandler; -use Drupal\Core\Form\FormStateInterface; /** * Defines the translation handler for comments. */ class CommentTranslationHandler extends ContentTranslationHandler { - /** - * {@inheritdoc} - */ - public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) { - parent::entityFormAlter($form, $form_state, $entity); - - if (isset($form['content_translation'])) { - // We do not need to show these values on comment forms: they inherit the - // basic comment property values. - $form['content_translation']['status']['#access'] = FALSE; - $form['content_translation']['name']['#access'] = FALSE; - $form['content_translation']['created']['#access'] = FALSE; - } - } - /** * {@inheritdoc} */ @@ -38,17 +22,4 @@ protected function entityFormTitle(EntityInterface $entity) { return t('Edit comment @subject', array('@subject' => $entity->label())); } - /** - * {@inheritdoc} - */ - public function entityFormEntityBuild($entity_type, EntityInterface $entity, array $form, FormStateInterface $form_state) { - if ($form_state->hasValue('content_translation')) { - $translation = &$form_state->getValue('content_translation'); - /** @var \Drupal\comment\CommentInterface $entity */ - $translation['status'] = $entity->isPublished(); - $translation['name'] = $entity->getAuthorName(); - } - parent::entityFormEntityBuild($entity_type, $entity, $form, $form_state); - } - } diff --git a/core/modules/comment/src/Tests/CommentTranslationUITest.php b/core/modules/comment/src/Tests/CommentTranslationUITest.php index 824c63bf5c6d..a0d13a9ff1cf 100644 --- a/core/modules/comment/src/Tests/CommentTranslationUITest.php +++ b/core/modules/comment/src/Tests/CommentTranslationUITest.php @@ -9,7 +9,6 @@ use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; use Drupal\content_translation\Tests\ContentTranslationUITest; -use Drupal\language\Entity\ConfigurableLanguage; /** * Tests the Comment Translation UI. @@ -109,58 +108,30 @@ protected function getNewEntityValues($langcode) { } /** - * {@inheritdoc} + * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::assertPublishedStatus(). */ - protected function doTestPublishedStatus() { - $entity_manager = \Drupal::entityManager(); - $storage = $entity_manager->getStorage($this->entityTypeId); - - $storage->resetCache(); - $entity = $storage->load($this->entityId); + protected function assertPublishedStatus() { + parent::assertPublishedStatus(); + $entity = entity_load($this->entityTypeId, $this->entityId); + $user = $this->drupalCreateUser(array('access comments')); + $this->drupalLogin($user); + $languages = $this->container->get('language_manager')->getLanguages(); - // Unpublish translations. + // Check that simple users cannot see unpublished field translations. foreach ($this->langcodes as $index => $langcode) { + $translation = $this->getTranslation($entity, $langcode); + $value = $this->getValue($translation, 'comment_body', $langcode); + $this->drupalGet($entity->urlInfo(), array('language' => $languages[$langcode])); if ($index > 0) { - $edit = array('status' => 0); - $url = $entity->urlInfo('edit-form', array('language' => ConfigurableLanguage::load($langcode))); - $this->drupalPostForm($url, $edit, $this->getFormSubmitAction($entity, $langcode)); - $storage->resetCache(); - $entity = $storage->load($this->entityId); - $this->assertFalse($this->manager->getTranslationMetadata($entity->getTranslation($langcode))->isPublished(), 'The translation has been correctly unpublished.'); + $this->assertNoRaw($value, 'Unpublished field translation is not shown.'); + } + else { + $this->assertRaw($value, 'Published field translation is shown.'); } - } - } - - /** - * {@inheritdoc} - */ - protected function doTestAuthoringInfo() { - $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); - $path = $entity->getSystemPath('edit-form'); - $languages = $this->container->get('language_manager')->getLanguages(); - $values = array(); - - // Post different authoring information for each translation. - foreach ($this->langcodes as $langcode) { - $user = $this->drupalCreateUser(); - $values[$langcode] = array( - 'uid' => $user->id(), - 'created' => REQUEST_TIME - mt_rand(0, 1000), - ); - $edit = array( - 'name' => $user->getUsername(), - 'date[date]' => format_date($values[$langcode]['created'], 'custom', 'Y-m-d'), - 'date[time]' => format_date($values[$langcode]['created'], 'custom', 'H:i:s'), - ); - $this->drupalPostForm($path, $edit, $this->getFormSubmitAction($entity, $langcode), array('language' => $languages[$langcode])); } - $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); - foreach ($this->langcodes as $langcode) { - $metadata = $this->manager->getTranslationMetadata($entity->getTranslation($langcode)); - $this->assertEqual($metadata->getAuthor()->id(), $values[$langcode]['uid'], 'Translation author correctly stored.'); - $this->assertEqual($metadata->getCreatedTime(), $values[$langcode]['created'], 'Translation date correctly stored.'); - } + // Login as translator again to ensure subsequent tests do not break. + $this->drupalLogin($this->translator); } /** diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc index b65eeeac5d5b..d8126526846b 100644 --- a/core/modules/content_translation/content_translation.admin.inc +++ b/core/modules/content_translation/content_translation.admin.inc @@ -97,8 +97,7 @@ function _content_translation_form_language_content_settings_form_alter(array &$ if ($fields) { foreach ($fields as $field_name => $definition) { // Allow to configure only fields supporting multilingual storage. - // We skip our own fields as they are always translatable. - if (!empty($storage_definitions[$field_name]) && $storage_definitions[$field_name]->isTranslatable() && $storage_definitions[$field_name]->getProvider() != 'content_translation') { + if (!empty($storage_definitions[$field_name]) && $storage_definitions[$field_name]->isTranslatable()) { $form['settings'][$entity_type_id][$bundle]['fields'][$field_name] = array( '#label' => $definition->getLabel(), '#type' => 'checkbox', @@ -339,5 +338,4 @@ function content_translation_form_language_content_settings_submit(array $form, // Ensure entity and menu router information are correctly rebuilt. \Drupal::entityManager()->clearCachedDefinitions(); \Drupal::service('router.builder_indicator')->setRebuildNeeded(); - \Drupal::service('content_translation.updates_manager')->updateDefinitions($entity_types); } diff --git a/core/modules/content_translation/content_translation.install b/core/modules/content_translation/content_translation.install index d0963d584983..c6e173bd112e 100644 --- a/core/modules/content_translation/content_translation.install +++ b/core/modules/content_translation/content_translation.install @@ -5,9 +5,81 @@ * Installation functions for Content Translation module. */ +use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl; +/** + * Implements hook_schema(). + */ +function content_translation_schema() { + $schema['content_translation'] = array( + 'description' => 'Table to track content translations', + 'fields' => array( + 'entity_type' => array( + 'type' => 'varchar', + 'length' => EntityTypeInterface::ID_MAX_LENGTH, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The entity type this translation relates to', + ), + 'entity_id' => array( + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The entity id this translation relates to', + ), + 'langcode' => array( + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The target language for this translation.', + ), + 'source' => array( + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The source language from which this translation was created.', + ), + 'outdated' => array( + 'description' => 'A boolean indicating whether this translation needs to be updated.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'uid' => array( + 'description' => 'The author of this translation.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'status' => array( + 'description' => 'Boolean indicating whether the translation is visible to non-translators.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 1, + ), + 'created' => array( + 'description' => 'The Unix timestamp when the translation was created.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'changed' => array( + 'description' => 'The Unix timestamp when the translation was most recently saved.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('entity_type', 'entity_id', 'langcode'), + ); + return $schema; +} + /** * Implements hook_install(). */ diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index 4277ea025661..0c675584a2e9 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -6,10 +6,9 @@ */ use Drupal\Core\Access\AccessResult; -use Drupal\Core\Entity\ContentEntityFormInterface; use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\ContentEntityFormInterface; use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Routing\RouteMatchInterface; @@ -75,9 +74,8 @@ function content_translation_language_types_info_alter(array &$language_types) { * Implements hook_entity_type_alter(). * * The content translation UI relies on the entity info to provide its features. - * See the documentation of hook_entity_type_build() in the Entity API - * documentation for more details on all the entity info keys that may be - * defined. + * See the documentation of hook_entity_type_build() in the Entity API documentation + * for more details on all the entity info keys that may be defined. * * To make Content Translation automatically support an entity type some keys * may need to be defined, but none of them is required unless the entity path @@ -85,27 +83,17 @@ function content_translation_language_types_info_alter(array &$language_types) { * "/taxonomy/term/{taxonomy_term}"), in which case at least the 'canonical' key * in the 'links' entity info property must be defined. * - * Every entity type needs a translation handler to be translated. This can be - * specified through the 'translation' key in the 'handlers' entity annotation - * property. If an entity type is translatable and no translation handler is - * defined, \Drupal\content_translation\ContentTranslationHandler will be - * assumed. Every translation handler must implement + * Every entity type needs a translation controller to be translated. This can + * be specified through the 'translation' key in the 'handlers' entity + * annotation property. If an entity type is translatable and no translation + * handler is defined, \Drupal\content_translation\ContentTranslationHandler + * will be assumed. Every translation handler must implement * \Drupal\content_translation\ContentTranslationHandlerInterface. * - * To implement its business logic the content translation UI relies on various - * metadata items describing the translation state. The default implementation - * is provided by \Drupal\content_translation\ContentTranslationMetadataWrapper, - * which is relying on one field for each metadata item (field definitions are - * provided by the translation handler). Entity types needing to customize this - * behavior can specify an alternative class through the - * 'content_translation_metadata' key in the entity type definition. Every - * content translation metadata wrapper needs to implement - * \Drupal\content_translation\ContentTranslationMetadataWrapperInterface. - * * If the entity paths match the default pattern above and there is no need for - * an entity-specific translation handler, Content Translation will provide - * built-in support for the entity. However enabling translation for each - * translatable bundle will be required. + * an entity-specific translation handler, Content Translation will + * provide built-in support for the entity. However enabling translation for + * each translatable bundle will be required. * * @see \Drupal\Core\Entity\Annotation\EntityType */ @@ -117,9 +105,6 @@ function content_translation_entity_type_alter(array &$entity_types) { if (!$entity_type->hasHandlerClass('translation')) { $entity_type->setHandlerClass('translation', 'Drupal\content_translation\ContentTranslationHandler'); } - if (!$entity_type->get('content_translation_metadata')) { - $entity_type->set('content_translation_metadata', 'Drupal\content_translation\ContentTranslationMetadataWrapper'); - } $translation = $entity_type->get('translation'); if (!$translation || !isset($translation['content_translation'])) { @@ -153,29 +138,6 @@ function content_translation_entity_bundle_info_alter(&$bundles) { } } -/** - * Implements hook_entity_base_field_info(). - */ -function content_translation_entity_base_field_info(EntityTypeInterface $entity_type) { - /** @var \Drupal\content_translation\ContentTranslationManagerInterface $manager */ - $manager = \Drupal::service('content_translation.manager'); - $entity_type_id = $entity_type->id(); - if ($manager->isSupported($entity_type_id)) { - $definitions = $manager->getTranslationHandler($entity_type_id)->getFieldDefinitions(); - $installed_storage_definitions = \Drupal::entityManager()->getLastInstalledFieldStorageDefinitions($entity_type_id); - // We return metadata storage fields whenever content translation is enabled - // or it was enabled before, so that we keep translation metadata around - // when translation is disabled. - // @todo Re-evaluate this approach and consider removing field storage - // definitions and the related field data if the entity type has no bundle - // enabled for translation, once base field purging is supported. - // See https://www.drupal.org/node/2282119. - if ($manager->isEnabled($entity_type_id) || array_intersect_key($definitions, $installed_storage_definitions)) { - return $definitions; - } - } -} - /** * Implements hook_field_info_alter(). * @@ -279,23 +241,133 @@ function content_translation_language_fallback_candidates_entity_view_alter(&$ca /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $context['data']; $entity_type_id = $entity->getEntityTypeId(); - /** @var \Drupal\content_translation\ContentTranslationManagerInterface $manager */ - $manager = \Drupal::service('content_translation.manager'); - if ($manager->isEnabled($entity_type_id, $entity->bundle())) { - $entity_type = $entity->getEntityType(); - $permission = $entity_type->getPermissionGranularity() == 'bundle' ? $permission = "translate {$entity->bundle()} $entity_type_id" : "translate $entity_type_id"; - $current_user = \Drupal::currentuser(); - if (!$current_user->hasPermission('translate any entity') && !$current_user->hasPermission($permission)) { - foreach ($entity->getTranslationLanguages() as $langcode => $language) { - $metadata = $manager->getTranslationMetadata($entity->getTranslation($langcode)); - if (!$metadata->isPublished()) { - unset($candidates[$langcode]); + $entity_type = $entity->getEntityType(); + $permission = $entity_type->getPermissionGranularity() == 'bundle' ? $permission = "translate {$entity->bundle()} $entity_type_id" : "translate $entity_type_id"; + $current_user = \Drupal::currentuser(); + if (!$current_user->hasPermission('translate any entity') && !$current_user->hasPermission($permission)) { + foreach ($entity->getTranslationLanguages() as $langcode => $language) { + if (empty($entity->translation[$langcode]['status'])) { + unset($candidates[$langcode]); + } + } + } +} + +/** + * Implements hook_entity_storage_load(). + */ +function content_translation_entity_storage_load(array $entities, $entity_type) { + $enabled_entities = array(); + + if (\Drupal::service('content_translation.manager')->isEnabled($entity_type)) { + foreach ($entities as $entity) { + if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) { + $enabled_entities[$entity->id()] = $entity; + } + } + } + + if (!empty($enabled_entities)) { + content_translation_load_translation_metadata($enabled_entities, $entity_type); + } +} + +/** + * Loads translation data into the given entities. + * + * @param array $entities + * The entities keyed by entity ID. + * @param string $entity_type + * The type of the entities. + */ +function content_translation_load_translation_metadata(array $entities, $entity_type) { + $query = 'SELECT * FROM {content_translation} te WHERE te.entity_type = :entity_type AND te.entity_id IN (:entity_id)'; + $result = db_query($query, array(':entity_type' => $entity_type, ':entity_id' => array_keys($entities))); + $exclude = array('entity_type', 'entity_id', 'langcode'); + foreach ($result as $record) { + $entity = $entities[$record->entity_id]; + // @todo Declare these as entity (translation?) properties. + foreach ($record as $field_name => $value) { + if (!in_array($field_name, $exclude)) { + $langcode = $record->langcode; + $entity->translation[$langcode][$field_name] = $value; + if (!$entity->hasTranslation($langcode)) { + $entity->initTranslation($langcode); } } } } } +/** + * Implements hook_entity_insert(). + */ +function content_translation_entity_insert(EntityInterface $entity) { + // Only do something if translation support for the given entity is enabled. + if (!($entity instanceof ContentEntityInterface) || !$entity->isTranslatable()) { + return; + } + + $fields = array('entity_type', 'entity_id', 'langcode', 'source', 'outdated', 'uid', 'status', 'created', 'changed'); + $query = db_insert('content_translation')->fields($fields); + + foreach ($entity->getTranslationLanguages() as $langcode => $language) { + $translation = isset($entity->translation[$langcode]) ? $entity->translation[$langcode] : array(); + + $translation += array( + 'source' => '', + 'uid' => \Drupal::currentUser()->id(), + 'outdated' => FALSE, + 'status' => TRUE, + 'created' => REQUEST_TIME, + 'changed' => REQUEST_TIME, + ); + + $translation['entity_type'] = $entity->getEntityTypeId(); + $translation['entity_id'] = $entity->id(); + $translation['langcode'] = $langcode; + + // Reorder values to match the schema. + $values = array(); + foreach ($fields as $field_name) { + $value = is_bool($translation[$field_name]) ? intval($translation[$field_name]) : $translation[$field_name]; + $values[$field_name] = $value; + } + $query->values($values); + } + + $query->execute(); +} + +/** + * Implements hook_entity_delete(). + */ +function content_translation_entity_delete(EntityInterface $entity) { + // Only do something if translation support for the given entity is enabled. + if (!($entity instanceof ContentEntityInterface) || !$entity->isTranslatable()) { + return; + } + + db_delete('content_translation') + ->condition('entity_type', $entity->getEntityTypeId()) + ->condition('entity_id', $entity->id()) + ->execute(); +} + +/** + * Implements hook_entity_update(). + */ +function content_translation_entity_update(EntityInterface $entity) { + // Only do something if translation support for the given entity is enabled. + if (!($entity instanceof ContentEntityInterface) || !$entity->isTranslatable()) { + return; + } + + // Delete and create to ensure no stale value remains behind. + content_translation_entity_delete($entity); + content_translation_entity_insert($entity); +} + /** * Implements hook_entity_extra_field_info(). */ @@ -357,18 +429,11 @@ function content_translation_form_field_ui_field_edit_form_alter(array &$form, F * Implements hook_entity_presave(). */ function content_translation_entity_presave(EntityInterface $entity) { - if ($entity instanceof ContentEntityInterface && $entity->isTranslatable() && !$entity->isNew()) { - // If we are creating a new translation we need to use the source language - // as original language, since source values are the only ones available to - // compare against. - if (!isset($entity->original)) { - $entity->original = entity_load_unchanged($entity->entityType(), $entity->id()); - } - $langcode = $entity->language()->getId(); - /** @var \Drupal\content_translation\ContentTranslationManagerInterface $manager */ - $manager = \Drupal::service('content_translation.manager'); - $source_langcode = !$entity->original->hasTranslation($langcode) ? $manager->getTranslationMetadata($entity)->getSource() : NULL; - \Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $langcode, $source_langcode); + if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) { + // @todo Avoid using request attributes once translation metadata become + // regular fields. + $attributes = \Drupal::request()->attributes; + \Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $entity->language()->getId(), $attributes->get('source_langcode')); } } diff --git a/core/modules/content_translation/content_translation.services.yml b/core/modules/content_translation/content_translation.services.yml index a06deaea48d1..8d4740ffde23 100644 --- a/core/modules/content_translation/content_translation.services.yml +++ b/core/modules/content_translation/content_translation.services.yml @@ -24,9 +24,3 @@ services: content_translation.manager: class: Drupal\content_translation\ContentTranslationManager arguments: ['@entity.manager'] - - content_translation.updates_manager: - class: Drupal\content_translation\ContentTranslationUpdatesManager - arguments: ['@entity.manager', '@entity.definition_update_manager'] - tags: - - { name: event_subscriber } diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php index 2d6b19d719ed..eb805477c01c 100644 --- a/core/modules/content_translation/src/ContentTranslationHandler.php +++ b/core/modules/content_translation/src/ContentTranslationHandler.php @@ -8,16 +8,13 @@ namespace Drupal\content_translation; use Drupal\Core\Access\AccessResult; -use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\Entity\EntityHandlerInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Render\Element; -use Drupal\user\Entity\User; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -26,7 +23,6 @@ * @ingroup entity_api */ class ContentTranslationHandler implements ContentTranslationHandlerInterface, EntityHandlerInterface { - use DependencySerializationTrait; /** * The type of the entity being translated. @@ -50,11 +46,14 @@ class ContentTranslationHandler implements ContentTranslationHandlerInterface, E protected $languageManager; /** - * The content translation manager. - * - * @var \Drupal\content_translation\ContentTranslationManagerInterface + * {@inheritdoc} */ - protected $manager; + public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { + return new static( + $entity_type, + $container->get('language_manager') + ); + } /** * Initializes an instance of the content translation controller. @@ -63,124 +62,11 @@ class ContentTranslationHandler implements ContentTranslationHandlerInterface, E * The info array of the given entity type. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * The language manager. - * @param \Drupal\content_translation\ContentTranslationManagerInterface $manager - * The content translation manager service. */ - public function __construct(EntityTypeInterface $entity_type, LanguageManagerInterface $language_manager, ContentTranslationManagerInterface $manager) { + public function __construct(EntityTypeInterface $entity_type, LanguageManagerInterface $language_manager) { $this->entityTypeId = $entity_type->id(); $this->entityType = $entity_type; $this->languageManager = $language_manager; - $this->manager = $manager; - } - - /** - * {@inheritdoc} - */ - public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { - return new static( - $entity_type, - $container->get('language_manager'), - $container->get('content_translation.manager') - ); - } - - /** - * {@inheritdoc} - */ - public function getFieldDefinitions() { - $definitions = array(); - - $definitions['content_translation_source'] = BaseFieldDefinition::create('language') - ->setLabel(t('Translation source')) - ->setDescription(t('The source language from which this translation was created.')) - ->setDefaultValue(LanguageInterface::LANGCODE_NOT_SPECIFIED) - ->setRevisionable(TRUE) - ->setTranslatable(TRUE); - - $definitions['content_translation_outdated'] = BaseFieldDefinition::create('boolean') - ->setLabel(t('Translation outdated')) - ->setDescription(t('A boolean indicating whether this translation needs to be updated.')) - ->setDefaultValue(FALSE) - ->setRevisionable(TRUE) - ->setTranslatable(TRUE); - - if (!$this->hasAuthor()) { - $definitions['content_translation_uid'] = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('Translation author')) - ->setDescription(t('The author of this translation.')) - ->setSetting('target_type', 'user') - ->setSetting('handler', 'default') - ->setRevisionable(TRUE) - ->setTranslatable(TRUE); - } - - if (!$this->hasPublishedStatus()) { - $definitions['content_translation_status'] = BaseFieldDefinition::create('boolean') - ->setLabel(t('Translation status')) - ->setDescription(t('A boolean indicating whether the translation is visible to non-translators.')) - ->setDefaultValue(TRUE) - ->setRevisionable(TRUE) - ->setTranslatable(TRUE); - } - - if (!$this->hasCreatedTime()) { - $definitions['content_translation_created'] = BaseFieldDefinition::create('created') - ->setLabel(t('Translation created time')) - ->setDescription(t('The Unix timestamp when the translation was created.')) - ->setRevisionable(TRUE) - ->setTranslatable(TRUE); - } - - if (!$this->hasChangedTime()) { - $definitions['content_translation_changed'] = BaseFieldDefinition::create('changed') - ->setLabel(t('Translation changed time')) - ->setDescription(t('The Unix timestamp when the translation was most recently saved.')) - ->setPropertyConstraints('value', array('EntityChanged' => array())) - ->setRevisionable(TRUE) - ->setTranslatable(TRUE); - } - - return $definitions; - } - - /** - * Checks whether the entity type supports author natively. - * - * @return bool - * TRUE if metadata is natively supported, FALSE otherwise. - */ - protected function hasAuthor() { - return is_subclass_of($this->entityType->getClass(), '\Drupal\user\EntityOwnerInterface'); - } - - /** - * Checks whether the entity type supports published status natively. - * - * @return bool - * TRUE if metadata is natively supported, FALSE otherwise. - */ - protected function hasPublishedStatus() { - return array_key_exists('status', \Drupal::entityManager()->getLastInstalledFieldStorageDefinitions($this->entityType->id())); - } - - /** - * Checks whether the entity type supports modification time natively. - * - * @return bool - * TRUE if metadata is natively supported, FALSE otherwise. - */ - protected function hasChangedTime() { - return is_subclass_of($this->entityType->getClass(), '\Drupal\Core\Entity\EntityChangedInterface'); - } - - /** - * Checks whether the entity type supports creation time natively. - * - * @return bool - * TRUE if metadata is natively supported, FALSE otherwise. - */ - protected function hasCreatedTime() { - return array_key_exists('created', \Drupal::entityManager()->getLastInstalledFieldStorageDefinitions($this->entityType->id())); } /** @@ -188,9 +74,9 @@ protected function hasCreatedTime() { */ public function retranslate(EntityInterface $entity, $langcode = NULL) { $updated_langcode = !empty($langcode) ? $langcode : $entity->language()->getId(); - foreach ($entity->getTranslationLanguages() as $langcode => $language) { - $this->manager->getTranslationMetadata($entity->getTranslation($langcode)) - ->setOutdated($langcode != $updated_langcode); + $translations = $entity->getTranslationLanguages(); + foreach ($translations as $langcode => $language) { + $entity->translation[$langcode]['outdated'] = $langcode != $updated_langcode; } } @@ -345,16 +231,20 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En ); // A new translation is enabled by default. - $metadata = $this->manager->getTranslationMetadata($entity); - $status = $new_translation || $metadata->isPublished(); + $status = $new_translation || $entity->translation[$form_langcode]['status']; // If there is only one published translation we cannot unpublish it, // since there would be nothing left to display. $enabled = TRUE; if ($status) { - $published = 0; - foreach ($entity->getTranslationLanguages() as $langcode => $language) { - $published += $this->manager->getTranslationMetadata($entity->getTranslation($langcode)) - ->isPublished(); + // A new translation is not available in the translation metadata, hence + // it should count as one more. + $published = $new_translation; + // When creating a brand new translation, $entity->translation is not + // set. + if (!$new_translation) { + foreach ($entity->translation as $translation) { + $published += $translation['status']; + } } $enabled = $published > 1; } @@ -370,7 +260,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En '#disabled' => !$enabled, ); - $translate = !$new_translation && $metadata->isOutdated(); + $translate = !$new_translation && $entity->translation[$form_langcode]['outdated']; if (!$translate) { $form['content_translation']['retranslate'] = array( '#type' => 'checkbox', @@ -394,8 +284,8 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En if ($new_translation) { $name = \Drupal::currentUser()->getUsername(); } - elseif (($account = $metadata->getAuthor()) && $account->id()) { - $name = $account->getUsername(); + elseif ($entity->translation[$form_langcode]['uid']) { + $name = user_load($entity->translation[$form_langcode]['uid'])->getUsername(); } $form['content_translation']['name'] = array( '#type' => 'textfield', @@ -406,13 +296,13 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En '#description' => t('Leave blank for %anonymous.', array('%anonymous' => \Drupal::config('user.settings')->get('anonymous'))), ); - $date = $new_translation ? REQUEST_TIME : $metadata->getCreatedTime(); + $date = $new_translation ? REQUEST_TIME : $entity->translation[$form_langcode]['created']; $form['content_translation']['created'] = array( '#type' => 'textfield', '#title' => t('Authored on'), '#maxlength' => 25, - '#description' => t('Format: %time. The date format is YYYY-MM-DD and %timezone is the time zone offset from UTC. Leave blank to use the time of form submission.', array('%time' => format_date(REQUEST_TIME, 'custom', 'Y-m-d H:i:s O'), '%timezone' => format_date(REQUEST_TIME, 'custom', 'O'))), - '#default_value' => $new_translation || !$date ? '' : format_date($date, 'custom', 'Y-m-d H:i:s O'), + '#description' => t('Format: %time. The date format is YYYY-MM-DD and %timezone is the time zone offset from UTC. Leave blank to use the time of form submission.', array('%time' => format_date($date, 'custom', 'Y-m-d H:i:s O'), '%timezone' => format_date($date, 'custom', 'O'))), + '#default_value' => $new_translation ? '' : format_date($date, 'custom', 'Y-m-d H:i:s O'), ); if (isset($language_widget)) { @@ -528,27 +418,35 @@ protected function addTranslatabilityClue(&$element) { public function entityFormEntityBuild($entity_type, EntityInterface $entity, array $form, FormStateInterface $form_state) { $form_object = $form_state->getFormObject(); $form_langcode = $form_object->getFormLangcode($form_state); - $values = &$form_state->getValue('content_translation', array()); - if ($values['name'] == \Drupal::config('user.settings')->get('anonymous')) { - $values['name'] = ''; + if (!isset($entity->translation[$form_langcode])) { + $entity->translation[$form_langcode] = array(); } + $values = $form_state->getValue('content_translation', array()); + $translation = &$entity->translation[$form_langcode]; - $metadata = $this->manager->getTranslationMetadata($entity); - $metadata->setAuthor(!empty($values['name']) && ($account = user_load_by_name($values['name'])) ? $account : User::load(0)); - $metadata->setPublished(!empty($values['status'])); - $metadata->setCreatedTime(!empty($values['created']) ? strtotime($values['created']) : REQUEST_TIME); - $metadata->setChangedTime(REQUEST_TIME); + // @todo Use the entity setter when all entities support multilingual + // properties. + $translation['uid'] = !empty($values['name']) && ($account = user_load_by_name($values['name'])) ? $account->id() : 0; + $translation['status'] = !empty($values['status']); + $translation['created'] = !empty($values['created']) ? strtotime($values['created']) : REQUEST_TIME; + $translation['changed'] = REQUEST_TIME; $source_langcode = $this->getSourceLangcode($form_state); if ($source_langcode) { - $metadata->setSource($source_langcode); + $translation['source'] = $source_langcode; } - $metadata->setOutdated(!empty($values['outdated'])); + $translation['outdated'] = !empty($values['outdated']); if (!empty($values['retranslate'])) { $this->retranslate($entity, $form_langcode); } + + // Set contextual information that can be reused during the storage phase. + // @todo Remove this once translation metadata are converted to regular + // fields. + $attributes = \Drupal::request()->attributes; + $attributes->set('source_langcode', $source_langcode); } /** diff --git a/core/modules/content_translation/src/ContentTranslationHandlerInterface.php b/core/modules/content_translation/src/ContentTranslationHandlerInterface.php index 12f59c17d848..5ab885816883 100644 --- a/core/modules/content_translation/src/ContentTranslationHandlerInterface.php +++ b/core/modules/content_translation/src/ContentTranslationHandlerInterface.php @@ -18,13 +18,6 @@ */ interface ContentTranslationHandlerInterface { - /** - * Returns a set of field definitions to be used to store metadata items. - * - * @return \Drupal\Core\Field\FieldDefinitionInterface[] - */ - public function getFieldDefinitions(); - /** * Checks if the user can perform the given operation on translations of the * wrapped entity. diff --git a/core/modules/content_translation/src/ContentTranslationManager.php b/core/modules/content_translation/src/ContentTranslationManager.php index a4d529ad2ffe..cff64c3f2d3a 100644 --- a/core/modules/content_translation/src/ContentTranslationManager.php +++ b/core/modules/content_translation/src/ContentTranslationManager.php @@ -7,9 +7,7 @@ namespace Drupal\content_translation; -use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Entity\EntityTypeInterface; use Drupal\language\Entity\ContentLanguageSettings; /** @@ -34,23 +32,6 @@ public function __construct(EntityManagerInterface $manager) { $this->entityManager = $manager; } - /** - * {@inheritdoc} - */ - function getTranslationHandler($entity_type_id) { - return $this->entityManager->getHandler($entity_type_id, 'translation'); - } - - /** - * {@inheritdoc} - */ - public function getTranslationMetadata(EntityInterface $translation) { - // We need a new instance of the metadata handler wrapping each translation. - $entity_type = $translation->getEntityType(); - $class = $entity_type->get('content_translation_metadata'); - return new $class($translation, $this->getTranslationHandler($entity_type->id())); - } - /** * {@inheritdoc} */ diff --git a/core/modules/content_translation/src/ContentTranslationManagerInterface.php b/core/modules/content_translation/src/ContentTranslationManagerInterface.php index 5afa2de35cf2..e3ae29f1d971 100644 --- a/core/modules/content_translation/src/ContentTranslationManagerInterface.php +++ b/core/modules/content_translation/src/ContentTranslationManagerInterface.php @@ -7,9 +7,6 @@ namespace Drupal\content_translation; -use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\EntityTypeInterface; - /** * Provides an interface for common functionality for content translation. */ @@ -34,28 +31,6 @@ public function getSupportedEntityTypes(); */ public function isSupported($entity_type_id); - /** - * Returns an instance of the Content translation handler. - * - * @param string $entity_type_id - * The type of the entity being translated. - * - * @return \Drupal\content_translation\ContentTranslationHandlerInterface - * An instance of the content translation handler. - */ - public function getTranslationHandler($entity_type_id); - - /** - * Returns an instance of the Content translation metadata. - * - * @param \Drupal\Core\Entity\EntityInterface $translation - * The entity translation whose metadata needs to be retrieved. - * - * @return \Drupal\content_translation\ContentTranslationMetadataWrapperInterface - * An instance of the content translation metadata. - */ - public function getTranslationMetadata(EntityInterface $translation); - /** * Sets the value for translatability of the given entity type bundle. * diff --git a/core/modules/content_translation/src/ContentTranslationMetadataWrapper.php b/core/modules/content_translation/src/ContentTranslationMetadataWrapper.php deleted file mode 100644 index 4b4d43ea94e3..000000000000 --- a/core/modules/content_translation/src/ContentTranslationMetadataWrapper.php +++ /dev/null @@ -1,145 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\content_translation\ContentTranslationMetadata. - */ - -namespace Drupal\content_translation; - -use Drupal\Core\Entity\EntityInterface; -use Drupal\user\UserInterface; - -/** - * Base class for content translation metadata wrappers. - */ -class ContentTranslationMetadataWrapper implements ContentTranslationMetadataWrapperInterface { - - /** - * The wrapped entity translation. - * - * @var \Drupal\Core\Entity\EntityInterface|\Drupal\Core\Entity\FieldableEntityInterface|\Drupal\Core\TypedData\TranslatableInterface - */ - protected $translation; - - /** - * The content translation handler. - * - * @var \Drupal\content_translation\ContentTranslationHandlerInterface - */ - protected $handler; - - /** - * Initializes an instance of the content translation metadata handler. - * - * @param EntityInterface $translation - * The entity translation to be wrapped. - * @param ContentTranslationHandlerInterface $handler - * The content translation handler. - */ - public function __construct(EntityInterface $translation, ContentTranslationHandlerInterface $handler) { - $this->translation = $translation; - $this->handler = $handler; - } - - /** - * {@inheritdoc} - */ - public function getSource() { - return $this->translation->get('content_translation_source')->value; - } - - /** - * {@inheritdoc} - */ - public function setSource($source) { - $this->translation->set('content_translation_source', $source); - return $this; - } - - /** - * {@inheritdoc} - */ - public function isOutdated() { - return (bool) $this->translation->get('content_translation_outdated')->value; - } - - /** - * {@inheritdoc} - */ - public function setOutdated($outdated) { - $this->translation->set('content_translation_outdated', $outdated); - return $this; - } - - /** - * {@inheritdoc} - */ - public function getAuthor() { - return $this->translation->hasField('content_translation_uid') ? $this->translation->get('content_translation_uid')->entity : $this->translation->getOwner(); - } - - /** - * {@inheritdoc} - */ - public function setAuthor(UserInterface $account) { - if ($this->translation->hasField('content_translation_uid')) { - $this->translation->set('content_translation_uid', $account->id()); - } - else { - $this->translation->setOwner($account); - } - return $this; - } - - /** - * {@inheritdoc} - */ - public function isPublished() { - $field_name = $this->translation->hasField('content_translation_status') ? 'content_translation_status' : 'status'; - return (bool) $this->translation->get($field_name)->value; - } - - /** - * {@inheritdoc} - */ - public function setPublished($published) { - $field_name = $this->translation->hasField('content_translation_status') ? 'content_translation_status' : 'status'; - $this->translation->set($field_name, $published); - return $this; - } - - /** - * {@inheritdoc} - */ - public function getCreatedTime() { - $field_name = $this->translation->hasField('content_translation_created') ? 'content_translation_created' : 'created'; - return $this->translation->get($field_name)->value; - } - - /** - * {@inheritdoc} - */ - public function setCreatedTime($timestamp) { - $field_name = $this->translation->hasField('content_translation_created') ? 'content_translation_created' : 'created'; - $this->translation->set($field_name, $timestamp); - return $this; - } - - /** - * {@inheritdoc} - */ - public function getChangedTime() { - return $this->translation->hasField('content_translation_changed') ? $this->translation->get('content_translation_changed')->value : $this->translation->getChangedTime(); - } - - /** - * {@inheritdoc} - */ - public function setChangedTime($timestamp) { - $field_name = $this->translation->hasField('content_translation_changed') ? 'content_translation_changed' : 'changed'; - $this->translation->set($field_name, $timestamp); - return $this; - } - -} diff --git a/core/modules/content_translation/src/ContentTranslationMetadataWrapperInterface.php b/core/modules/content_translation/src/ContentTranslationMetadataWrapperInterface.php deleted file mode 100644 index 4a0a65bc3269..000000000000 --- a/core/modules/content_translation/src/ContentTranslationMetadataWrapperInterface.php +++ /dev/null @@ -1,122 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\content_translation\ContentTranslationMetadataInterface. - */ - -namespace Drupal\content_translation; - -use Drupal\Core\Entity\EntityChangedInterface; -use Drupal\Core\Entity\EntityInterface; -use Drupal\user\UserInterface; - -/** - * Common interface for content translation metadata wrappers. - * - * This acts as a wrapper for an entity translation object, encapsulating the - * logic needed to retrieve translation metadata. - */ -interface ContentTranslationMetadataWrapperInterface extends EntityChangedInterface { - - /** - * Retrieves the source language for this translation. - * - * @return string - * The source language code. - */ - public function getSource(); - - /** - * Sets the source language for this translation. - * - * @param string $source - * The source language code. - * - * @return $this - */ - public function setSource($source); - - /** - * Returns the translation outdated status. - * - * @return bool - * TRUE if the translation is outdated, FALSE otherwise. - */ - public function isOutdated(); - - /** - * Sets the translation outdated status. - * - * @param bool $outdated - * TRUE if the translation is outdated, FALSE otherwise. - * - * @return $this - */ - public function setOutdated($outdated); - - /** - * Returns the translation author. - * - * @return \Drupal\user\UserInterface - * The user entity for the translation author. - */ - public function getAuthor(); - - /** - * Sets the translation author. - * - * @param \Drupal\user\UserInterface $account - * The translation author user entity. - * - * @return $this - */ - public function setAuthor(UserInterface $account); - - /** - * Returns the translation published status. - * - * @return bool - * TRUE if the translation is published, FALSE otherwise. - */ - public function isPublished(); - - /** - * Sets the translation published status. - * - * @param bool $published - * TRUE if the translation is published, FALSE otherwise. - * - * @return $this - */ - public function setPublished($published); - - /** - * Returns the translation creation timestamp. - * - * @return int - * The UNIX timestamp of when the translation was created. - */ - public function getCreatedTime(); - - /** - * Sets the translation creation timestamp. - * - * @param int $timestamp - * The UNIX timestamp of when the translation was created. - * - * @return $this - */ - public function setCreatedTime($timestamp); - - /** - * Sets the translation modification timestamp. - * - * @param int $timestamp - * The UNIX timestamp of when the translation was last modified. - * - * @return $this - */ - public function setChangedTime($timestamp); - -} diff --git a/core/modules/content_translation/src/ContentTranslationUpdatesManager.php b/core/modules/content_translation/src/ContentTranslationUpdatesManager.php deleted file mode 100644 index 8ebfa2700dcd..000000000000 --- a/core/modules/content_translation/src/ContentTranslationUpdatesManager.php +++ /dev/null @@ -1,89 +0,0 @@ -<?php - -/** - * Contains \Drupal\content_translation\ContentTranslationUpdatesManager. - */ - -namespace Drupal\content_translation; - -use Drupal\Core\Config\ConfigEvents; -use Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface; -use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Entity\EntityTypeInterface; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -/** - * Provides the logic needed to update field storage definitions when needed. - */ -class ContentTranslationUpdatesManager implements EventSubscriberInterface { - - /** - * The entity manager. - * - * @var \Drupal\Core\Entity\EntityManagerInterface - */ - protected $entityManager; - - /** - * The entity definition update manager. - * - * @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface - */ - protected $updateManager; - - /** - * Constructs an updates manager instance. - * - * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager - * The entity manager. - * @param \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface $update_manager - * The entity definition update manager. - */ - public function __construct(EntityManagerInterface $entity_manager, EntityDefinitionUpdateManagerInterface $update_manager) { - $this->entityManager = $entity_manager; - $this->updateManager = $update_manager; - } - - /** - * Executes field storage definition updates if needed. - * - * @param array $entity_types - * A list of entity type definitions to be processed. - */ - public function updateDefinitions(array $entity_types) { - // Handle field storage definition creation, if needed. - // @todo Generalize this code in https://www.drupal.org/node/2346013. - // @todo Handle initial values in https://www.drupal.org/node/2346019. - if ($this->updateManager->needsUpdates()) { - foreach ($entity_types as $entity_type_id => $entity_type) { - $storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); - $installed_storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type_id); - foreach (array_diff_key($storage_definitions, $installed_storage_definitions) as $storage_definition) { - /** @var $storage_definition \Drupal\Core\Field\FieldStorageDefinitionInterface */ - if ($storage_definition->getProvider() == 'content_translation') { - $this->entityManager->onFieldStorageDefinitionCreate($storage_definition); - } - } - } - } - } - - /** - * Listener for the ConfigImporter import event. - */ - public function onConfigImporterImport() { - $entity_types = array_filter($this->entityManager->getDefinitions(), function (EntityTypeInterface $entity_type) { - return $entity_type->isTranslatable(); - }); - $this->updateDefinitions($entity_types); - } - - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents() { - $events[ConfigEvents::IMPORT][] = ['onConfigImporterImport', 60]; - return $events; - } - -} diff --git a/core/modules/content_translation/src/Controller/ContentTranslationController.php b/core/modules/content_translation/src/Controller/ContentTranslationController.php index d00dee24a41b..dc74210738fa 100644 --- a/core/modules/content_translation/src/Controller/ContentTranslationController.php +++ b/core/modules/content_translation/src/Controller/ContentTranslationController.php @@ -7,43 +7,17 @@ namespace Drupal\content_translation\Controller; -use Drupal\content_translation\ContentTranslationManagerInterface; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; -use Symfony\Component\DependencyInjection\ContainerInterface; /** * Base class for entity translation controllers. */ class ContentTranslationController extends ControllerBase { - /** - * The content translation manager. - * - * @var \Drupal\content_translation\ContentTranslationManagerInterface - */ - protected $manager; - - /** - * Initializes a content translation controller. - * - * @param \Drupal\content_translation\ContentTranslationManagerInterface - * A content translation manager instance. - */ - public function __construct(ContentTranslationManagerInterface $manager) { - $this->manager = $manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static($container->get('content_translation.manager')); - } - /** * Populates target values with the source values. * @@ -74,7 +48,6 @@ public function overview(RouteMatchInterface $route_match, $entity_type_id = NUL $entity = $route_match->getParameter($entity_type_id); $account = $this->currentUser(); $handler = $this->entityManager()->getHandler($entity_type_id, 'translation'); - $manager = $this->manager; $languages = $this->languageManager()->getLanguages(); $original = $entity->getUntranslated()->language()->getId(); @@ -95,9 +68,8 @@ public function overview(RouteMatchInterface $route_match, $entity_type_id = NUL } // Show source-language column if there are non-original source langcodes. - $additional_source_langcodes = array_filter(array_keys($translations), function ($langcode) use ($entity, $original, $manager) { - $source = $manager->getTranslationMetadata($entity->getTranslation($langcode))->getSource(); - return $source != $original && $source != LanguageInterface::LANGCODE_NOT_SPECIFIED; + $additional_source_langcodes = array_filter($entity->translation, function ($translation) use ($original) { + return !empty($translation['source']) && $translation['source'] != $original; }); $show_source_column = !empty($additional_source_langcodes); @@ -146,9 +118,7 @@ public function overview(RouteMatchInterface $route_match, $entity_type_id = NUL $links = &$operations['data']['#links']; if (array_key_exists($langcode, $translations)) { // Existing translation in the translation set: display status. - $translation = $entity->getTranslation($langcode); - $metadata = $manager->getTranslationMetadata($translation); - $source = $metadata->getSource() ?: LanguageInterface::LANGCODE_NOT_SPECIFIED; + $source = isset($entity->translation[$langcode]['source']) ? $entity->translation[$langcode]['source'] : ''; $is_original = $langcode == $original; $label = $entity->getTranslation($langcode)->label(); $link = isset($links->links[$langcode]['url']) ? $links->links[$langcode] : array('url' => $entity->urlInfo()); @@ -175,12 +145,13 @@ public function overview(RouteMatchInterface $route_match, $entity_type_id = NUL if (isset($links['edit'])) { $links['edit']['title'] = $this->t('Edit'); } + $translation = $entity->translation[$langcode]; $status = array('data' => array( '#type' => 'inline_template', '#template' => '<span class="status">{% if status %}{{ "Published"|t }}{% else %}{{ "Not published"|t }}{% endif %}</span>{% if outdated %} <span class="marker">{{ "outdated"|t }}</span>{% endif %}', '#context' => array( - 'status' => $metadata->isPublished(), - 'outdated' => $metadata->isOutdated(), + 'status' => $translation['status'], + 'outdated' => $translation['outdated'], ), )); diff --git a/core/modules/content_translation/src/Tests/ContentTranslationConfigImportTest.php b/core/modules/content_translation/src/Tests/ContentTranslationConfigImportTest.php deleted file mode 100644 index c06fdb26dcad..000000000000 --- a/core/modules/content_translation/src/Tests/ContentTranslationConfigImportTest.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\content_translation\Tests\ContentTranslationConfigImportTest. - */ - -namespace Drupal\content_translation\Tests; - -use Drupal\Core\Config\ConfigImporter; -use Drupal\Core\Config\StorageComparer; -use Drupal\simpletest\KernelTestBase; - -/** - * Tests content translation updates performed during config import. - * - * @group content_translation - */ -class ContentTranslationConfigImportTest extends KernelTestBase { - - /** - * Config Importer object used for testing. - * - * @var \Drupal\Core\Config\ConfigImporter - */ - protected $configImporter; - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = array('system', 'user', 'entity_test', 'language', 'content_translation'); - - /** - * {@inheritdoc} - */ - protected function setUp() { - parent::setUp(); - - $this->installEntitySchema('entity_test_mul'); - $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging')); - - // Set up the ConfigImporter object for testing. - $storage_comparer = new StorageComparer( - $this->container->get('config.storage.staging'), - $this->container->get('config.storage'), - $this->container->get('config.manager') - ); - $this->configImporter = new ConfigImporter( - $storage_comparer->createChangelist(), - $this->container->get('event_dispatcher'), - $this->container->get('config.manager'), - $this->container->get('lock'), - $this->container->get('config.typed'), - $this->container->get('module_handler'), - $this->container->get('module_installer'), - $this->container->get('theme_handler'), - $this->container->get('string_translation') - ); - } - - /** - * Tests config import updates. - */ - function testConfigImportUpdates() { - $entity_type_id = 'entity_test_mul'; - $config_id = $entity_type_id . '.' . $entity_type_id; - $config_name = 'language.content_settings.' . $config_id; - $storage = $this->container->get('config.storage'); - $staging = $this->container->get('config.storage.staging'); - - // Verify the configuration to create does not exist yet. - $this->assertIdentical($storage->exists($config_name), FALSE, $config_name . ' not found.'); - - // Create new config entity. - $data = array( - 'uuid' => 'a019d89b-c4d9-4ed4-b859-894e4e2e93cf', - 'langcode' => 'en', - 'status' => TRUE, - 'dependencies' => array( - 'module' => array('content_translation') - ), - 'id' => $config_id, - 'target_entity_type_id' => 'entity_test_mul', - 'target_bundle' => 'entity_test_mul', - 'default_langcode' => 'site_default', - 'language_alterable' => FALSE, - 'third_party_settings' => array( - 'content_translation' => array('enabled' => TRUE), - ), - ); - $staging->write($config_name, $data); - $this->assertIdentical($staging->exists($config_name), TRUE, $config_name . ' found.'); - - // Import. - $this->configImporter->reset()->import(); - - // Verify the values appeared. - $config = $this->config($config_name); - $this->assertIdentical($config->get('id'), $config_id); - - // Verify that updates were performed. - $entity_type = $this->container->get('entity.manager')->getDefinition($entity_type_id); - $table = $entity_type->getDataTable(); - $db_schema = $this->container->get('database')->schema(); - $result = $db_schema->fieldExists($table, 'content_translation_source') && $db_schema->fieldExists($table, 'content_translation_outdated'); - $this->assertTrue($result, 'Content translation updates were successfully performed during config import.'); - } - -} diff --git a/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php b/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php index 17d40cc65649..1efe28a9a022 100644 --- a/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php @@ -116,6 +116,10 @@ function testImageFieldSync() { $default_langcode = $this->langcodes[0]; $langcode = $this->langcodes[1]; + // Populate the required contextual values. + $attributes = \Drupal::request()->attributes; + $attributes->set('source_langcode', $default_langcode); + // Populate the test entity with some random initial values. $values = array( 'name' => $this->randomMachineName(), @@ -183,7 +187,6 @@ function testImageFieldSync() { // Perform synchronization: the translation language is used as source, // while the default language is used as target. - $this->manager->getTranslationMetadata($translation)->setSource($default_langcode); $entity = $this->saveEntity($translation); $translation = $entity->getTranslation($langcode); @@ -213,6 +216,8 @@ function testImageFieldSync() { 'title' => $langcode . '_' . $removed_fid . '_' . $this->randomMachineName(), ); $translation->{$this->fieldName}->setValue(array_values($values[$langcode])); + // When updating an entity we do not have a source language defined. + $attributes->remove('source_langcode'); $entity = $this->saveEntity($translation); $translation = $entity->getTranslation($langcode); diff --git a/core/modules/content_translation/src/Tests/ContentTranslationTestBase.php b/core/modules/content_translation/src/Tests/ContentTranslationTestBase.php index a9d2c5ba40ba..9077f267d4e1 100644 --- a/core/modules/content_translation/src/Tests/ContentTranslationTestBase.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationTestBase.php @@ -79,11 +79,6 @@ abstract class ContentTranslationTestBase extends WebTestBase { */ protected $controller; - /** - * @var \Drupal\content_translation\ContentTranslationManagerInterface - */ - protected $manager; - protected function setUp() { parent::setUp(); @@ -93,8 +88,7 @@ protected function setUp() { $this->setupUsers(); $this->setupTestFields(); - $this->manager = $this->container->get('content_translation.manager'); - $this->controller = $this->manager->getTranslationHandler($this->entityTypeId); + $this->controller = \Drupal::entityManager()->getHandler($this->entityTypeId, 'translation'); // Rebuild the container so that the new languages are picked up by services // that hold a list of languages. @@ -173,7 +167,6 @@ protected function enableTranslation() { drupal_static_reset(); \Drupal::entityManager()->clearCachedDefinitions(); \Drupal::service('router.builder')->rebuild(); - \Drupal::service('entity.definition_update_manager')->applyUpdates(); } /** diff --git a/core/modules/content_translation/src/Tests/ContentTranslationUITest.php b/core/modules/content_translation/src/Tests/ContentTranslationUITest.php index 41bcf954966d..775df7ad38c4 100644 --- a/core/modules/content_translation/src/Tests/ContentTranslationUITest.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationUITest.php @@ -176,7 +176,7 @@ protected function doTestOutdatedStatus() { $this->drupalGet($url); $this->assertFieldByXPath('//input[@name="content_translation[retranslate]"]', FALSE, 'The retranslate flag is now shown.'); $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); - $this->assertFalse($this->manager->getTranslationMetadata($entity->getTranslation($added_langcode))->isOutdated(), 'The "outdated" status has been correctly stored.'); + $this->assertFalse($entity->translation[$added_langcode]['outdated'], 'The "outdated" status has been correctly stored.'); } } } @@ -194,7 +194,7 @@ protected function doTestPublishedStatus() { $edit = array('content_translation[status]' => FALSE); $this->drupalPostForm($url, $edit, $this->getFormSubmitAction($entity, $langcode)); $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); - $this->assertFalse($this->manager->getTranslationMetadata($entity->getTranslation($langcode))->isPublished(), 'The translation has been correctly unpublished.'); + $this->assertFalse($entity->translation[$langcode]['status'], 'The translation has been correctly unpublished.'); } } @@ -227,9 +227,8 @@ protected function doTestAuthoringInfo() { $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); foreach ($this->langcodes as $langcode) { - $metadata = $this->manager->getTranslationMetadata($entity->getTranslation($langcode)); - $this->assertEqual($metadata->getAuthor()->id(), $values[$langcode]['uid'], 'Translation author correctly stored.'); - $this->assertEqual($metadata->getCreatedTime(), $values[$langcode]['created'], 'Translation date correctly stored.'); + $this->assertEqual($entity->translation[$langcode]['uid'], $values[$langcode]['uid'], 'Translation author correctly stored.'); + $this->assertEqual($entity->translation[$langcode]['created'], $values[$langcode]['created'], 'Translation date correctly stored.'); } // Try to post non valid values and check that they are rejected. @@ -241,9 +240,8 @@ protected function doTestAuthoringInfo() { ); $this->drupalPostForm($entity->urlInfo('edit-form'), $edit, $this->getFormSubmitAction($entity, $langcode)); $this->assertTrue($this->xpath('//div[contains(@class, "error")]//ul'), 'Invalid values generate a list of form errors.'); - $metadata = $this->manager->getTranslationMetadata($entity->getTranslation($langcode)); - $this->assertEqual($metadata->getAuthor()->id(), $values[$langcode]['uid'], 'Translation author correctly kept.'); - $this->assertEqual($metadata->getCreatedTime(), $values[$langcode]['created'], 'Translation date correctly kept.'); + $this->assertEqual($entity->translation[$langcode]['uid'], $values[$langcode]['uid'], 'Translation author correctly kept.'); + $this->assertEqual($entity->translation[$langcode]['created'], $values[$langcode]['created'], 'Translation date correctly kept.'); } /** diff --git a/core/modules/entity_reference/src/Tests/EntityReferenceFieldTranslatedReferenceViewTest.php b/core/modules/entity_reference/src/Tests/EntityReferenceFieldTranslatedReferenceViewTest.php index 648920b7ece8..2c90f7efd352 100644 --- a/core/modules/entity_reference/src/Tests/EntityReferenceFieldTranslatedReferenceViewTest.php +++ b/core/modules/entity_reference/src/Tests/EntityReferenceFieldTranslatedReferenceViewTest.php @@ -176,7 +176,6 @@ protected function enableTranslation() { drupal_static_reset(); \Drupal::entityManager()->clearCachedDefinitions(); \Drupal::service('router.builder')->rebuild(); - \Drupal::service('entity.definition_update_manager')->applyUpdates(); } /** diff --git a/core/modules/file/src/Tests/PrivateFileOnTranslatedEntityTest.php b/core/modules/file/src/Tests/PrivateFileOnTranslatedEntityTest.php index 4841d0257613..1b5bef2ce574 100644 --- a/core/modules/file/src/Tests/PrivateFileOnTranslatedEntityTest.php +++ b/core/modules/file/src/Tests/PrivateFileOnTranslatedEntityTest.php @@ -68,7 +68,6 @@ protected function setUp() { "settings[node][page][fields][$this->fieldName]" => 1, ); $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration')); - \Drupal::entityManager()->clearCachedDefinitions(); } /** diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/src/Tests/NodeTranslationUITest.php index 60d5c33833f2..54f913ed10be 100644 --- a/core/modules/node/src/Tests/NodeTranslationUITest.php +++ b/core/modules/node/src/Tests/NodeTranslationUITest.php @@ -113,8 +113,9 @@ protected function doTestPublishedStatus() { // The node is created as unpublished thus we switch to the published // status first. $status = !$index; + $this->assertEqual($status, $entity->translation[$langcode]['status'], 'The translation has been correctly unpublished.'); $translation = $entity->getTranslation($langcode); - $this->assertEqual($status, $this->manager->getTranslationMetadata($translation)->isPublished(), 'The translation has been correctly unpublished.'); + $this->assertEqual($status, $translation->isPublished(), 'The status of the translation has been correctly saved.'); } } } @@ -150,10 +151,11 @@ protected function doTestAuthoringInfo() { $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); foreach ($this->langcodes as $langcode) { + $this->assertEqual($entity->translation[$langcode]['uid'], $values[$langcode]['uid'], 'Translation author correctly stored.'); + $this->assertEqual($entity->translation[$langcode]['created'], $values[$langcode]['created'], 'Translation date correctly stored.'); $translation = $entity->getTranslation($langcode); - $metadata = $this->manager->getTranslationMetadata($translation); - $this->assertEqual($metadata->getAuthor()->id(), $values[$langcode]['uid'], 'Translation author correctly stored.'); - $this->assertEqual($metadata->getCreatedTime(), $values[$langcode]['created'], 'Translation date correctly stored.'); + $this->assertEqual($translation->getOwnerId(), $values[$langcode]['uid'], 'Author of translation correctly stored.'); + $this->assertEqual($translation->getCreatedTime(), $values[$langcode]['created'], 'Date of Translation correctly stored.'); $this->assertEqual($translation->isSticky(), $values[$langcode]['sticky'], 'Sticky of Translation correctly stored.'); $this->assertEqual($translation->isPromoted(), $values[$langcode]['promote'], 'Promoted of Translation correctly stored.'); } @@ -200,7 +202,7 @@ public function testDisabledBundle() { )); // Make sure that nothing was inserted into the {content_translation} table. - $rows = db_query('SELECT nid, count(nid) AS count FROM {node_field_data} WHERE type <> :type GROUP BY nid HAVING count >= 2', array(':type' => $this->bundle))->fetchAll(); + $rows = db_query('SELECT * FROM {content_translation}')->fetchAll(); $this->assertEqual(0, count($rows)); // Ensure the translation tab is not accessible. diff --git a/core/modules/path/src/Tests/PathLanguageTest.php b/core/modules/path/src/Tests/PathLanguageTest.php index 93cd776c003d..01c7f705ace4 100644 --- a/core/modules/path/src/Tests/PathLanguageTest.php +++ b/core/modules/path/src/Tests/PathLanguageTest.php @@ -66,7 +66,6 @@ protected function setUp() { 'settings[node][page][settings][language][language_alterable]' => 1, ); $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration')); - \Drupal::entityManager()->clearCachedDefinitions(); $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'page'); $this->assertTrue($definitions['path']->isTranslatable(), 'Node path is translatable.'); diff --git a/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php b/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php index dffd0b4b4bf1..4a935c493081 100644 --- a/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php +++ b/core/modules/taxonomy/src/Tests/TaxonomyTranslationTestTrait.php @@ -69,7 +69,6 @@ protected function enableTranslation() { drupal_static_reset(); \Drupal::entityManager()->clearCachedDefinitions(); \Drupal::service('router.builder')->rebuild(); - \Drupal::service('entity.definition_update_manager')->applyUpdates(); } /** @@ -81,6 +80,7 @@ protected function setUpTermReferenceField() { 'entity_type' => 'node', 'type' => 'taxonomy_term_reference', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, + 'translatable' => FALSE, 'settings' => array( 'allowed_values' => array( array( @@ -95,7 +95,6 @@ protected function setUpTermReferenceField() { 'field_name' => $this->termFieldName, 'bundle' => 'article', 'entity_type' => 'node', - 'translatable' => FALSE, )); $field->save(); entity_get_form_display('node', 'article', 'default') diff --git a/core/modules/taxonomy/src/Tests/TermTranslationUITest.php b/core/modules/taxonomy/src/Tests/TermTranslationUITest.php index 07400a5484ed..5c0e9d5a18e6 100644 --- a/core/modules/taxonomy/src/Tests/TermTranslationUITest.php +++ b/core/modules/taxonomy/src/Tests/TermTranslationUITest.php @@ -95,9 +95,9 @@ public function testTranslationUI() { // Make sure that no row was inserted for taxonomy vocabularies which do // not have translations enabled. - $rows = db_query('SELECT tid, count(tid) AS count FROM {taxonomy_term_field_data} WHERE vid <> :vid GROUP BY tid', array(':vid' => $this->bundle))->fetchAll(); + $rows = db_query('SELECT * FROM {content_translation}')->fetchAll(); foreach ($rows as $row) { - $this->assertTrue($row->count < 2, 'Term does not have translations.'); + $this->assertEqual('taxonomy_term', $row->entity_type, 'Row contains a taxonomy term.'); } } diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php index 7b37eb40137a..d6bb322f1a08 100644 --- a/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php +++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyTermViewTest.php @@ -119,7 +119,6 @@ public function testTaxonomyTermView() { drupal_static_reset(); \Drupal::entityManager()->clearCachedDefinitions(); \Drupal::service('router.builder')->rebuild(); - \Drupal::service('entity.definition_update_manager')->applyUpdates(); $edit['title[0][value]'] = $translated_title = $this->randomMachineName(); @@ -138,7 +137,6 @@ public function testTaxonomyTermView() { // Uninstall language module and ensure that the language is not part of the // query anymore. // @see \Drupal\views\Plugin\views\filter\LanguageFilter::query() - $node->delete(); \Drupal::service('module_installer')->uninstall(['content_translation', 'language']); $view = Views::getView('taxonomy_term'); diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php index 22303e5a3fe2..81386d76713a 100644 --- a/core/modules/user/src/Entity/User.php +++ b/core/modules/user/src/Entity/User.php @@ -56,7 +56,7 @@ * "cancel-form" = "/user/{user}/cancel", * "collection" = "/admin/people", * }, - * field_ui_base_route = "entity.user.admin_form" + * field_ui_base_route = "entity.user.admin_form", * ) */ class User extends ContentEntityBase implements UserInterface { diff --git a/core/modules/user/src/ProfileTranslationHandler.php b/core/modules/user/src/ProfileTranslationHandler.php index b24e6348b0f1..cd8befc6e965 100644 --- a/core/modules/user/src/ProfileTranslationHandler.php +++ b/core/modules/user/src/ProfileTranslationHandler.php @@ -16,22 +16,6 @@ */ class ProfileTranslationHandler extends ContentTranslationHandler { - /** - * {@inheritdoc} - */ - protected function hasPublishedStatus() { - // User status has nothing to do with translations visibility. - return FALSE; - } - - /** - * {@inheritdoc} - */ - protected function hasCreatedTime() { - // User creation date has nothing to do with translation creation date. - return FALSE; - } - /** * {@inheritdoc} */ @@ -47,7 +31,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En * * @see \Drupal\Core\Entity\EntityForm::build(). */ - public function entityFormSave(array $form, FormStateInterface $form_state) { + function entityFormSave(array $form, FormStateInterface $form_state) { if ($this->getSourceLangcode($form_state)) { $entity = $form_state->getFormObject()->getEntity(); // We need a redirect here, otherwise we would get an access denied page @@ -56,5 +40,4 @@ public function entityFormSave(array $form, FormStateInterface $form_state) { $form_state->setRedirectUrl($entity->urlInfo()); } } - } diff --git a/core/modules/views/src/Tests/SearchMultilingualTest.php b/core/modules/views/src/Tests/SearchMultilingualTest.php index 4fb6b54e76b2..4a6d4c77741e 100644 --- a/core/modules/views/src/Tests/SearchMultilingualTest.php +++ b/core/modules/views/src/Tests/SearchMultilingualTest.php @@ -55,7 +55,6 @@ public function testMultilingualSearchFilter() { 'settings[node][' . $type->id() . '][fields][body]' => TRUE, ); $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration')); - \Drupal::entityManager()->clearCachedDefinitions(); // Add a node in English, with title "sandwich". $values = array( diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index 8a3dfa494dda..7cc10be7260c 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -594,11 +594,6 @@ # $config['system.performance']['fast_404']['paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; # $config['system.performance']['fast_404']['html'] = '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>'; -/** - * Load services definition file. - */ -$settings['container_yamls'][] = __DIR__ . '/services.yml'; - /** * Load local development override configuration, if available. * -- GitLab