Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
7e9e8871 | 4 | | CiviCRM version 4.7 | |
6a488035 | 5 | +--------------------------------------------------------------------+ |
0f03f337 | 6 | | Copyright CiviCRM LLC (c) 2004-2017 | |
6a488035 TO |
7 | +--------------------------------------------------------------------+ |
8 | | This file is a part of CiviCRM. | | |
9 | | | | |
10 | | CiviCRM is free software; you can copy, modify, and distribute it | | |
11 | | under the terms of the GNU Affero General Public License | | |
12 | | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | | |
13 | | | | |
14 | | CiviCRM is distributed in the hope that it will be useful, but | | |
15 | | WITHOUT ANY WARRANTY; without even the implied warranty of | | |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | | |
17 | | See the GNU Affero General Public License for more details. | | |
18 | | | | |
19 | | You should have received a copy of the GNU Affero General Public | | |
20 | | License and the CiviCRM Licensing Exception along | | |
21 | | with this program; if not, contact CiviCRM LLC | | |
22 | | at info[AT]civicrm[DOT]org. If you have questions about the | | |
23 | | GNU Affero General Public License or the licensing of CiviCRM, | | |
24 | | see the CiviCRM license FAQ at http://civicrm.org/licensing | | |
25 | +--------------------------------------------------------------------+ | |
d25dd0ee | 26 | */ |
6a488035 TO |
27 | |
28 | /** | |
29 | * | |
30 | * @package CRM | |
0f03f337 | 31 | * @copyright CiviCRM LLC (c) 2004-2017 |
6a488035 TO |
32 | */ |
33 | ||
34 | /** | |
ce064e4f | 35 | * This class generates form components for Localization. |
6a488035 TO |
36 | */ |
37 | class CRM_Admin_Form_Setting_Localization extends CRM_Admin_Form_Setting { | |
8a61528e TO |
38 | |
39 | protected $_settings = array( | |
9c325795 | 40 | 'contact_default_language' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, |
8a61528e TO |
41 | 'countryLimit' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, |
42 | 'customTranslateFunction' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
43 | 'defaultContactCountry' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
44 | 'defaultContactStateProvince' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
45 | 'defaultCurrency' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
46 | 'fieldSeparator' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
47 | 'inheritLocale' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
48 | 'lcMessages' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
49 | 'legacyEncoding' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
50 | 'monetaryThousandSeparator' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
51 | 'monetaryDecimalPoint' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
52 | 'moneyformat' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
53 | 'moneyvalueformat' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
54 | 'provinceLimit' => CRM_Core_BAO_Setting::LOCALIZATION_PREFERENCES_NAME, | |
55 | ); | |
6a488035 TO |
56 | |
57 | /** | |
eceb18cc | 58 | * Build the form object. |
6a488035 TO |
59 | */ |
60 | public function buildQuickForm() { | |
61 | $config = CRM_Core_Config::singleton(); | |
62 | ||
6a488035 TO |
63 | CRM_Utils_System::setTitle(ts('Settings - Localization')); |
64 | ||
fe25a292 | 65 | $warningTitle = json_encode(ts("Warning")); |
b72b5fc0 | 66 | $defaultLocaleOptions = CRM_Admin_Form_Setting_Localization::getDefaultLocaleOptions(); |
8a61528e | 67 | |
6a488035 TO |
68 | $domain = new CRM_Core_DAO_Domain(); |
69 | $domain->find(TRUE); | |
6a488035 | 70 | |
8a61528e | 71 | if ($domain->locales) { |
6a488035 | 72 | // add language limiter and language adder |
b72b5fc0 TO |
73 | $this->addCheckBox('languageLimit', ts('Available Languages'), array_flip($defaultLocaleOptions), NULL, NULL, NULL, NULL, ' '); |
74 | $this->addElement('select', 'addLanguage', ts('Add Language'), array_merge(array('' => ts('- select -')), array_diff(CRM_Core_I18n::languages(), $defaultLocaleOptions))); | |
6a488035 TO |
75 | |
76 | // add the ability to return to single language | |
fe25a292 | 77 | $warning = ts('This will make your CiviCRM installation a single-language one again. THIS WILL DELETE ALL DATA RELATED TO LANGUAGES OTHER THAN THE DEFAULT ONE SELECTED ABOVE (and only that language will be preserved).'); |
6a488035 | 78 | $this->assign('warning', $warning); |
fe25a292 | 79 | $warning = json_encode($warning); |
6a488035 | 80 | $this->addElement('checkbox', 'makeSinglelingual', ts('Return to Single Language'), |
fe25a292 | 81 | NULL, array('onChange' => "if (this.checked) CRM.alert($warning, $warningTitle)") |
6a488035 TO |
82 | ); |
83 | } | |
84 | else { | |
fe25a292 | 85 | $warning = ts('Enabling multiple languages changes the schema of your database, so make sure you know what you are doing when enabling this function; making a database backup is strongly recommended.'); |
6a488035 | 86 | $this->assign('warning', $warning); |
fe25a292 | 87 | $warning = json_encode($warning); |
6a488035 TO |
88 | $validTriggerPermission = CRM_Core_DAO::checkTriggerViewPermission(TRUE); |
89 | ||
90 | if ($validTriggerPermission && | |
91 | !$config->logging | |
92 | ) { | |
93 | $this->addElement('checkbox', 'makeMultilingual', ts('Enable Multiple Languages'), | |
fe25a292 | 94 | NULL, array('onChange' => "if (this.checked) CRM.alert($warning, $warningTitle)") |
6a488035 TO |
95 | ); |
96 | } | |
97 | } | |
9c325795 TO |
98 | $this->addElement('select', 'contact_default_language', ts('Default Language for users'), |
99 | CRM_Admin_Form_Setting_Localization::getDefaultLanguageOptions()); | |
6a488035 TO |
100 | |
101 | $includeCurrency = &$this->addElement('advmultiselect', 'currencyLimit', | |
8a61528e | 102 | ts('Available Currencies') . ' ', self::getCurrencySymbols(), |
6a488035 TO |
103 | array( |
104 | 'size' => 5, | |
105 | 'style' => 'width:150px', | |
106 | 'class' => 'advmultiselect', | |
107 | ) | |
108 | ); | |
109 | ||
110 | $includeCurrency->setButtonAttributes('add', array('value' => ts('Add >>'))); | |
111 | $includeCurrency->setButtonAttributes('remove', array('value' => ts('<< Remove'))); | |
112 | ||
6a488035 TO |
113 | $this->addFormRule(array('CRM_Admin_Form_Setting_Localization', 'formRule')); |
114 | ||
115 | parent::buildQuickForm(); | |
116 | } | |
117 | ||
e0ef6999 EM |
118 | /** |
119 | * @param $fields | |
120 | * | |
121 | * @return array|bool | |
122 | */ | |
00be9182 | 123 | public static function formRule($fields) { |
6a488035 TO |
124 | $errors = array(); |
125 | if (CRM_Utils_Array::value('monetaryThousandSeparator', $fields) == | |
126 | CRM_Utils_Array::value('monetaryDecimalPoint', $fields) | |
127 | ) { | |
128 | $errors['monetaryThousandSeparator'] = ts('Thousands Separator and Decimal Delimiter can not be the same.'); | |
129 | } | |
130 | ||
131 | if (strlen($fields['monetaryThousandSeparator']) == 0) { | |
132 | $errors['monetaryThousandSeparator'] = ts('Thousands Separator can not be empty. You can use a space character instead.'); | |
133 | } | |
134 | ||
135 | if (strlen($fields['monetaryThousandSeparator']) > 1) { | |
136 | $errors['monetaryThousandSeparator'] = ts('Thousands Separator can not have more than 1 character.'); | |
137 | } | |
138 | ||
139 | if (strlen($fields['monetaryDecimalPoint']) > 1) { | |
140 | $errors['monetaryDecimalPoint'] = ts('Decimal Delimiter can not have more than 1 character.'); | |
141 | } | |
142 | ||
143 | if (trim($fields['customTranslateFunction']) && | |
144 | !function_exists(trim($fields['customTranslateFunction'])) | |
145 | ) { | |
146 | $errors['customTranslateFunction'] = ts('Please define the custom translation function first.'); | |
147 | } | |
148 | ||
149 | // CRM-7962, CRM-7713, CRM-9004 | |
150 | if (!empty($fields['defaultContactCountry']) && | |
8cc574cf | 151 | (!empty($fields['countryLimit']) && |
6a488035 TO |
152 | (!in_array($fields['defaultContactCountry'], $fields['countryLimit'])) |
153 | ) | |
154 | ) { | |
155 | $errors['defaultContactCountry'] = ts('Please select a default country that is in the list of available countries.'); | |
b05e28de | 156 | } |
6a488035 TO |
157 | |
158 | return empty($errors) ? TRUE : $errors; | |
159 | } | |
160 | ||
00be9182 | 161 | public function setDefaultValues() { |
6a488035 TO |
162 | parent::setDefaultValues(); |
163 | ||
164 | // CRM-1496 | |
165 | // retrieve default values for currencyLimit | |
166 | $this->_defaults['currencyLimit'] = array_keys(CRM_Core_OptionGroup::values('currencies_enabled')); | |
167 | ||
b72b5fc0 TO |
168 | $this->_defaults['languageLimit'] = Civi::settings()->get('languageLimit'); |
169 | ||
6a488035 TO |
170 | // CRM-5111: unset these two unconditionally, we don’t want them to stick – ever |
171 | unset($this->_defaults['makeMultilingual']); | |
172 | unset($this->_defaults['makeSinglelingual']); | |
173 | return $this->_defaults; | |
174 | } | |
175 | ||
176 | public function postProcess() { | |
177 | $values = $this->exportValues(); | |
178 | ||
6a488035 TO |
179 | //cache contact fields retaining localized titles |
180 | //though we changed localization, so reseting cache. | |
181 | CRM_Core_BAO_Cache::deleteGroup('contact fields'); | |
182 | ||
183 | //CRM-8559, cache navigation do not respect locale if it is changed, so reseting cache. | |
184 | CRM_Core_BAO_Cache::deleteGroup('navigation'); | |
185 | ||
186 | // we do this only to initialize monetary decimal point and thousand separator | |
187 | $config = CRM_Core_Config::singleton(); | |
188 | ||
6a488035 TO |
189 | // save enabled currencies and defaul currency in option group 'currencies_enabled' |
190 | // CRM-1496 | |
191 | if (empty($values['currencyLimit'])) { | |
192 | $values['currencyLimit'] = array($values['defaultCurrency']); | |
193 | } | |
194 | elseif (!in_array($values['defaultCurrency'], | |
353ffa53 TO |
195 | $values['currencyLimit'] |
196 | ) | |
197 | ) { | |
6a488035 TO |
198 | $values['currencyLimit'][] = $values['defaultCurrency']; |
199 | } | |
200 | ||
201 | // sort so that when we display drop down, weights have right value | |
202 | sort($values['currencyLimit']); | |
203 | ||
204 | // get labels for all the currencies | |
205 | $options = array(); | |
206 | ||
8a61528e | 207 | $currencySymbols = self::getCurrencySymbols(); |
6a488035 TO |
208 | for ($i = 0; $i < count($values['currencyLimit']); $i++) { |
209 | $options[] = array( | |
8a61528e | 210 | 'label' => $currencySymbols[$values['currencyLimit'][$i]], |
6a488035 TO |
211 | 'value' => $values['currencyLimit'][$i], |
212 | 'weight' => $i + 1, | |
213 | 'is_active' => 1, | |
214 | 'is_default' => $values['currencyLimit'][$i] == $values['defaultCurrency'], | |
215 | ); | |
216 | } | |
217 | ||
218 | $dontCare = NULL; | |
219 | CRM_Core_OptionGroup::createAssoc('currencies_enabled', | |
220 | $options, | |
221 | $dontCare | |
222 | ); | |
223 | ||
224 | // unset currencyLimit so we dont store there | |
225 | unset($values['currencyLimit']); | |
226 | ||
227 | // make the site multi-lang if requested | |
a7488080 | 228 | if (!empty($values['makeMultilingual'])) { |
6a488035 TO |
229 | CRM_Core_I18n_Schema::makeMultilingual($values['lcMessages']); |
230 | $values['languageLimit'][$values['lcMessages']] = 1; | |
231 | // make the site single-lang if requested | |
232 | } | |
a7488080 | 233 | elseif (!empty($values['makeSinglelingual'])) { |
6a488035 TO |
234 | CRM_Core_I18n_Schema::makeSinglelingual($values['lcMessages']); |
235 | $values['languageLimit'] = ''; | |
236 | } | |
237 | ||
238 | // add a new db locale if the requested language is not yet supported by the db | |
239 | if (!CRM_Utils_Array::value('makeSinglelingual', $values) and CRM_Utils_Array::value('addLanguage', $values)) { | |
240 | $domain = new CRM_Core_DAO_Domain(); | |
241 | $domain->find(TRUE); | |
242 | if (!substr_count($domain->locales, $values['addLanguage'])) { | |
243 | CRM_Core_I18n_Schema::addLocale($values['addLanguage'], $values['lcMessages']); | |
244 | } | |
245 | $values['languageLimit'][$values['addLanguage']] = 1; | |
246 | } | |
247 | ||
248 | // if we manipulated the language list, return to the localization admin screen | |
02fc859b | 249 | $return = (bool) (CRM_Utils_Array::value('makeMultilingual', $values) or CRM_Utils_Array::value('addLanguage', $values)); |
6a488035 | 250 | |
b72b5fc0 TO |
251 | $filteredValues = $values; |
252 | unset($filteredValues['makeMultilingual']); | |
253 | unset($filteredValues['makeSinglelingual']); | |
254 | unset($filteredValues['addLanguage']); | |
255 | unset($filteredValues['languageLimit']); | |
256 | ||
257 | Civi::settings()->set('languageLimit', CRM_Utils_Array::value('languageLimit', $values)); | |
258 | ||
6a488035 | 259 | // save all the settings |
b72b5fc0 | 260 | parent::commonProcess($filteredValues); |
6a488035 TO |
261 | |
262 | if ($return) { | |
263 | CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/setting/localization', 'reset=1')); | |
264 | } | |
265 | } | |
96025800 | 266 | |
8a61528e TO |
267 | /** |
268 | * @return array | |
269 | */ | |
270 | public static function getAvailableCountries() { | |
271 | $i18n = CRM_Core_I18n::singleton(); | |
272 | $country = array(); | |
273 | CRM_Core_PseudoConstant::populate($country, 'CRM_Core_DAO_Country', TRUE, 'name', 'is_active'); | |
274 | $i18n->localizeArray($country, array('context' => 'country')); | |
275 | asort($country); | |
276 | return $country; | |
277 | } | |
278 | ||
279 | /** | |
280 | * @return array | |
281 | */ | |
282 | public static function getDefaultLocaleOptions() { | |
283 | $domain = new CRM_Core_DAO_Domain(); | |
284 | $domain->find(TRUE); | |
285 | $locales = CRM_Core_I18n::languages(); | |
286 | if ($domain->locales) { | |
287 | // for multi-lingual sites, populate default language drop-down with available languages | |
b72b5fc0 | 288 | $defaultLocaleOptions = array(); |
8a61528e TO |
289 | foreach ($locales as $loc => $lang) { |
290 | if (substr_count($domain->locales, $loc)) { | |
b72b5fc0 | 291 | $defaultLocaleOptions[$loc] = $lang; |
8a61528e TO |
292 | } |
293 | } | |
294 | } | |
295 | else { | |
b72b5fc0 | 296 | $defaultLocaleOptions = $locales; |
8a61528e | 297 | } |
b72b5fc0 | 298 | return $defaultLocaleOptions; |
8a61528e TO |
299 | } |
300 | ||
301 | /** | |
302 | * Get a list of currencies (with their symbols). | |
303 | * | |
304 | * @return array | |
305 | * Array('USD' => 'USD ($)'). | |
306 | */ | |
307 | public static function getCurrencySymbols() { | |
308 | $symbols = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'currency', array( | |
309 | 'labelColumn' => 'symbol', | |
310 | 'orderColumn' => TRUE, | |
311 | )); | |
312 | $_currencySymbols = array(); | |
313 | foreach ($symbols as $key => $value) { | |
314 | $_currencySymbols[$key] = "$key"; | |
315 | if ($value) { | |
316 | $_currencySymbols[$key] .= " ($value)"; | |
317 | } | |
318 | } | |
319 | return $_currencySymbols; | |
320 | } | |
321 | ||
b72b5fc0 TO |
322 | public static function onChangeLcMessages($oldLocale, $newLocale, $metadata, $domainID) { |
323 | if ($oldLocale == $newLocale) { | |
324 | return; | |
325 | } | |
326 | ||
327 | $session = CRM_Core_Session::singleton(); | |
328 | if ($newLocale && $session->get('userID')) { | |
329 | $ufm = new CRM_Core_DAO_UFMatch(); | |
330 | $ufm->contact_id = $session->get('userID'); | |
331 | if ($newLocale && $ufm->find(TRUE)) { | |
332 | $ufm->language = $newLocale; | |
333 | $ufm->save(); | |
334 | $session->set('lcMessages', $newLocale); | |
335 | } | |
336 | } | |
337 | } | |
338 | ||
9c325795 TO |
339 | /** |
340 | * @return array | |
341 | */ | |
342 | public static function getDefaultLanguageOptions() { | |
343 | return array( | |
344 | '*default*' => ts('Use default site language'), | |
345 | 'undefined' => ts('Leave undefined'), | |
346 | 'current_site_language' => ts('Use language in use at the time'), | |
347 | ); | |
348 | } | |
349 | ||
6a488035 | 350 | } |