Resolves #50742: Translation handling fails in multi select fields (TCA)
[TYPO3CMS/Extensions/static_info_tables.git] / Classes / Hook / Backend / Form / ElementRenderingHelper.php
1 <?php
2 namespace SJBR\StaticInfoTables\Hook\Backend\Form;
3 use SJBR\StaticInfoTables\Utility\TcaUtility;
4 use SJBR\StaticInfoTables\Utility\LocalizationUtility;
5 use TYPO3\CMS\Core\Utility\GeneralUtility;
6 /***************************************************************
7 * Copyright notice
8 *
9 * (c) 2013 Stanislas Rolland <typo3(arobas)sjbr.ca>
10 * All rights reserved
11 *
12 * This script is part of the Typo3 project. The Typo3 project is
13 * free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * The GNU General Public License can be found at
19 * http://www.gnu.org/copyleft/gpl.html.
20 *
21 * This script is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
28 /**
29 * Custom rendering of some backend forms elements
30 *
31 */
32 class ElementRenderingHelper {
33 /**
34 * Translate selcted items before rendering
35 */
36 public function getSingleField_beforeRender($table, $field, $row, &$PA) {
37 if ($PA['fieldConf']['config']['form_type'] == 'select' && $PA['fieldConf']['config']['maxitems'] > 1) {
38 switch ($PA['fieldConf']['config']['foreign_table']) {
39 case 'static_countries':
40 case 'static_currencies':
41 case 'static_languages':
42 case 'static_territories':
43 $PA['itemFormElValue'] = $this->translateSelectedItems($PA['itemFormElValue'], $PA['fieldConf']['config']['foreign_table']);
44 break;
45 }
46 }
47 }
48
49 /*
50 * Add ISO codes to the label of entities
51 */
52 public function addIsoCodeToLabel (&$PA, &$fObj) {
53 $PA['title'] = $PA['row'][$GLOBALS['TCA'][$PA['table']]['ctrl']['label']];
54 if (TYPO3_MODE == 'BE') {
55 switch ($PA['table']) {
56 case 'static_territories':
57 $isoCode = $PA['row']['tr_iso_nr'];
58 if (!$isoCode) {
59 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
60 'uid,tr_iso_nr',
61 $PA['table'],
62 'uid = ' . intval($PA['row']['uid']) . TcaUtility::getEnableFields($PA['table'])
63 );
64 $isoCode = $rows[0]['tr_iso_nr'];
65 }
66 if ($isoCode) {
67 $PA['title'] = $PA['title'] . ' (' . $isoCode . ')';
68 }
69 break;
70 case 'static_countries':
71 $isoCode = $PA['row']['cn_iso_2'];
72 if (!$isoCode) {
73 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
74 'uid,cn_iso_2',
75 $PA['table'],
76 'uid = ' . intval($PA['row']['uid']) . TcaUtility::getEnableFields($PA['table'])
77 );
78 $isoCode = $rows[0]['cn_iso_2'];
79 }
80 if ($isoCode) {
81 $PA['title'] = $PA['title'] . ' (' . $isoCode . ')';
82 }
83 break;
84 case 'static_languages':
85 $isoCodes = array($PA['row']['lg_iso_2']);
86 if ($PA['row']['lg_country_iso_2']) {
87 $isoCodes[] = $PA['row']['lg_country_iso_2'];
88 }
89 $isoCode = implode('_', $isoCodes);
90 if (!$isoCode || !$PA['row']['lg_country_iso_2']) {
91 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
92 'uid,lg_iso_2,lg_country_iso_2',
93 $PA['table'],
94 'uid = ' . intval($PA['row']['uid']) . TcaUtility::getEnableFields($PA['table'])
95 );
96 $isoCodes = array($rows[0]['lg_iso_2']);
97 if ($rows[0]['lg_country_iso_2']) {
98 $isoCodes[] = $rows[0]['lg_country_iso_2'];
99 }
100 $isoCode = implode('_', $isoCodes);
101 }
102 if ($isoCode) {
103 $PA['title'] = $PA['title'] . ' (' . $isoCode . ')';
104 }
105 break;
106 case 'static_currencies':
107 $isoCode = $PA['row']['cu_iso_3'];
108 if (!$isoCode) {
109 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
110 'uid,cu_iso_3',
111 $PA['table'],
112 'uid = ' . intval($PA['row']['uid']) . TcaUtility::getEnableFields($PA['table'])
113 );
114 $isoCode = $rows[0]['cu_iso_3'];
115 }
116 if ($isoCode) {
117 $PA['title'] = $PA['title'] . ' (' . $isoCode . ')';
118 }
119 break;
120 default:
121 break;
122 }
123 }
124 }
125
126 /*
127 * Translate and sort the territories selector using the current locale
128 */
129 public function translateTerritoriesSelector($PA, $fObj) {
130 switch ($PA['table']) {
131 case 'static_territories':
132 // Avoid circular relation
133 $row = $PA['row'];
134 foreach ($PA['items'] as $index => $item) {
135 if ($item[1] == $row['uid']) {
136 unset($PA['items'][$index]);
137 }
138 }
139 break;
140 }
141 $PA['items'] = $this->translateSelectorItems($PA['items'], 'static_territories');
142 }
143
144 /*
145 * Translate and sort the countries selector using the current locale
146 */
147 public function translateCountriesSelector($PA, $fObj) {
148 $PA['items'] = $this->translateSelectorItems($PA['items'], 'static_countries');
149 }
150
151 /*
152 * Translate and sort the currencies selector using the current locale
153 */
154 public function translateCurrenciesSelector($PA, $fObj) {
155 $PA['items'] = $this->translateSelectorItems($PA['items'], 'static_currencies');
156 }
157
158 /**
159 * Translate and sort the languages selector using the current locale
160 */
161 public function translateLanguagesSelector($PA, $fObj) {
162 $PA['items'] = $this->translateSelectorItems($PA['items'], 'static_languages');
163 }
164
165 /**
166 * Translate selector items array
167 *
168 * @param array $items: array of value/label pairs
169 * @param string $tableName: name of static info tables
170 * @return array array of value/translated label pairs
171 */
172 protected function translateSelectorItems($items, $tableName) {
173 $translatedItems = $items;
174 foreach ($translatedItems as $key => $item) {
175 if ($translatedItems[$key][1]) {
176 //Get isocode if present
177 $code = strstr($item[0], '(');
178 $code2 = strstr(substr($code, 1), '(');
179 $code = $code2 ? $code2 : $code;
180 // Translate
181 $translatedItems[$key][0] = LocalizationUtility::translate(array('uid' => $item[1]), $tableName);
182 // Re-append isocode, if present
183 $translatedItems[$key][0] = $translatedItems[$key][0] . ($code ? ' ' . $code : '');
184 }
185 }
186 $currentLocale = setlocale(LC_COLLATE, '0');
187 $locale = \SJBR\StaticInfoTables\Utility\LocalizationUtility::setCollatingLocale();
188 if ($locale !== FALSE) {
189 uasort($translatedItems, array($this, 'strcollOnLabels'));
190 }
191 setlocale(LC_COLLATE, $currentLocale);
192 return $translatedItems;
193 }
194
195 /**
196 * Translate selector items array
197 *
198 * @param string $itemFormElValue: value of the form element
199 * @param string $tableName: name of static info tables
200 * @return string value of the form element with translated labels
201 */
202 protected function translateSelectedItems($itemFormElValue, $tableName) {
203 // Get the array with selected items:
204 $itemArray = GeneralUtility::trimExplode(',', $itemFormElValue, 1);
205 // Perform modification of the selected items array:
206 foreach ($itemArray as $tk => $tv) {
207 $tvP = explode('|', $tv, 2);
208 if ($tvP[0]) {
209 //Get isocode if present
210 $code = strstr($tvP[1], '%28');
211 $code2 = strstr(substr($code, 1), '%28');
212 $code = $code2 ? $code2 : $code;
213 // Translate
214 $tvP[1] = LocalizationUtility::translate(array('uid' => $tvP[0]), $tableName);
215 // Re-append isocode, if present
216 $tvP[1] = $tvP[1] . ($code ? '%20' . $code : '');
217 }
218 $itemArray[$tk] = implode('|', $tvP);
219 }
220 return implode(',', $itemArray);
221 }
222
223 /**
224 * Using strcoll comparison on labels
225 *
226 * @return integer see strcoll
227 */
228 protected function strcollOnLabels($itemA, $itemB) {
229 return strcoll($itemA[0], $itemB[0]);
230 }
231 }
232 ?>