Commit dee2a1e8 authored by Tim Bozeman's avatar Tim Bozeman Committed by Tim Bozeman
Browse files

Issue #3325340 by Tim Bozeman: Translation improvements

parent 5fcb0362
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -373,7 +373,9 @@ class EntityVariationHandler extends EntityHandlerBase {
        if (!\str_contains($deleted_variation_code, '-')) {
          continue;
        }
        [$langcode, $deleted_variant_delta] = \explode('-', $deleted_variation_code);
        $langcode_info = LocationHandler::parseCode($deleted_variation_code);
        $langcode = $langcode_info['langcode'];
        $deleted_variant_delta = $langcode_info['location'];

        // If this entity is the default localization.
        if ($langcode === LocationHandler::DEFAULT_LANGUAGE) {
@@ -382,7 +384,9 @@ class EntityVariationHandler extends EntityHandlerBase {

          // Delete the translations of this localization.
          foreach ($entity->getTranslationLanguages() as $code => $l) {
            [$lang, $delta] = \explode('-', $code);
            $langcode_info = LocationHandler::parseCode($deleted_variation_code);
            $lang = $langcode_info['langcode'];
            $delta = $langcode_info['location'];
            if ($langcode !== $lang && $deleted_variant_delta === $delta) {
              $entity->removeTranslation($code);
              $need_to_save = TRUE;
@@ -397,7 +401,9 @@ class EntityVariationHandler extends EntityHandlerBase {
          $variant_references = $entity->get('variants')->getValue();
          $variant_references_map = [];
          foreach ($entity->getTranslationLanguages() as $current_code => $current_language) {
            [$current_langcode, $current_variant_delta] = \explode('-', $current_code);
            $langcode_info = LocationHandler::parseCode($deleted_variation_code);
            $current_langcode = $langcode_info['langcode'];
            $current_variant_delta = $langcode_info['location'];
            // If the current variation delta is greater than the delta that was
            // removed.
            if ($current_variant_delta > $deleted_variant_delta) {
+47 −3
Original line number Diff line number Diff line
@@ -2,12 +2,15 @@

namespace Drupal\location_variant\Form;

use Drupal\Core\Url;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\TempStore\PrivateTempStore;
use Drupal\location_variant\LocationHandler;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\location_variant\EntityVariationHandler;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
@@ -18,19 +21,22 @@ class AddLocation extends FormBase {
  protected EntityVariationHandler $entityVariationHandler;
  private LocationHandler $locationHandler;
  private PrivateTempStore $tempStore;
  protected EntityTypeManagerInterface $entityTypeManager;

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('location_variant.entity_handler'),
      $container->get('location_variant.location_handler'),
      $container->get('tempstore.private')
      $container->get('tempstore.private'),
      $container->get('entity_type.manager')
    );
  }

  public function __construct(EntityVariationHandler $entity_location_handler, LocationHandler $location_handler, PrivateTempStoreFactory $temp_store) {
  public function __construct(EntityVariationHandler $entity_location_handler, LocationHandler $location_handler, PrivateTempStoreFactory $temp_store, EntityTypeManagerInterface $entityTypeManager) {
    $this->entityVariationHandler = $entity_location_handler;
    $this->locationHandler = $location_handler;
    $this->tempStore = $temp_store->get('location_variant');
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
@@ -45,10 +51,48 @@ class AddLocation extends FormBase {
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form_state->set('workspace_safe', TRUE);
    // Check that we haven't reached the variant limit.
    $route_match = $this->getRouteMatch();
    $entity_type_id = $route_match->getParameter('entity_type_id');
    $entity_id = $route_match->getRawParameter($entity_type_id);
    $entity = $this->entityTypeManager->getStorage($entity_type_id)->load($entity_id);
    $variants = $this->entityVariationHandler->getVariants($entity);
    $max_variants = $this->config('variants.settings')->get('variant_limit');
    if (count($variants) >= $max_variants) {
      $this->messenger()->addWarning($this->t('This entity already has %max localizations which is the <a href="@settings_url">current maximum</a>.', [
        '%max' => $max_variants,
        '@settings_url' => Url::fromRoute('variants_settings')->toString(),
      ]));
      return new RedirectResponse($entity->toUrl('drupal:content-translation-overview')->toString());
    }

    $location_options = $this->locationHandler->getLocationOptions();
    $location_variants = $this->entityTypeManager->getStorage('variant')->loadByProperties(['entity_id' => $entity_id]);
    if ($location_variants) {
      foreach ($location_variants as $location) {
        $location_code = $location->get('locations')->getValue()[0]['value'] ?? '';
        if ($location_code && isset($location_options[$location_code])) {
          // Mark any already used locations as an option group since disabling
          // single select options is STILL not supported.
          $i = 0;
          foreach ($location_options as $location_id => $label) {
            if ($location_code === $location_id) {
              $location_options = array_slice($location_options, 0, $i, true) +
                [ltrim($label) => []] +
                array_slice($location_options, $i, NULL, true);
              unset($location_options[$location_id]);
              break;
            }
            $i++;
          }
        }
      }
    }

    $form['locations'] = [
      '#type' => 'select',
      '#title' => $this->t('Location'),
      '#options' => $this->locationHandler->getAvailableLocationOptions(),
      '#options' => $location_options,
      '#required' => TRUE,
      '#multiple' => TRUE,
    ];
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ class VariationDeleteForm extends ContentEntityDeleteForm {
        if ($langcode_to_delete === LocationHandler::DEFAULT_LANGUAGE) {
          // Delete the translations of this localization.
          foreach ($entity->getTranslationLanguages() as $variation_code => $langcode) {
            [, $delta] = \explode('-', $variation_code);
            $delta = LocationHandler::parseCode($variation_code)['location'];
            if ($delta === $delta_to_delete && $variation_code !== $variation_code_to_delete) {
              $variation = $entity->getTranslation($variation_code);
              $variations[] = $variation->label();
+0 −40
Original line number Diff line number Diff line
@@ -124,46 +124,6 @@ class LocationHandler {
    return $options;
  }

  /**
   * Get an array of location options, excluding locations that already exist.
   *
   * @param bool $rebuild
   *   Flag to rebuild locations.
   *
   * @return array
   *   An array of location options.
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function getAvailableLocationOptions(bool $rebuild = FALSE): array {
    // Get the current entity ID.
    $request = $this->requestStack->getCurrentRequest();
    $entity_type = $request->attributes->get('entity_type_id');
    $entity = $request->attributes->get($entity_type);
    $entity_id = $entity->id();

    // Find any variants belonging to the current entity ID.
    $location_variants = $this->entityTypeManager->getStorage('variant')->loadByProperties(['entity_id' => $entity_id,]);

    // Return the default location options if we found no variants.
    $location_options = $this->getLocationOptions($rebuild);
    if (!$location_variants) {
      return $location_options;
    }

    // If we have variants, get their locations and remove them from the
    // locations array.
    $extant_locations = [];
    foreach ($location_variants as $location) {
      $location_code = $location->get('locations')->getValue()[0]['value'] ?? '';
      if (!$location_code) {
        continue;
      }
      $extant_locations[$location_code] = $location_code;
    }
    return array_filter($location_options, fn($location_code) => !in_array($location_code, $extant_locations), ARRAY_FILTER_USE_KEY);
  }

  /**
   * Append child options.
   *