44
55namespace Sitegeist \LostInTranslation \Controller ;
66
7+ use DeepL \GlossaryInfo ;
8+ use Neos \Error \Messages \Message ;
79use Neos \Fusion \View \FusionView ;
810use Neos \Neos \Controller \Module \AbstractModuleController ;
911use Neos \Flow \Annotations as Flow ;
12+ use Sitegeist \LostInTranslation \Domain \Model \Glossary ;
13+ use Sitegeist \LostInTranslation \Domain \Model \GlossaryEntry ;
14+ use Sitegeist \LostInTranslation \Domain \Repository \GlossaryRepository ;
15+ use Sitegeist \LostInTranslation \Infrastructure \DeepL \DeepLCacheService ;
1016use Sitegeist \LostInTranslation \Infrastructure \DeepL \DeepLCustomAuthenticationKeyService ;
17+ use Sitegeist \LostInTranslation \Infrastructure \DeepL \DeepLGlossaryService ;
1118use Sitegeist \LostInTranslation \Infrastructure \DeepL \DeepLTranslationService ;
1219
1320class LostInTranslationModuleController extends AbstractModuleController
@@ -18,19 +25,56 @@ class LostInTranslationModuleController extends AbstractModuleController
1825 */
1926 protected $ translationService ;
2027
28+ /**
29+ * @var DeepLCacheService
30+ * @Flow\Inject
31+ */
32+ protected $ cacheService ;
33+
34+ /**
35+ * @var DeepLGlossaryService
36+ * @Flow\Inject
37+ */
38+ protected $ glossaryService ;
39+
40+ /**
41+ * @var GlossaryRepository
42+ * @Flow\Inject
43+ */
44+ protected $ glossaryRepository ;
45+
2146 /**
2247 * @Flow\Inject
2348 * @var DeepLCustomAuthenticationKeyService
2449 */
2550 protected $ customAuthenticationKeyService ;
2651
52+ /**
53+ * @Flow\InjectConfiguration(path="nodeTranslation.languageDimensionName")
54+ * @var string
55+ */
56+ protected $ languageDimensionName ;
57+
58+ /**
59+ * @Flow\InjectConfiguration(package="Neos.ContentRepository", path="contentDimensions")
60+ * @var array<string,array{'default': string, 'defaultPreset': string, 'presets': array<string,mixed> }>
61+ */
62+ protected $ contentDimensionConfiguration ;
63+
2764 /**
2865 * @var FusionView
2966 */
3067 protected $ view ;
3168
3269
3370 public function indexAction (): void
71+ {
72+ $ status = $ this ->translationService ->getStatus ();
73+ $ this ->view ->assign ('status ' , $ status );
74+ $ this ->view ->assign ('glossaries ' , $ this ->glossaryRepository ->findAll ()->toArray ());
75+ }
76+
77+ public function showStatusAction (): void
3478 {
3579 $ status = $ this ->translationService ->getStatus ();
3680 $ this ->view ->assign ('status ' , $ status );
@@ -51,4 +95,134 @@ public function removeCustomKeyAction(): void
5195 $ this ->customAuthenticationKeyService ->remove ();
5296 $ this ->forward ('index ' );
5397 }
98+
99+ /**
100+ * The list of supported language pairs is narrowed by only including exising language dimension
101+ * values and removing already existing glossaries. We only look into the first segments as this
102+ * deepl glossaries currently do not support country identifiers
103+ */
104+ public function createGlossaryAction (): void
105+ {
106+ $ languageKeysOfInterest = [];
107+ $ languagePresets = $ this ->contentDimensionConfiguration [$ this ->languageDimensionName ]['presets ' ];
108+ foreach ($ languagePresets as $ key => $ languagePreset ) {
109+ $ deeplLanguage = $ languagePreset ['options ' ]['deeplLanguage ' ] ?? null ;
110+ if ($ deeplLanguage ) {
111+ $ deeplLanguagesParts = explode (': ' , $ deeplLanguage );
112+ foreach ($ deeplLanguagesParts as $ deeplLanguagesPart ) {
113+ $ keyParts = explode ('- ' , $ deeplLanguagesPart );
114+ $ languageKeysOfInterest [] = strtolower ($ keyParts [0 ]);
115+ }
116+ } else {
117+ $ keyParts = explode ('- ' , $ key );
118+ $ languageKeysOfInterest [] = strtolower ($ keyParts [0 ]);
119+ }
120+ }
121+
122+ $ languageKeysOfInterest = array_unique ($ languageKeysOfInterest );
123+ $ languagePairs = $ this ->glossaryService ->getGlossaryLanguagePairs ();
124+ $ sourceTargetCombinations = [];
125+ foreach ($ languagePairs as $ languagePair ) {
126+ if (in_array ($ languagePair ->sourceLang , $ languageKeysOfInterest ) && in_array ($ languagePair ->targetLang , $ languageKeysOfInterest )) {
127+ $ existingGlossary = $ this ->glossaryRepository ->findOneBySourceAndTargetLanguageKey ($ languagePair ->sourceLang , $ languagePair ->targetLang );
128+ if ($ existingGlossary ) {
129+ continue ;
130+ }
131+ $ sourceTargetCombinations [] = $ languagePair ->sourceLang . ' -> ' . $ languagePair ->targetLang ;
132+ }
133+ }
134+
135+ $ this ->view ->assign ('sourceTargetCombinations ' , $ sourceTargetCombinations );
136+ }
137+
138+ public function addGlossaryAction (string $ sourceAndTarget ): void
139+ {
140+ list ($ source , $ target ) = explode (' -> ' , $ sourceAndTarget );
141+ $ existingGlossary = $ this ->glossaryRepository ->findOneBySourceAndTargetLanguageKey ($ source , $ target );
142+ if ($ existingGlossary instanceof Glossary) {
143+ $ this ->addFlashMessage ('Glossary already exists! ' , '' , Message::SEVERITY_WARNING );
144+ $ this ->forward (actionName: 'showGlossary ' , arguments: ['glossary ' => $ existingGlossary ]);
145+ }
146+ $ glossary = Glossary::create ($ source , $ target );
147+ $ this ->glossaryRepository ->add ($ glossary );
148+ $ this ->forward ('index ' );
149+ }
150+
151+ public function showGlossaryAction (Glossary $ glossary ): void
152+ {
153+ $ this ->view ->assign ('glossary ' , $ glossary );
154+ }
155+
156+ public function uploadGlossaryAction (Glossary $ glossary , bool $ toIndex = false ): void
157+ {
158+ $ identifier = $ this ->glossaryService ->uploadRemoteGlossary ($ glossary );
159+
160+ if (is_string ($ identifier )) {
161+ $ glossary ->updateSynchronizationIdentifier ($ identifier );
162+ $ this ->glossaryRepository ->update ($ glossary );
163+ $ this ->cacheService ->flush ();
164+ $ deleted = $ this ->glossaryService ->cleanupRemoteGlossaries ();
165+ $ removedNumber = count ($ deleted );
166+ if ($ removedNumber == 0 ) {
167+ $ this ->addFlashMessage ("Glossary was uploaded " , "" );
168+ } elseif ($ removedNumber == 1 ) {
169+ $ this ->addFlashMessage (sprintf ("Glossary was uploaded, %s outdated glossary was removed " , $ removedNumber ), "" );
170+ } else {
171+ $ this ->addFlashMessage (sprintf ("Glossary was uploaded, %s outdated glossaries were removed " , $ removedNumber ), "" );
172+ }
173+ } else {
174+ $ this ->addFlashMessage ("Upload failed " , "" , Message::SEVERITY_ERROR );
175+ }
176+
177+ if ($ toIndex === true ) {
178+ $ this ->forward (actionName: 'index ' );
179+ } else {
180+ $ this ->forward (actionName: 'showGlossary ' , arguments: ['glossary ' => $ glossary ]);
181+ }
182+ }
183+
184+ public function deleteGlossaryAction (Glossary $ glossary ): void
185+ {
186+ $ this ->glossaryRepository ->remove ($ glossary );
187+ $ this ->addFlashMessage ('Glossary deleted ' );
188+ $ this ->forward ('index ' );
189+ }
190+
191+ public function createGlossaryEntryAction (Glossary $ glossary ): void
192+ {
193+ $ this ->view ->assign ('glossary ' , $ glossary );
194+ }
195+
196+ public function addGlossaryEntryAction (Glossary $ glossary , string $ sourceText , string $ targetText ): void
197+ {
198+ $ entry = new GlossaryEntry ();
199+ $ entry ->glossary = $ glossary ;
200+ $ entry ->sourceText = $ sourceText ;
201+ $ entry ->targetText = $ targetText ;
202+ $ glossary ->addEntry ($ entry );
203+ $ this ->glossaryRepository ->update ($ glossary );
204+ $ this ->forward (actionName: 'showGlossary ' , arguments: ['glossary ' => $ glossary ]);
205+ }
206+ public function editGlossaryEntryAction (GlossaryEntry $ entry ): void
207+ {
208+ $ this ->view ->assign ('entry ' , $ entry );
209+ $ this ->view ->assign ('glossary ' , $ entry ->glossary );
210+ }
211+
212+ public function updateGlossaryEntryAction (GlossaryEntry $ entry , string $ sourceText , string $ targetText ): void
213+ {
214+ $ entry ->sourceText = $ sourceText ;
215+ $ entry ->targetText = $ targetText ;
216+ $ entry ->glossary ->updateModificationDate ();
217+ $ this ->glossaryRepository ->update ($ entry ->glossary );
218+ $ this ->forward (actionName: 'showGlossary ' , arguments: ['glossary ' => $ entry ->glossary ]);
219+ }
220+
221+ public function deleteGlossaryEntryAction (GlossaryEntry $ entry ): void
222+ {
223+ $ glossary = $ entry ->glossary ;
224+ $ glossary ->removeEntry ($ entry );
225+ $ this ->glossaryRepository ->update ($ glossary );
226+ $ this ->forward (actionName: 'showGlossary ' , arguments: ['glossary ' => $ glossary ]);
227+ }
54228}
0 commit comments