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');
}
}
}