translators-8.x-1.x-dev/modules/translators_content/src/Handler/TranslatorsContentTranslationHandlerTrait.php
modules/translators_content/src/Handler/TranslatorsContentTranslationHandlerTrait.php
<?php
namespace Drupal\translators_content\Handler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Language\LanguageInterface;
/**
* Trait TranslatorsContentTranslationHandlerTrait.
*
* @package Drupal\translators_content
*/
trait TranslatorsContentTranslationHandlerTrait {
/**
* Checks if the user can perform the given operation on translations.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity whose translation has to be accessed.
* @param string $operation
* The operation to be performed on the translation. Possible values are:
* - "create"
* - "update"
* - "delete"
* @param string $active
* Language ID of the active language.
* @param string $target
* Language ID of the target language when creating new translations.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function getTranslationAccess(EntityInterface $entity, $operation, $active = NULL, $target = NULL) {
if (!in_array($operation, ['create', 'update', 'delete'])) {
return AccessResult::neutral();
}
$operation_access = NULL;
if ($operation == 'create') {
if ($active == NULL) {
$active = $this->getMissingSourceLangcode($entity);
}
if ($target == NULL) {
$target = $this->getMissingTargetLangcode($entity);
}
$operation_access = $this->getCreateTranslationAccess($entity, $active, $target);
}
else {
if ($active == NULL) {
$active = $entity->language()->getId();
}
$operation_access = $this->getOperationTranslationAccess($entity, $operation, $active);
}
if ($operation_access->isAllowed()) {
return AccessResult::allowedIf($this->getBundleTranslationAccess($entity))
->cachePerPermissions()->addCacheableDependency($entity);
}
return AccessResult::forbidden()
->cachePerPermissions()->addCacheableDependency($entity);
}
/**
* Get missing source Language ID.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity being checked.
*
* @return string|null
* Source Language ID, or NULL if none is found
*/
protected function getMissingSourceLangcode(ContentEntityInterface $entity) {
$routMatch = \Drupal::routeMatch();
$source_language = $routMatch->getParameter('source');
if (!$source_language instanceof LanguageInterface) {
$source_language = $entity->language();
}
if ($source_language instanceof LanguageInterface) {
return $source_language->getId();
}
return NULL;
}
/**
* Get missing target Language ID.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity being checked.
*
* @return string|null
* Target Language ID, or NULL if none is found
*/
protected function getMissingTargetLangcode(ContentEntityInterface $entity) {
$routMatch = \Drupal::routeMatch();
$target_language = $routMatch->getParameter('target');
if (!$target_language instanceof LanguageInterface) {
$target_language = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT);
}
if ($target_language instanceof LanguageInterface) {
return $target_language->getId();
}
return NULL;
}
/**
* Performs bundle access checks for the specified entity.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity being checked.
*
* @return \Drupal\Core\Access\AccessResultInterface
* An access result object.
*/
public function getBundleTranslationAccess(EntityInterface $entity) {
if ($this->currentUser->hasPermission('translate any entity')) {
return AccessResult::allowed();
}
elseif ($permission_granularity = $entity->getEntityType()->getPermissionGranularity()) {
$bundle_permission = $permission_granularity == 'bundle' ? "translate {$entity->bundle()} {$entity->getEntityTypeId()}" : "translate {$entity->getEntityTypeId()}";
$bundle_permission = "translate {$entity->bundle()} {$entity->getEntityTypeId()}";
return AccessResult::allowedIf($this->currentUser->hasPermission($bundle_permission));
}
return AccessResult::neutral();
}
/**
* Performs create translation operation access check.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity being checked.
* @param string $source
* Source Language ID.
* @param string $target
* Target Language ID.
*
* @return \Drupal\Core\Access\AccessResultInterface
* An access result object.
*/
public function getCreateTranslationAccess($entity, $source, $target) {
if ($source == $target) {
return AccessResult::forbidden();
}
elseif ($this->currentUser->hasPermission('create content translations')) {
return AccessResult::allowed()->cachePerPermissions();
}
elseif ($this->currentUser->hasPermission('translators_content create content translations')) {
$config = \Drupal::configFactory()->get('translators.settings');
// Allow access if user has both languages in their translation skills.
$translatorSkills = \Drupal::service('translators.skills');
if (!$config->get('enable_strict_translation_skill_pairing')) {
return AccessResult::allowedIf(
$translatorSkills->hasLangcode($source)
&& $translatorSkills->hasLangcode($target))
->cachePerPermissions();
}
// Allow access if the user has the source-target language pair.
return AccessResult::allowedIf(
$translatorSkills->hasTranslationSkills($source, $target))
->cachePerPermissions();
}
return AccessResult::neutral();
}
/**
* Performs translation operation access check.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity being checked.
* @param string $operation
* Operation machine name.
* @param string $langcode
* Language ID.
*
* @return \Drupal\Core\Access\AccessResultInterface
* An access result object.
*/
public function getOperationTranslationAccess($entity, $operation, $langcode) {
if ($this->currentUser->hasPermission("$operation content translations")) {
return AccessResult::allowed();
}
elseif ($this->currentUser->hasPermission("translators_content $operation content translations")) {
$translatorSkills = \Drupal::service('translators.skills');
return AccessResult::allowedIf($translatorSkills->hasLangcode($langcode))
->cachePerPermissions();
}
return AccessResult::neutral();
}
/**
* Check if current user has permission to performe translation operations.
*
* @return bool
* TRUE if user has translation operation permission, FALSE otherwise.
*/
public function hasOperationTranslationAccess() {
$translationOperationPermissions = [
'create content translations',
'translators_content create content translations',
'update content translations',
'translators_content update content translations',
'delete content translations',
'translators_content delete content translations',
];
foreach ($translationOperationPermissions as $permission) {
if ($this->currentUser->hasPermission($permission)) {
return TRUE;
}
}
return FALSE;
}
}
