Mercurial > hg > isophonics-drupal-site
comparison core/modules/content_translation/src/ContentTranslationHandler.php @ 14:1fec387a4317
Update Drupal core to 8.5.2 via Composer
author | Chris Cannam |
---|---|
date | Mon, 23 Apr 2018 09:46:53 +0100 |
parents | 4c8ae668cc8c |
children | c2387f117808 |
comparison
equal
deleted
inserted
replaced
13:5fb285c0d0e3 | 14:1fec387a4317 |
---|---|
3 namespace Drupal\content_translation; | 3 namespace Drupal\content_translation; |
4 | 4 |
5 use Drupal\Core\Access\AccessResult; | 5 use Drupal\Core\Access\AccessResult; |
6 use Drupal\Core\DependencyInjection\DependencySerializationTrait; | 6 use Drupal\Core\DependencyInjection\DependencySerializationTrait; |
7 use Drupal\Core\Entity\EntityChangedInterface; | 7 use Drupal\Core\Entity\EntityChangedInterface; |
8 use Drupal\Core\Entity\EntityChangesDetectionTrait; | |
8 use Drupal\Core\Entity\EntityHandlerInterface; | 9 use Drupal\Core\Entity\EntityHandlerInterface; |
9 use Drupal\Core\Entity\EntityInterface; | 10 use Drupal\Core\Entity\EntityInterface; |
10 use Drupal\Core\Entity\EntityManagerInterface; | 11 use Drupal\Core\Entity\EntityManagerInterface; |
11 use Drupal\Core\Entity\EntityTypeInterface; | 12 use Drupal\Core\Entity\EntityTypeInterface; |
12 use Drupal\Core\Field\BaseFieldDefinition; | 13 use Drupal\Core\Field\BaseFieldDefinition; |
13 use Drupal\Core\Form\FormStateInterface; | 14 use Drupal\Core\Form\FormStateInterface; |
14 use Drupal\Core\Language\LanguageInterface; | 15 use Drupal\Core\Language\LanguageInterface; |
15 use Drupal\Core\Language\LanguageManagerInterface; | 16 use Drupal\Core\Language\LanguageManagerInterface; |
17 use Drupal\Core\Messenger\MessengerInterface; | |
16 use Drupal\Core\Render\Element; | 18 use Drupal\Core\Render\Element; |
17 use Drupal\Core\Session\AccountInterface; | 19 use Drupal\Core\Session\AccountInterface; |
20 use Drupal\Core\StringTranslation\StringTranslationTrait; | |
18 use Drupal\user\Entity\User; | 21 use Drupal\user\Entity\User; |
19 use Drupal\user\EntityOwnerInterface; | 22 use Drupal\user\EntityOwnerInterface; |
20 use Symfony\Component\DependencyInjection\ContainerInterface; | 23 use Symfony\Component\DependencyInjection\ContainerInterface; |
21 | 24 |
22 /** | 25 /** |
23 * Base class for content translation handlers. | 26 * Base class for content translation handlers. |
24 * | 27 * |
25 * @ingroup entity_api | 28 * @ingroup entity_api |
26 */ | 29 */ |
27 class ContentTranslationHandler implements ContentTranslationHandlerInterface, EntityHandlerInterface { | 30 class ContentTranslationHandler implements ContentTranslationHandlerInterface, EntityHandlerInterface { |
31 | |
32 use EntityChangesDetectionTrait; | |
28 use DependencySerializationTrait; | 33 use DependencySerializationTrait; |
34 use StringTranslationTrait; | |
29 | 35 |
30 /** | 36 /** |
31 * The type of the entity being translated. | 37 * The type of the entity being translated. |
32 * | 38 * |
33 * @var string | 39 * @var string |
52 * The content translation manager. | 58 * The content translation manager. |
53 * | 59 * |
54 * @var \Drupal\content_translation\ContentTranslationManagerInterface | 60 * @var \Drupal\content_translation\ContentTranslationManagerInterface |
55 */ | 61 */ |
56 protected $manager; | 62 protected $manager; |
63 | |
64 /** | |
65 * The entity type manager. | |
66 * | |
67 * @var \Drupal\Core\Entity\EntityTypeManagerInterface | |
68 */ | |
69 protected $entityTypeManager; | |
57 | 70 |
58 /** | 71 /** |
59 * The current user. | 72 * The current user. |
60 * | 73 * |
61 * @var \Drupal\Core\Session\AccountInterface | 74 * @var \Drupal\Core\Session\AccountInterface |
67 * by field name. | 80 * by field name. |
68 * | 81 * |
69 * @var \Drupal\Core\Field\FieldStorageDefinitionInterface[] | 82 * @var \Drupal\Core\Field\FieldStorageDefinitionInterface[] |
70 */ | 83 */ |
71 protected $fieldStorageDefinitions; | 84 protected $fieldStorageDefinitions; |
85 | |
86 /** | |
87 * The messenger service. | |
88 * | |
89 * @var \Drupal\Core\Messenger\MessengerInterface | |
90 */ | |
91 protected $messenger; | |
72 | 92 |
73 /** | 93 /** |
74 * Initializes an instance of the content translation controller. | 94 * Initializes an instance of the content translation controller. |
75 * | 95 * |
76 * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type | 96 * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type |
81 * The content translation manager service. | 101 * The content translation manager service. |
82 * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager | 102 * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager |
83 * The entity manager. | 103 * The entity manager. |
84 * @param \Drupal\Core\Session\AccountInterface $current_user | 104 * @param \Drupal\Core\Session\AccountInterface $current_user |
85 * The current user. | 105 * The current user. |
86 */ | 106 * @param \Drupal\Core\Messenger\MessengerInterface $messenger |
87 public function __construct(EntityTypeInterface $entity_type, LanguageManagerInterface $language_manager, ContentTranslationManagerInterface $manager, EntityManagerInterface $entity_manager, AccountInterface $current_user) { | 107 * The messenger service. |
108 */ | |
109 public function __construct(EntityTypeInterface $entity_type, LanguageManagerInterface $language_manager, ContentTranslationManagerInterface $manager, EntityManagerInterface $entity_manager, AccountInterface $current_user, MessengerInterface $messenger) { | |
88 $this->entityTypeId = $entity_type->id(); | 110 $this->entityTypeId = $entity_type->id(); |
89 $this->entityType = $entity_type; | 111 $this->entityType = $entity_type; |
90 $this->languageManager = $language_manager; | 112 $this->languageManager = $language_manager; |
91 $this->manager = $manager; | 113 $this->manager = $manager; |
114 $this->entityTypeManager = $entity_manager; | |
92 $this->currentUser = $current_user; | 115 $this->currentUser = $current_user; |
93 $this->fieldStorageDefinitions = $entity_manager->getLastInstalledFieldStorageDefinitions($this->entityTypeId); | 116 $this->fieldStorageDefinitions = $entity_manager->getLastInstalledFieldStorageDefinitions($this->entityTypeId); |
117 $this->messenger = $messenger; | |
94 } | 118 } |
95 | 119 |
96 /** | 120 /** |
97 * {@inheritdoc} | 121 * {@inheritdoc} |
98 */ | 122 */ |
100 return new static( | 124 return new static( |
101 $entity_type, | 125 $entity_type, |
102 $container->get('language_manager'), | 126 $container->get('language_manager'), |
103 $container->get('content_translation.manager'), | 127 $container->get('content_translation.manager'), |
104 $container->get('entity.manager'), | 128 $container->get('entity.manager'), |
105 $container->get('current_user') | 129 $container->get('current_user'), |
130 $container->get('messenger') | |
106 ); | 131 ); |
107 } | 132 } |
108 | 133 |
109 /** | 134 /** |
110 * {@inheritdoc} | 135 * {@inheritdoc} |
267 | 292 |
268 /** | 293 /** |
269 * {@inheritdoc} | 294 * {@inheritdoc} |
270 */ | 295 */ |
271 public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) { | 296 public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) { |
297 /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ | |
298 | |
272 $form_object = $form_state->getFormObject(); | 299 $form_object = $form_state->getFormObject(); |
273 $form_langcode = $form_object->getFormLangcode($form_state); | 300 $form_langcode = $form_object->getFormLangcode($form_state); |
274 $entity_langcode = $entity->getUntranslated()->language()->getId(); | 301 $entity_langcode = $entity->getUntranslated()->language()->getId(); |
275 $source_langcode = $this->getSourceLangcode($form_state); | 302 $source_langcode = $this->getSourceLangcode($form_state); |
276 | 303 |
361 if (isset($form['actions'][$key]['weight'])) { | 388 if (isset($form['actions'][$key]['weight'])) { |
362 $weight = $form['actions'][$key]['weight']; | 389 $weight = $form['actions'][$key]['weight']; |
363 break; | 390 break; |
364 } | 391 } |
365 } | 392 } |
366 $access = $this->getTranslationAccess($entity, 'delete')->isAllowed() || ($entity->access('delete') && $this->entityType->hasLinkTemplate('delete-form')); | 393 /** @var \Drupal\Core\Access\AccessResultInterface $delete_access */ |
394 $delete_access = \Drupal::service('content_translation.delete_access')->checkAccess($entity); | |
395 $access = $delete_access->isAllowed() && ( | |
396 $this->getTranslationAccess($entity, 'delete')->isAllowed() || | |
397 ($entity->access('delete') && $this->entityType->hasLinkTemplate('delete-form')) | |
398 ); | |
367 $form['actions']['delete_translation'] = [ | 399 $form['actions']['delete_translation'] = [ |
368 '#type' => 'submit', | 400 '#type' => 'submit', |
369 '#value' => t('Delete translation'), | 401 '#value' => t('Delete translation'), |
370 '#weight' => $weight, | 402 '#weight' => $weight, |
371 '#submit' => [[$this, 'entityFormDeleteTranslation']], | 403 '#submit' => [[$this, 'entityFormDeleteTranslation']], |
424 '#description' => $description, | 456 '#description' => $description, |
425 '#disabled' => !$enabled, | 457 '#disabled' => !$enabled, |
426 ]; | 458 ]; |
427 | 459 |
428 $translate = !$new_translation && $metadata->isOutdated(); | 460 $translate = !$new_translation && $metadata->isOutdated(); |
429 if (!$translate) { | 461 $outdated_access = !ContentTranslationManager::isPendingRevisionSupportEnabled($entity->getEntityTypeId(), $entity->bundle()); |
462 if (!$outdated_access) { | |
463 $form['content_translation']['outdated'] = [ | |
464 '#markup' => $this->t('Translations cannot be flagged as outdated when content is moderated.'), | |
465 ]; | |
466 } | |
467 elseif (!$translate) { | |
430 $form['content_translation']['retranslate'] = [ | 468 $form['content_translation']['retranslate'] = [ |
431 '#type' => 'checkbox', | 469 '#type' => 'checkbox', |
432 '#title' => t('Flag other translations as outdated'), | 470 '#title' => t('Flag other translations as outdated'), |
433 '#default_value' => FALSE, | 471 '#default_value' => FALSE, |
434 '#description' => t('If you made a significant change, which means the other translations should be updated, you can flag all translations of this content as outdated. This will not change any other property of them, like whether they are published or not.'), | 472 '#description' => t('If you made a significant change, which means the other translations should be updated, you can flag all translations of this content as outdated. This will not change any other property of them, like whether they are published or not.'), |
473 '#access' => $outdated_access, | |
435 ]; | 474 ]; |
436 } | 475 } |
437 else { | 476 else { |
438 $form['content_translation']['outdated'] = [ | 477 $form['content_translation']['outdated'] = [ |
439 '#type' => 'checkbox', | 478 '#type' => 'checkbox', |
440 '#title' => t('This translation needs to be updated'), | 479 '#title' => t('This translation needs to be updated'), |
441 '#default_value' => $translate, | 480 '#default_value' => $translate, |
442 '#description' => t('When this option is checked, this translation needs to be updated. Uncheck when the translation is up to date again.'), | 481 '#description' => t('When this option is checked, this translation needs to be updated. Uncheck when the translation is up to date again.'), |
482 '#access' => $outdated_access, | |
443 ]; | 483 ]; |
444 $form['content_translation']['#open'] = TRUE; | 484 $form['content_translation']['#open'] = TRUE; |
445 } | 485 } |
446 | 486 |
447 // Default to the anonymous user. | 487 // Default to the anonymous user. |
510 // multilingual value. | 550 // multilingual value. |
511 if (!isset($ignored_types)) { | 551 if (!isset($ignored_types)) { |
512 $ignored_types = array_flip(['actions', 'value', 'hidden', 'vertical_tabs', 'token', 'details']); | 552 $ignored_types = array_flip(['actions', 'value', 'hidden', 'vertical_tabs', 'token', 'details']); |
513 } | 553 } |
514 | 554 |
555 /** @var \Drupal\Core\Entity\ContentEntityForm $form_object */ | |
556 $form_object = $form_state->getFormObject(); | |
557 /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ | |
558 $entity = $form_object->getEntity(); | |
559 $display_translatability_clue = !$entity->isDefaultTranslationAffectedOnly(); | |
560 $hide_untranslatable_fields = $entity->isDefaultTranslationAffectedOnly() && !$entity->isDefaultTranslation(); | |
561 $translation_form = $form_state->get(['content_translation', 'translation_form']); | |
562 $display_warning = FALSE; | |
563 | |
564 // We use field definitions to identify untranslatable field widgets to be | |
565 // hidden. Fields that are not involved in translation changes checks should | |
566 // not be affected by this logic (the "revision_log" field, for instance). | |
567 $field_definitions = array_diff_key($entity->getFieldDefinitions(), array_flip($this->getFieldsToSkipFromTranslationChangesCheck($entity))); | |
568 | |
515 foreach (Element::children($element) as $key) { | 569 foreach (Element::children($element) as $key) { |
516 if (!isset($element[$key]['#type'])) { | 570 if (!isset($element[$key]['#type'])) { |
517 $this->entityFormSharedElements($element[$key], $form_state, $form); | 571 $this->entityFormSharedElements($element[$key], $form_state, $form); |
518 } | 572 } |
519 else { | 573 else { |
522 continue; | 576 continue; |
523 } | 577 } |
524 // Elements are considered to be non multilingual by default. | 578 // Elements are considered to be non multilingual by default. |
525 if (empty($element[$key]['#multilingual'])) { | 579 if (empty($element[$key]['#multilingual'])) { |
526 // If we are displaying a multilingual entity form we need to provide | 580 // If we are displaying a multilingual entity form we need to provide |
527 // translatability clues, otherwise the shared form elements should be | 581 // translatability clues, otherwise the non-multilingual form elements |
528 // hidden. | 582 // should be hidden. |
529 if (!$form_state->get(['content_translation', 'translation_form'])) { | 583 if (!$translation_form) { |
530 $this->addTranslatabilityClue($element[$key]); | 584 if ($display_translatability_clue) { |
585 $this->addTranslatabilityClue($element[$key]); | |
586 } | |
587 // Hide widgets for untranslatable fields. | |
588 if ($hide_untranslatable_fields && isset($field_definitions[$key])) { | |
589 $element[$key]['#access'] = FALSE; | |
590 $display_warning = TRUE; | |
591 } | |
531 } | 592 } |
532 else { | 593 else { |
533 $element[$key]['#access'] = FALSE; | 594 $element[$key]['#access'] = FALSE; |
534 } | 595 } |
535 } | 596 } |
536 } | 597 } |
598 } | |
599 | |
600 if ($display_warning && !$form_state->isSubmitted() && !$form_state->isRebuilding()) { | |
601 $url = $entity->getUntranslated()->toUrl('edit-form')->toString(); | |
602 $this->messenger->addWarning($this->t('Fields that apply to all languages are hidden to avoid conflicting changes. <a href=":url">Edit them on the original language form</a>.', [':url' => $url])); | |
537 } | 603 } |
538 | 604 |
539 return $element; | 605 return $element; |
540 } | 606 } |
541 | 607 |
641 | 707 |
642 // ContentEntityForm::submit will update the changed timestamp on submit | 708 // ContentEntityForm::submit will update the changed timestamp on submit |
643 // after the entity has been validated, so that it does not break the | 709 // after the entity has been validated, so that it does not break the |
644 // EntityChanged constraint validator. The content translation metadata | 710 // EntityChanged constraint validator. The content translation metadata |
645 // field for the changed timestamp does not have such a constraint defined | 711 // field for the changed timestamp does not have such a constraint defined |
646 // at the moment, but it is correct to update it's value in a submission | 712 // at the moment, but it is correct to update its value in a submission |
647 // handler as well and have the same logic like in the Form API. | 713 // handler as well and have the same logic like in the Form API. |
648 if ($entity->hasField('content_translation_changed')) { | 714 if ($entity->hasField('content_translation_changed')) { |
649 $metadata = $this->manager->getTranslationMetadata($entity); | 715 $metadata = $this->manager->getTranslationMetadata($entity); |
650 $metadata->setChangedTime(REQUEST_TIME); | 716 $metadata->setChangedTime(REQUEST_TIME); |
651 } | 717 } |