/** * Returns an array of content translation permissions. * * @return array */ public function contentPermissions() { $permission = []; // Create a translate permission for each enabled entity type and (optionally) // bundle. foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) { if ($permission_granularity = $entity_type->getPermissionGranularity()) { $t_args = ['@entity_label' => $entity_type->getLowercaseLabel()]; switch ($permission_granularity) { case 'bundle': foreach ($this->entityManager->getBundleInfo($entity_type_id) as $bundle => $bundle_info) { if ($this->contentTranslationManager->isEnabled($entity_type_id, $bundle)) { $t_args['%bundle_label'] = isset($bundle_info['label']) ? $bundle_info['label'] : $bundle; $permission["translate {$bundle} {$entity_type_id}"] = ['title' => $this->t('Translate %bundle_label @entity_label', $t_args)]; } } break; case 'entity_type': if ($this->contentTranslationManager->isEnabled($entity_type_id)) { $permission["translate {$entity_type_id}"] = ['title' => $this->t('Translate @entity_label', $t_args)]; } break; } } } return $permission; }
/** * {@inheritdoc} */ protected function alterRoutes(RouteCollection $collection) { foreach ($this->contentTranslationManager->getSupportedEntityTypes() as $entity_type_id => $entity_type) { // Try to get the route from the current collection. $link_template = $entity_type->getLinkTemplate('canonical'); if (strpos($link_template, '/') !== FALSE) { $base_path = '/' . $link_template; } else { if (!($entity_route = $collection->get("entity.{$entity_type_id}.canonical"))) { continue; } $base_path = $entity_route->getPath(); } // Inherit admin route status from edit route, if exists. $is_admin = FALSE; $route_name = "entity.{$entity_type_id}.edit_form"; if ($edit_route = $collection->get($route_name)) { $is_admin = (bool) $edit_route->getOption('_admin_route'); } $path = $base_path . '/translations'; $route = new Route($path, array('_controller' => '\\Drupal\\content_translation\\Controller\\ContentTranslationController::overview', 'entity_type_id' => $entity_type_id), array('_entity_access' => $entity_type_id . '.view', '_access_content_translation_overview' => $entity_type_id), array('parameters' => array($entity_type_id => array('type' => 'entity:' . $entity_type_id)), '_admin_route' => $is_admin)); $route_name = "entity.{$entity_type_id}.content_translation_overview"; $collection->add($route_name, $route); $route = new Route($path . '/add/{source}/{target}', array('_controller' => '\\Drupal\\content_translation\\Controller\\ContentTranslationController::add', 'source' => NULL, 'target' => NULL, '_title' => 'Add', 'entity_type_id' => $entity_type_id), array('_entity_access' => $entity_type_id . '.view', '_access_content_translation_manage' => 'create'), array('parameters' => array('source' => array('type' => 'language'), 'target' => array('type' => 'language'), $entity_type_id => array('type' => 'entity:' . $entity_type_id)), '_admin_route' => $is_admin)); $collection->add("entity.{$entity_type_id}.content_translation_add", $route); $route = new Route($path . '/edit/{language}', array('_controller' => '\\Drupal\\content_translation\\Controller\\ContentTranslationController::edit', 'language' => NULL, '_title' => 'Edit', 'entity_type_id' => $entity_type_id), array('_access_content_translation_manage' => 'update'), array('parameters' => array('language' => array('type' => 'language'), $entity_type_id => array('type' => 'entity:' . $entity_type_id)), '_admin_route' => $is_admin)); $collection->add("entity.{$entity_type_id}.content_translation_edit", $route); $route = new Route($path . '/delete/{language}', array('_entity_form' => $entity_type_id . '.content_translation_deletion', 'language' => NULL, '_title' => 'Delete', 'entity_type_id' => $entity_type_id), array('_access_content_translation_manage' => 'delete'), array('parameters' => array('language' => array('type' => 'language'), $entity_type_id => array('type' => 'entity:' . $entity_type_id)), '_admin_route' => $is_admin)); $collection->add("entity.{$entity_type_id}.content_translation_delete", $route); } }
/** * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { // Create contextual links for translatable entity types. foreach ($this->contentTranslationManager->getSupportedEntityTypes() as $entity_type_id => $entity_type) { $this->derivatives[$entity_type_id]['title'] = t('Translate'); $this->derivatives[$entity_type_id]['route_name'] = "entity.{$entity_type_id}.content_translation_overview"; $this->derivatives[$entity_type_id]['group'] = $entity_type_id; } return parent::getDerivativeDefinitions($base_plugin_definition); }
/** * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { // Create tabs for all possible entity types. foreach ($this->contentTranslationManager->getSupportedEntityTypes() as $entity_type_id => $entity_type) { // Find the route name for the translation overview. $translation_route_name = $entity_type->getLinkTemplate('drupal:content-translation-overview'); $this->derivatives[$translation_route_name] = array('entity_type' => $entity_type_id, 'title' => 'Translate', 'route_name' => $translation_route_name, 'base_route' => $entity_type->getLinkTemplate('canonical')) + $base_plugin_definition; } return parent::getDerivativeDefinitions($base_plugin_definition); }
/** * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { // Create tabs for all possible entity types. foreach ($this->contentTranslationManager->getSupportedEntityTypes() as $entity_type_id => $entity_type) { // Find the route name for the translation overview. $translation_route_name = "entity.{$entity_type_id}.content_translation_overview"; $base_route_name = "entity.{$entity_type_id}.canonical"; $this->derivatives[$translation_route_name] = array('entity_type' => $entity_type_id, 'title' => $this->t('Translate'), 'route_name' => $translation_route_name, 'base_route' => $base_route_name) + $base_plugin_definition; } return parent::getDerivativeDefinitions($base_plugin_definition); }
protected function setUp() { parent::setUp(); $this->setupLanguages(); $this->setupBundle(); $this->enableTranslation(); $this->setupUsers(); $this->setupTestFields(); $this->manager = $this->container->get('content_translation.manager'); $this->controller = $this->manager->getTranslationHandler($this->entityTypeId); // Rebuild the container so that the new languages are picked up by services // that hold a list of languages. $this->rebuildContainer(); }
/** * Populates target values with the source values. * * @param \Drupal\Core\Entity\ContentEntityInterface $entity * The entity being translated. * @param \Drupal\Core\Language\LanguageInterface $source * The language to be used as source. * @param \Drupal\Core\Language\LanguageInterface $target * The language to be used as target. */ public function prepareTranslation(ContentEntityInterface $entity, LanguageInterface $source, LanguageInterface $target) { /* @var \Drupal\Core\Entity\ContentEntityInterface $source_translation */ $source_translation = $entity->getTranslation($source->getId()); $target_translation = $entity->addTranslation($target->getId(), $source_translation->toArray()); // Make sure we do not inherit the affected status from the source values. if ($entity->getEntityType()->isRevisionable()) { $target_translation->setRevisionTranslationAffected(NULL); } /** @var \Drupal\user\UserInterface $user */ $user = $this->entityManager()->getStorage('user')->load($this->currentUser()->id()); $metadata = $this->manager->getTranslationMetadata($target_translation); // Update the translation author to current user, as well the translation // creation time. $metadata->setAuthor($user); $metadata->setCreatedTime(REQUEST_TIME); }
/** * {@inheritdoc} */ protected function alterRoutes(RouteCollection $collection) { foreach ($this->contentTranslationManager->getSupportedEntityTypes() as $entity_type_id => $entity_type) { // Try to get the route from the current collection. if (!($entity_route = $collection->get($entity_type->getLinkTemplate('canonical')))) { continue; } $path = $entity_route->getPath() . '/translations'; // Inherit admin route status from edit route, if exists. $is_admin = FALSE; if ($edit_route = $collection->get($entity_type->getLinkTemplate('edit-form'))) { $is_admin = (bool) $edit_route->getOption('_admin_route'); } $route = new Route($path, array('_content' => '\\Drupal\\content_translation\\Controller\\ContentTranslationController::overview', '_entity_type_id' => $entity_type_id), array('_access_content_translation_overview' => $entity_type_id, '_permission' => 'translate any entity'), array('_access_mode' => 'ANY', 'parameters' => array('entity' => array('type' => 'entity:' . $entity_type_id), $entity_type_id => array('type' => 'entity:' . $entity_type_id)), '_admin_route' => $is_admin)); $collection->add($entity_type->getLinkTemplate('drupal:content-translation-overview'), $route); $route = new Route($path . '/add/{source}/{target}', array('_content' => '\\Drupal\\content_translation\\Controller\\ContentTranslationController::add', 'source' => NULL, 'target' => NULL, '_title' => 'Add', '_entity_type_id' => $entity_type_id), array('_permission' => 'translate any entity', '_access_content_translation_manage' => 'create'), array('_access_mode' => 'ANY', 'parameters' => array('entity' => array('type' => 'entity:' . $entity_type_id), $entity_type_id => array('type' => 'entity:' . $entity_type_id)), '_admin_route' => $is_admin)); $collection->add("content_translation.translation_add_{$entity_type_id}", $route); $route = new Route($path . '/edit/{language}', array('_content' => '\\Drupal\\content_translation\\Controller\\ContentTranslationController::edit', 'language' => NULL, '_title' => 'Edit', '_entity_type_id' => $entity_type_id), array('_permission' => 'translate any entity', '_access_content_translation_manage' => 'update'), array('_access_mode' => 'ANY', 'parameters' => array('entity' => array('type' => 'entity:' . $entity_type_id), $entity_type_id => array('type' => 'entity:' . $entity_type_id)), '_admin_route' => $is_admin)); $collection->add("content_translation.translation_edit_{$entity_type_id}", $route); $route = new Route($path . '/delete/{language}', array('_form' => '\\Drupal\\content_translation\\Form\\ContentTranslationDeleteForm', 'language' => NULL, '_title' => 'Delete', '_entity_type_id' => $entity_type_id), array('_permission' => 'translate any entity', '_access_content_translation_manage' => 'delete'), array('parameters' => array('entity' => array('type' => 'entity:' . $entity_type_id), $entity_type_id => array('type' => 'entity:' . $entity_type_id)), '_access_mode' => 'ANY', '_admin_route' => $is_admin)); $collection->add("content_translation.delete_{$entity_type_id}", $route); } }
/** * Form submission handler for ContentTranslationHandler::entityFormAlter(). * * Updates metadata fields, which should be updated only after the validation * has run and before the entity is saved. */ function entityFormSubmit($form, FormStateInterface $form_state) { /** @var \Drupal\Core\Entity\ContentEntityFormInterface $form_object */ $form_object = $form_state->getFormObject(); /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $form_object->getEntity(); // ContentEntityForm::submit will update the changed timestamp on submit // after the entity has been validated, so that it does not break the // EntityChanged constraint validator. The content translation metadata // field for the changed timestamp does not have such a constraint defined // at the moment, but it is correct to update it's value in a submission // handler as well and have the same logic like in the Form API. if ($entity->hasField('content_translation_changed')) { $metadata = $this->manager->getTranslationMetadata($entity); $metadata->setChangedTime(REQUEST_TIME); } }
/** * Entity builder method. * * @param string $entity_type * The type of the entity. * @param \Drupal\Core\Entity\EntityInterface $entity * The entity whose form is being built. * * @see \Drupal\content_translation\ContentTranslationHandler::entityFormAlter() */ 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()); $metadata = $this->manager->getTranslationMetadata($entity); $metadata->setAuthor(!empty($values['uid']) ? User::load($values['uid']) : User::load(0)); $metadata->setPublished(!empty($values['status'])); $metadata->setCreatedTime(!empty($values['created']) ? strtotime($values['created']) : REQUEST_TIME); $metadata->setChangedTime(REQUEST_TIME); $source_langcode = $this->getSourceLangcode($form_state); if ($source_langcode) { $metadata->setSource($source_langcode); } $metadata->setOutdated(!empty($values['outdated'])); if (!empty($values['retranslate'])) { $this->retranslate($entity, $form_langcode); } }