addRoleAssignment( [Role::ROLE_ID_SITE_ADMIN], [ 'fetchGrid', 'fetchRow', 'installLocale', 'saveInstallLocale', 'uninstallLocale', 'disableLocale', 'enableLocale', 'setPrimaryLocale' ] ); } // // Implement template methods from PKPHandler. // /** * @copydoc GridHandler::authorize() */ public function authorize($request, &$args, $roleAssignments) { $rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES); foreach ($roleAssignments as $role => $operations) { $rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations)); } $this->addPolicy($rolePolicy); return parent::authorize($request, $args, $roleAssignments); } /** * @copydoc LanguageGridHandler::initialize() * * @param null|mixed $args */ public function initialize($request, $args = null) { parent::initialize($request, $args); // Grid actions. $router = $request->getRouter(); $this->addAction( new LinkAction( 'installLocale', new AjaxModal( $router->url($request, null, null, 'installLocale', null, null), __('admin.languages.installLocale'), null, true ), __('admin.languages.installLocale'), 'add' ) ); // Columns. // Enable locale. $this->addColumn( new GridColumn( 'enable', 'common.enable', null, 'controllers/grid/common/cell/selectStatusCell.tpl', $this->getCellProvider(), ['width' => 10] ) ); $this->addNameColumn(); // Locale name. $this->addLocaleCodeColumn(); // Locale code. // Primary locale. if ($this->_canManage($request)) { $primaryId = 'contextPrimary'; } else { $primaryId = 'sitePrimary'; } $this->addPrimaryColumn($primaryId); if ($this->_canManage($request)) { $this->addManagementColumns(); } $this->setFootNote('admin.locale.maybeIncomplete'); } // // Implement methods from GridHandler. // /** * @copydoc GridHandler::loadData() */ protected function loadData($request, $filter) { $site = $request->getSite(); /** @var Site $site */ $data = []; $installedLocales = $site->getInstalledLocaleNames(); $supportedLocales = $site->getSupportedLocales(); $primaryLocale = $site->getPrimaryLocale(); foreach ($installedLocales as $localeKey => $localeName) { $data[$localeKey] = []; $data[$localeKey]['code'] = $localeKey; $data[$localeKey]['name'] = $localeName; $data[$localeKey]['incomplete'] = !Locale::getMetadata($localeKey)->isComplete(); $data[$localeKey]['supported'] = in_array($localeKey, $supportedLocales); if ($this->_canManage($request)) { $context = $request->getContext(); $primaryLocale = $context->getPrimaryLocale(); } $data[$localeKey]['primary'] = $localeKey === $primaryLocale; } if ($this->_canManage($request)) { $data = $this->addManagementData($request, $data); } return $data; } // // Public grid actions. // /** * Open a form to select locales for installation. * * @param array $args * @param PKPRequest $request * * @return JSONMessage JSON object */ public function installLocale($args, $request) { // Form handling. $installLanguageForm = new InstallLanguageForm(); $installLanguageForm->initData(); return new JSONMessage(true, $installLanguageForm->fetch($request)); } /** * Save the install language form. * * @param array $args * @param PKPRequest $request * * @return JSONMessage JSON object */ public function saveInstallLocale($args, $request) { $installLanguageForm = new InstallLanguageForm(); $installLanguageForm->readInputData(); if ($installLanguageForm->validate()) { $installLanguageForm->execute(); $this->_updateContextLocaleSettings($request); $notificationManager = new NotificationManager(); $user = $request->getUser(); $notificationManager->createTrivialNotification( $user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('notification.localeInstalled')] ); } return \PKP\db\DAO::getDataChangedEvent(); } /** * Uninstall a locale. * * @param array $args * @param Request $request * * @return JSONMessage JSON object */ public function uninstallLocale($args, $request) { $site = $request->getSite(); $locale = $request->getUserVar('rowId'); $gridData = $this->getGridDataElements($request); if ($request->checkCSRF() && array_key_exists($locale, $gridData)) { $localeData = $gridData[$locale]; if ($localeData['primary']) { return new JSONMessage(false); } $installedLocales = $site->getInstalledLocales(); if (in_array($locale, $installedLocales)) { $installedLocales = array_diff($installedLocales, [$locale]); $site->setInstalledLocales($installedLocales); $supportedLocales = $site->getSupportedLocales(); $supportedLocales = array_diff($supportedLocales, [$locale]); $site->setSupportedLocales($supportedLocales); $siteDao = DAORegistry::getDAO('SiteDAO'); /** @var SiteDAO $siteDao */ $siteDao->updateObject($site); $this->_updateContextLocaleSettings($request); Locale::uninstallLocale($locale); $notificationManager = new NotificationManager(); $user = $request->getUser(); $notificationManager->createTrivialNotification( $user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('notification.localeUninstalled', ['locale' => $localeData['name']])] ); } return \PKP\db\DAO::getDataChangedEvent($locale); } return new JSONMessage(false); } /** * Enable an existing locale. * * @param array $args * @param Request $request * * @return JSONMessage JSON object */ public function enableLocale($args, $request) { $rowId = $request->getUserVar('rowId'); $gridData = $this->getGridDataElements($request); if (array_key_exists($rowId, $gridData)) { $this->_updateLocaleSupportState($request, $rowId, true); $notificationManager = new NotificationManager(); $user = $request->getUser(); $notificationManager->createTrivialNotification( $user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('notification.localeEnabled')] ); } return \PKP\db\DAO::getDataChangedEvent($rowId); } /** * Disable an existing locale. * * @param array $args * @param Request $request * * @return JSONMessage JSON object */ public function disableLocale($args, $request) { $locale = $request->getUserVar('rowId'); $gridData = $this->getGridDataElements($request); $notificationManager = new NotificationManager(); $user = $request->getUser(); if ($request->checkCSRF() && array_key_exists($locale, $gridData)) { // Don't disable primary locales. if ($gridData[$locale]['primary']) { $notificationManager->createTrivialNotification( $user->getId(), PKPNotification::NOTIFICATION_TYPE_ERROR, ['contents' => __('admin.languages.cantDisable')] ); } else { $this->_updateLocaleSupportState($request, $locale, false); $notificationManager->createTrivialNotification( $user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('notification.localeDisabled')] ); } return \PKP\db\DAO::getDataChangedEvent($locale); } return new JSONMessage(false); } /** * Set primary locale. * * @param array $args * @param Request $request * * @return JSONMessage JSON object */ public function setPrimaryLocale($args, $request) { $rowId = $request->getUserVar('rowId'); $gridData = $this->getGridDataElements($request); $localeData = $gridData[$rowId]; $notificationManager = new NotificationManager(); $user = $request->getUser(); $site = $request->getSite(); if (array_key_exists($rowId, $gridData)) { if (Locale::isLocaleValid($rowId)) { $oldSitePrimaryLocale = $site->getPrimaryLocale(); Repo::user()->dao->changeSitePrimaryLocale($oldSitePrimaryLocale, $rowId); $site->setPrimaryLocale($rowId); $siteDao = DAORegistry::getDAO('SiteDAO'); /** @var SiteDAO $siteDao */ $siteDao->updateObject($site); $notificationManager->createTrivialNotification( $user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('notification.primaryLocaleDefined', ['locale' => $localeData['name']])] ); } } // Need to refresh whole grid to remove the check in others // primary locale radio buttons. return \PKP\db\DAO::getDataChangedEvent(); } // // Helper methods. // /** * Update the locale support state (enabled or disabled). * * @param Request $request * @param string $rowId The locale row id. * @param bool $enable Enable locale flag. */ protected function _updateLocaleSupportState($request, $rowId, $enable) { $newSupportedLocales = []; $gridData = $this->getGridDataElements($request); foreach ($gridData as $locale => $data) { if ($data['supported']) { array_push($newSupportedLocales, $locale); } } if (Locale::isLocaleValid($rowId)) { if ($enable) { array_push($newSupportedLocales, $rowId); } else { $key = array_search($rowId, $newSupportedLocales); if ($key !== false) { unset($newSupportedLocales[$key]); } } } $site = $request->getSite(); $site->setSupportedLocales($newSupportedLocales); $siteDao = DAORegistry::getDAO('SiteDAO'); /** @var SiteDAO $siteDao */ $siteDao->updateObject($site); $this->_updateContextLocaleSettings($request); } /** * Helper function to update locale settings in all * installed contexts, based on site locale settings. * * @param object $request */ protected function _updateContextLocaleSettings($request) { $site = $request->getSite(); $siteSupportedLocales = $site->getSupportedLocales(); $contextService = Services::get('context'); $contextDao = Application::getContextDAO(); $contexts = $contextDao->getAll(); while ($context = $contexts->next()) { $params = []; $primaryLocale = $context->getPrimaryLocale(); foreach (['supportedLocales', 'supportedFormLocales', 'supportedSubmissionLocales'] as $settingName) { $localeList = $context->getData($settingName); if (is_array($localeList)) { $params[$settingName] = array_intersect($localeList, $siteSupportedLocales); } } if (!in_array($primaryLocale, $siteSupportedLocales)) { $params['primaryLocale'] = $site->getPrimaryLocale(); $primaryLocale = $params['primaryLocale']; } $errors = $contextService->validate(EntityWriteInterface::VALIDATE_ACTION_EDIT, $params, $params['supportedLocales'], $primaryLocale); // If there are errors, it's too late to do anything about it assert(empty($errors)); $contextService->edit($context, $params, $request); } } /** * This grid can also present management functions * if the conditions above are true. * * @param Request $request * * @return bool */ protected function _canManage($request) { $contextDao = Application::getContextDAO(); $contexts = $contextDao->getAll(); $userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES); [$firstContext, $secondContext] = [$contexts->next(), $contexts->next()]; return ($firstContext && !$secondContext && $request->getContext() && in_array(Role::ROLE_ID_MANAGER, $userRoles)); } }