Spaces:
No application file
No application file
| namespace Mautic\CoreBundle\Model; | |
| use Mautic\CoreBundle\Entity\TranslationEntityInterface; | |
| use Mautic\LeadBundle\Entity\Lead; | |
| use Symfony\Component\HttpFoundation\Request; | |
| /** | |
| * Provides helper methods for determine the requested language from contact's profile and/or request. | |
| */ | |
| trait TranslationModelTrait | |
| { | |
| /** | |
| * Get the entity based on requested translation. | |
| * | |
| * @param Lead|array|null $lead | |
| * | |
| * @return array[$parentEntity, TranslationEntityInterface $entity] | |
| */ | |
| public function getTranslatedEntity(TranslationEntityInterface $entity, $lead = null, Request $request = null): array | |
| { | |
| [$translationParent, $translationChildren] = $entity->getTranslations(); | |
| $leadPreference = $chosenLanguage = null; | |
| if (count($translationChildren)) { | |
| if ($translationParent) { | |
| $translationChildren = $translationParent->getTranslationChildren(); | |
| } else { | |
| $translationParent = $entity; | |
| } | |
| // Generate a list of translations | |
| $translations = [$translationParent->getId() => $translationParent->getLanguage()]; | |
| foreach ($translationChildren as $c) { | |
| $translations[$c->getId()] = $c->getLanguage(); | |
| } | |
| // Generate a list of translations for this entity | |
| $translationList = []; | |
| foreach ($translations as $id => $language) { | |
| $core = $this->getTranslationLocaleCore($language); | |
| if (!isset($translationList[$core])) { | |
| $translationList[$core] = []; | |
| } | |
| $translationList[$core][$language] = $id; | |
| } | |
| // Get the contact's preferred language if defined | |
| $languageList = []; | |
| $leadPreference = null; | |
| if ($lead) { | |
| if ($lead instanceof Lead) { | |
| $languageList[$leadPreference] = $lead->getPreferredLocale(); | |
| } elseif (is_array($lead) && isset($lead['preferred_locale'])) { | |
| $languageList[$leadPreference] = $lead['preferred_locale']; | |
| } | |
| } | |
| // Check request for language | |
| if (null !== $request) { | |
| $browserLanguages = $request->server->get('HTTP_ACCEPT_LANGUAGE'); | |
| if (!empty($browserLanguages)) { | |
| $browserLanguages = explode(',', $browserLanguages); | |
| foreach ($browserLanguages as $language) { | |
| if (($pos = strpos($language, ';q=')) !== false) { | |
| // remove weights | |
| $language = substr($language, 0, $pos + 1); | |
| } | |
| // change - to _ | |
| $language = str_replace('-', '_', $language); | |
| if (!isset($languageList[$language])) { | |
| $languageList[$language] = $language; | |
| } | |
| } | |
| } | |
| } | |
| $matchFound = false; | |
| $preferredCore = false; | |
| foreach ($languageList as $language) { | |
| $core = $this->getTranslationLocaleCore($language); | |
| if (isset($translationList[$core])) { | |
| // Does the dialect exist? | |
| if (isset($translationList[$core][$language])) { | |
| // There's a match | |
| $matchFound = $translationList[$core][$language]; | |
| $chosenLanguage = $language; | |
| break; | |
| } elseif (!$preferredCore) { | |
| // This will be the fallback if no matches are found | |
| $preferredCore = $core; | |
| } | |
| } | |
| } | |
| if ($matchFound) { | |
| // A translation was found based on language preference | |
| $entity = ($matchFound == $translationParent->getId()) ? $translationParent : $translationChildren[$matchFound]; | |
| } elseif ($preferredCore) { | |
| // Return the best matching language | |
| $bestMatch = array_values($translationList[$preferredCore])[0]; | |
| $entity = ($bestMatch == $translationParent->getId()) ? $translationParent : $translationChildren[$bestMatch]; | |
| $chosenLanguage = $preferredCore; | |
| } | |
| } | |
| // Save the preferred language to the lead's profile | |
| if (!$leadPreference && !empty($chosenLanguage) && $lead instanceof Lead) { | |
| $lead->addUpdatedField('preferred_locale', $chosenLanguage); | |
| } | |
| // Return the translation parent and translated entity | |
| return [$translationParent, $entity]; | |
| } | |
| /** | |
| * Run post saving a translation aware entity. | |
| */ | |
| public function postTranslationEntitySave(TranslationEntityInterface $entity): void | |
| { | |
| // If parent, add this entity as a child of the parent so that it populates the list in the tab (due to Doctrine hanging on to entities in memory) | |
| if ($translationParent = $entity->getTranslationParent()) { | |
| $translationParent->addTranslationChild($entity); | |
| } | |
| } | |
| /** | |
| * @return string | |
| */ | |
| protected function getTranslationLocaleCore($locale) | |
| { | |
| if (str_contains($locale, '_')) { | |
| $locale = substr($locale, 0, 2); | |
| } | |
| return $locale; | |
| } | |
| } | |