You are here

allowed_languages.module in Allowed Languages 2.x

Same filename and directory in other branches
  1. 8 allowed_languages.module

File

allowed_languages.module
View source
<?php

/**
 * @file
 * Contains allowed_languages.module.
 */
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\ContentEntityFormInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Form\FormStateInterface;
use Drupal\allowed_languages\Form\AllowedLanguagesTrustedCallbacks;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Routing\RouteMatchInterface;

/**
 * Implements hook_help().
 */
function allowed_languages_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the allowed_languages module.
    case 'help.page.allowed_languages':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('Lets you limit the languages a user may use when managing content.') . '</p>';
      return $output;
  }
}

/**
 * Implements hook_entity_base_field_info().
 */
function allowed_languages_entity_base_field_info(EntityTypeInterface $entity_type) {
  if ($entity_type
    ->id() !== 'user') {
    return [];
  }
  $fields = [];

  // Add the allowed languages entity reference field to the user entity.
  $fields['allowed_languages'] = BaseFieldDefinition::create('entity_reference')
    ->setLabel(t('Allowed languages'))
    ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED)
    ->setDescription(t('The languages the user is allowed to manage.'))
    ->setSetting('target_type', 'configurable_language');
  return $fields;
}

/**
 * Implements hook_field_widget_WIDGET_TYPE_form_alter().
 *
 * Apply a pre-render function to the language select field widget.
 */
function allowed_languages_field_widget_language_select_form_alter(&$element, FormStateInterface $form_state, $context) {
  $form_object = $form_state
    ->getFormObject();

  // We're only interested in altering forms for content entities.
  if (!$form_object instanceof ContentEntityFormInterface) {
    return;
  }

  // We can translate all languages.
  if (\Drupal::currentUser()
    ->hasPermission('translate all languages')) {
    return;
  }

  // Only alter translatable entity types.
  $entity = $form_object
    ->getEntity();
  if (!$entity
    ->isTranslatable()) {
    return;
  }
  $element['#pre_render'][] = [
    AllowedLanguagesTrustedCallbacks::class,
    'languageSelectWidgetPreRender',
  ];
}

/**
 * Add the allowed languages checkboxes to the user form.
 *
 * @param array $form
 *   The user form.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   The user form state.
 */
function allowed_languages_form_user_form_alter(array &$form, FormStateInterface $form_state) {

  /** @var \Drupal\user\UserInterface $user */
  $user = $form_state
    ->getFormObject()
    ->getEntity();
  $languages = allowed_languages_get_language_options();
  $users_allowed_languages = \Drupal::service('allowed_languages.allowed_languages_manager')
    ->assignedLanguages($user);

  // Merge the array of languages with the all languages option.
  $language_options = [
    'all' => t('Allow all languages'),
  ] + $languages;

  // Diff the keys from the languages against the users allowed languages to
  // determine if the all languages checkbox should be checked.
  $not_allowed_languages = array_diff(array_keys($languages), $users_allowed_languages);
  if (!$not_allowed_languages) {
    $users_allowed_languages[] = 'all';
  }
  $form['allowed_languages'] = [
    '#tree' => TRUE,
    '#type' => 'details',
    '#title' => t('Allowed languages'),
    '#open' => TRUE,
    '#access' => \Drupal::currentUser()
      ->hasPermission('administer allowed languages'),
  ];
  $form['allowed_languages']['languages'] = [
    '#type' => 'checkboxes',
    '#options' => $language_options,
    '#default_value' => $users_allowed_languages,
  ];
  $form['actions']['submit']['#submit'][] = 'allowed_languages_user_form_submit';
  $form['#attached']['library'][] = 'allowed_languages/user';
}

/**
 * Allowed languages user form submit handler.
 *
 * @param array $form
 *   The user form.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   The user form state.
 */
function allowed_languages_user_form_submit(array &$form, FormStateInterface $form_state) {
  $languages = array_filter($form_state
    ->getValue([
    'allowed_languages',
    'languages',
  ], []));

  // If the al languages checkbox was checked then lets remove it to not have
  // it saved to the allowed languages.
  if (isset($languages['all'])) {
    unset($languages['all']);
  }

  /** @var \Drupal\user\UserInterface $account */
  $account = $form_state
    ->getFormObject()
    ->getEntity();
  if ($account
    ->hasField('allowed_languages')) {
    $account
      ->set('allowed_languages', array_values($languages))
      ->save();
  }
}

/**
 * Implements hook_entity_access().
 */
function allowed_languages_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
  if (!\Drupal::service('allowed_languages.allowed_languages_manager')
    ->isEntityLanguageControlled($entity)) {
    return AccessResult::neutral();
  }

  // Only perform the access check when performing update/delete operations.
  if (!in_array($operation, [
    'update',
    'delete',
  ])) {
    return AccessResult::neutral();
  }
  $language = $entity
    ->language();
  $user = \Drupal::service('allowed_languages.allowed_languages_manager')
    ->accountFromProxy($account);
  if (\Drupal::service('allowed_languages.allowed_languages_manager')
    ->hasPermissionForLanguage($language, $user)) {
    return AccessResult::allowed()
      ->cachePerUser()
      ->addCacheableDependency($user);
  }

  // Access check failed so do not allow the user to translate the specified
  // language.
  return AccessResult::forbidden()
    ->cachePerUser()
    ->addCacheableDependency($user);
}

/**
 * Get an array of languages to use with the allowed language checkboxes.
 *
 * @return array
 *   An array of languages keyed by id => name.
 */
function allowed_languages_get_language_options() {
  $element = [
    '#languages' => LanguageInterface::STATE_CONFIGURABLE,
  ];
  $language_element = language_process_language_select($element);
  $language_options = $language_element['#options'];
  asort($language_options);
  return $language_options;
}

Functions

Namesort descending Description
allowed_languages_entity_access Implements hook_entity_access().
allowed_languages_entity_base_field_info Implements hook_entity_base_field_info().
allowed_languages_field_widget_language_select_form_alter Implements hook_field_widget_WIDGET_TYPE_form_alter().
allowed_languages_form_user_form_alter Add the allowed languages checkboxes to the user form.
allowed_languages_get_language_options Get an array of languages to use with the allowed language checkboxes.
allowed_languages_help Implements hook_help().
allowed_languages_user_form_submit Allowed languages user form submit handler.