Puncte:1

How to override a class method that is not a service?

drapel lb

Usually we override services using RouteSubscribers, but i need to override a method of a class that is not a service. I need to alter the module of the core "views", the general structure of this module is:

> views
  > src
    > Entity
      > Render
        - ConfigurableLanguageRenderer.php
        - EntityTranslationRenderTrait.php

I need to override one method of one of those files.

In ConfigurableLanguageRenderer.php i need to override "getLanguage()" method or in EntityTranslationRenderTrait.php i need to override "getEntityTranslation()" method, but i don't know how override a trait or a class that is not a service, is that possible? Thanks.

--- More context ---

A hook_language_fallback_candidates_OPERATION_alter() was implemented and we have a custom priority candidates to return the content translated, but one validation in the views module broke my custom fallback candidates.

E.G: if the content was written in English(en), and you send in the view rest the parameter lang=en, the view will be skip to search the translation in the candidates and the hook_language_fallback... doesn't be executed because if you looking for a node in english and this article has english as default is not necessary to search translation and this return the original language of the content.

Then i need to alter the langcode that return $this->getEntityTranslationRenderer()->getLangcode($row)

  • ConfigurableLanguageRenderer.php

    public function getEntityTranslation(EntityInterface $entity, ResultRow $row) {
      // We assume the same language should be used for all entity fields
      // belonging to a single row, even if they are attached to different entity
      // types. Below we apply language fallback to ensure a valid value is always
      // picked.
      $translation = $entity;
      if ($entity instanceof TranslatableInterface && count($entity->getTranslationLanguages()) > 1) {
        $langcode = $this->getEntityTranslationRenderer()->getLangcode($row);
        $translation = $this->getEntityRepository()->getTranslationFromContext($entity, $langcode);
      }
      return $translation;
    }
    

So i need to alter those methods or alter the default language of the node, or if it's possible alter "context" to enter to the following validation: ($entity->language()->getId() != $langcode)

public function getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = []) {
    $translation = $entity;

    if ($entity instanceof TranslatableDataInterface && count($entity->getTranslationLanguages()) > 1) {
      if (empty($langcode)) {
        $langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
        $entity->addCacheContexts(['languages:' . LanguageInterface::TYPE_CONTENT]);
      }

      // Retrieve language fallback candidates to perform the entity language
      // negotiation, unless the current translation is already the desired one.
      if ($entity->language()->getId() != $langcode) {
        $context['data'] = $entity;
        $context += ['operation' => 'entity_view', 'langcode' => $langcode];
        $candidates = $this->languageManager->getFallbackCandidates($context);

        // Ensure the default language has the proper language code.
        $default_language = $entity->getUntranslated()->language();
        $candidates[$default_language->getId()] = LanguageInterface::LANGCODE_DEFAULT;

        // Return the most fitting entity translation.
        foreach ($candidates as $candidate) {
          if ($entity->hasTranslation($candidate)) {
            $translation = $entity->getTranslation($candidate);
            break;
          }
        }
      }
    }

    return $translation;
  }

-- Update --

as @4k4 mentioned i overwritten the service EntityRepository.php and that solved my problem

class GlobalizationServiceProvider extends ServiceProviderBase {

  /**
  * {@inheritdoc}
  */
  public function alter(ContainerBuilder $container) {
    if ($container->hasDefinition('entity.repository')) {
      $definition = $container->getDefinition('entity.repository');
      $definition->setClass('Drupal\Globalization\CustomEntityRepository');
    }
  }
}
drapel in
Poate doriți să oferiți puțin context cu privire la ceea ce încercați să realizați. Ar putea exista și alte modalități de a realiza ceea ce încerci să faci decât această abordare.
Puncte:1
drapel cn

Prima clasă este codificată greu în a doua clasă, iar a doua clasă este o trăsătură utilizată în diferite pluginuri de câmp și rând. Deci, trebuie să vizați unul dintre aceste pluginuri. Există mai multe moduri. Cel mai preferat este să atribuiți un ID de plugin personalizat clasei de plugin extinse și să îl configurați în vizualizarea personalizată. Dacă doriți să suprascrieți clasa de plugin în general, vedeți Cum înlocuiesc un plugin?


Ultima metodă pe care ați adăugat-o mai mult context este într-un serviciu și puteți implementa MyEntityRepository::getTranslationFromContext() și apoi schimbați clasa într-un ServiceProvider (nu RouteSubcriber): Vezi modificarea serviciilor existente.

Mauricio avatar
drapel lb
ca @4k4, asta a fost soluția la problema mea, mulțumesc

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.