Issues (3627)

bundles/CoreBundle/Model/TranslationModelTrait.php (1 issue)

1
<?php
2
3
/*
4
 * @copyright   2016 Mautic Contributors. All rights reserved
5
 * @author      Mautic
6
 *
7
 * @link        http://mautic.org
8
 *
9
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10
 */
11
12
namespace Mautic\CoreBundle\Model;
13
14
use Mautic\CoreBundle\Entity\TranslationEntityInterface;
15
use Mautic\LeadBundle\Entity\Lead;
16
use Symfony\Component\HttpFoundation\Request;
17
18
/**
19
 * Provides helper methods for determine the requested language from contact's profile and/or request.
20
 *
21
 * Class TranslationModelTrait
22
 */
23
trait TranslationModelTrait
24
{
25
    /**
26
     * Get the entity based on requested translation.
27
     *
28
     * @param Lead|array|null $lead
29
     *
30
     * @return array[$parentEntity, TranslationEntityInterface $entity]
31
     */
32
    public function getTranslatedEntity(TranslationEntityInterface $entity, $lead = null, Request $request = null)
33
    {
34
        list($translationParent, $translationChildren) = $entity->getTranslations();
35
36
        $leadPreference = $chosenLanguage = null;
37
38
        if (count($translationChildren)) {
39
            if ($translationParent) {
40
                $translationChildren = $translationParent->getTranslationChildren();
41
            } else {
42
                $translationParent = $entity;
43
            }
44
45
            // Generate a list of translations
46
            $translations = [$translationParent->getId() => $translationParent->getLanguage()];
47
            foreach ($translationChildren as $c) {
48
                $translations[$c->getId()] = $c->getLanguage();
49
            }
50
51
            // Generate a list of translations for this entity
52
            $translationList = [];
53
            foreach ($translations as $id => $language) {
54
                $core = $this->getTranslationLocaleCore($language);
55
                if (!isset($languageList[$core])) {
56
                    $translationList[$core] = [];
57
                }
58
                $translationList[$core][$language] = $id;
59
            }
60
61
            // Get the contact's preferred language if defined
62
            $languageList   = [];
63
            $leadPreference = null;
64
            if ($lead) {
65
                if ($lead instanceof Lead) {
66
                    $languageList[$leadPreference] = $lead->getPreferredLocale();
67
                } elseif (is_array($lead) && isset($lead['preferred_locale'])) {
68
                    $languageList[$leadPreference] = $lead['preferred_locale'];
69
                }
70
            }
71
72
            // Check request for language
73
            if (null !== $request) {
74
                $browserLanguages = $request->server->get('HTTP_ACCEPT_LANGUAGE');
75
                if (!empty($browserLanguages)) {
76
                    $browserLanguages = explode(',', $browserLanguages);
77
                    if (!empty($browserLanguages)) {
78
                        foreach ($browserLanguages as $language) {
79
                            if ($pos = false !== strpos($language, ';q=')) {
80
                                //remove weights
81
                                $language = substr($language, 0, ($pos + 1));
82
                            }
83
                            //change - to _
84
                            $language = str_replace('-', '_', $language);
85
86
                            if (!isset($languageList[$language])) {
87
                                $languageList[$language] = $language;
88
                            }
89
                        }
90
                    }
91
                }
92
            }
93
94
            $matchFound    = false;
95
            $preferredCore = false;
96
            foreach ($languageList as $language) {
97
                $core = $this->getTranslationLocaleCore($language);
98
                if (isset($translationList[$core])) {
99
                    // Does the dialect exist?
100
                    if (isset($translationList[$core][$language])) {
101
                        // There's a match
102
                        $matchFound     = $translationList[$core][$language];
103
                        $chosenLanguage = $language;
104
                        break;
105
                    } elseif (!$preferredCore) {
106
                        // This will be the fallback if no matches are found
107
                        $preferredCore = $core;
108
                    }
109
                }
110
            }
111
112
            if ($matchFound) {
113
                // A translation was found based on language preference
114
                $entity = ($matchFound == $translationParent->getId()) ? $translationParent : $translationChildren[$matchFound];
115
            } elseif ($preferredCore) {
116
                // Return the best matching language
117
                $bestMatch      = array_values($translationList[$preferredCore])[0];
118
                $entity         = ($bestMatch == $translationParent->getId()) ? $translationParent : $translationChildren[$bestMatch];
119
                $chosenLanguage = $preferredCore;
120
            }
121
        }
122
123
        // Save the preferred language to the lead's profile
124
        if (!$leadPreference && !empty($chosenLanguage) && $lead instanceof Lead) {
0 ignored issues
show
$leadPreference is of type null, thus it always evaluated to false.
Loading history...
125
            $lead->addUpdatedField('preferred_locale', $chosenLanguage);
126
        }
127
128
        // Return the translation parent and translated entity
129
        return [$translationParent, $entity];
130
    }
131
132
    /**
133
     * Run post saving a translation aware entity.
134
     */
135
    public function postTranslationEntitySave(TranslationEntityInterface $entity)
136
    {
137
        // 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)
138
        if ($translationParent = $entity->getTranslationParent()) {
139
            $translationParent->addTranslationChild($entity);
140
        }
141
    }
142
143
    /**
144
     * @param $locale
145
     *
146
     * @return string
147
     */
148
    protected function getTranslationLocaleCore($locale)
149
    {
150
        if (false !== strpos($locale, '_')) {
151
            $locale = substr($locale, 0, 2);
152
        }
153
154
        return $locale;
155
    }
156
}
157