diff --git a/apps/qubit/modules/settings/actions/diacriticsAction.class.php b/apps/qubit/modules/settings/actions/diacriticsAction.class.php new file mode 100644 index 0000000000..d47529abe8 --- /dev/null +++ b/apps/qubit/modules/settings/actions/diacriticsAction.class.php @@ -0,0 +1,84 @@ +. + */ + +class SettingsDiacriticsAction extends SettingsEditAction +{ + // Arrays not allowed in class constants + public static $NAMES = [ + 'diacritics', + ]; + + public function earlyExecute() + { + parent::earlyExecute(); + + $this->updateMessage = $this->i18n->__('Diacritics settings saved.'); + + $this->settingDefaults = [ + 'diacritics' => 0, + ]; + } + + public function execute($request) + { + parent::execute($request); + } + + public function uploadDiacritics($request) + { + $file = $request->getFiles('mappings'); + $diacriticsMappingPath = sfConfig::get('sf_plugins_dir').DIRECTORY_SEPARATOR.'arElasticSearchPlugin'.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'diacritics_mapping.yml'; + + if (1 === (int) $request->getPostParameters()['diacritics']) { + if ('application/x-yaml' === $request->getFiles()['mappings']['type']) { + // Move uploaded file to replace diacritics_mapping.yml. + try { + $file = Qubit::moveUploadFile($file); + } catch (sfException $e) { + $this->getUser()->setFlash('error', $e->getMessage()); + } + + // Replace /config/diacritics_mapping.yml with uploaded file + $uploadMappingPath = $file['tmp_name']; + $diacriticsMappings = file_get_contents($uploadMappingPath); + file_put_contents($diacriticsMappingPath, $diacriticsMappings); + $this->getUser()->setFlash('notice', $this->context->i18n->__('Diacritics setting updated. Rebuild the search index for the changes to be applied.')); + } else { + QubitSetting::findAndSave('diacritics', 0, ['sourceCulture' => true]); + $this->getUser()->setFlash('error', $this->context->i18n->__('Error: Unable to upload diacritics mapping. Must be a YAML file.')); + } + } else { + // Reset diacritics yaml when disabling the setting + unlink($diacriticsMappingPath); + } + } + + protected function addField($name) + { + switch ($name) { + case 'diacritics': + $this->form->setDefault($name, $this->settingDefaults[$name]); + $this->form->setWidget($name, new sfWidgetFormSelectRadio(['choices' => [0 => $this->i18n->__('Disabled'), 1 => $this->i18n->__('Enabled')]], ['class' => 'radio'])); + $this->form->setValidator($name, new sfValidatorChoice(['choices' => [1, 0]])); + $this->form->setWidget('mappings', new sfWidgetFormInputFile()); + $this->form->setValidator('mappings', new sfValidatorFile()); + + break; + } + } +} diff --git a/apps/qubit/modules/settings/actions/editAction.class.php b/apps/qubit/modules/settings/actions/editAction.class.php index e868af28d7..acb91d0030 100644 --- a/apps/qubit/modules/settings/actions/editAction.class.php +++ b/apps/qubit/modules/settings/actions/editAction.class.php @@ -28,7 +28,7 @@ public function execute($request) // Handle posted data if ($request->isMethod('post')) { - $this->form->bind($request->getPostParameters()); + $this->form->bind($request->getPostParameters(), $request->getFiles()); if ($this->form->isValid()) { $this->processForm(); @@ -39,6 +39,10 @@ public function execute($request) $this->getUser()->setFlash('notice', $this->updateMessage); } + if (null !== $request->getFiles() && 'SettingsDiacriticsAction' === get_called_class()) { + $this->uploadDiacritics($request); + } + $this->redirect([ 'module' => $this->getContext()->getModuleName(), 'action' => $this->getContext()->getActionName(), diff --git a/apps/qubit/modules/settings/actions/menuComponent.class.php b/apps/qubit/modules/settings/actions/menuComponent.class.php index 2948c80290..621f2ae063 100644 --- a/apps/qubit/modules/settings/actions/menuComponent.class.php +++ b/apps/qubit/modules/settings/actions/menuComponent.class.php @@ -39,6 +39,10 @@ public function execute($request) 'label' => $i18n->__('Default template'), 'action' => 'template', ], + [ + 'label' => $i18n->__('Diacritics'), + 'action' => 'diacritics', + ], [ 'label' => $i18n->__('Digital object derivatives'), 'action' => 'digitalObjectDerivatives', diff --git a/apps/qubit/modules/settings/templates/diacriticsSuccess.php b/apps/qubit/modules/settings/templates/diacriticsSuccess.php new file mode 100644 index 0000000000..47075e3a6b --- /dev/null +++ b/apps/qubit/modules/settings/templates/diacriticsSuccess.php @@ -0,0 +1,57 @@ + + + + + + + + + +

+ + + + +
+

+
$ php symfony search:populate
+
+ + renderGlobalErrors(); ?> + + renderFormTag(url_for(['module' => 'settings', 'action' => 'diacritics']), ['method' => 'post']); ?> + + renderHiddenFields(); ?> + +
+ + + + + + + + + + + + + + + + + + +
diacritics; ?>
+
+ mappings; ?>
+
+
+ +
+ +
+ + + + diff --git a/plugins/arDominionB5Plugin/modules/settings/templates/diacriticsSuccess.php b/plugins/arDominionB5Plugin/modules/settings/templates/diacriticsSuccess.php new file mode 100644 index 0000000000..9185b46e00 --- /dev/null +++ b/plugins/arDominionB5Plugin/modules/settings/templates/diacriticsSuccess.php @@ -0,0 +1,57 @@ + + + + + + + + + +

+ + + + +
+

+
$ php symfony search:populate
+
+ + renderGlobalErrors(); ?> + + renderFormTag(url_for(['module' => 'settings', 'action' => 'diacritics']), ['method' => 'post']); ?> + + renderHiddenFields(); ?> + +
+ + + + + + + + + + + + + + + + + + +
diacritics; ?>
+
+ mappings; ?>
+
+
+ +
+ +
+ + + + diff --git a/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php b/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php index 39862e184d..d28c997178 100644 --- a/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php +++ b/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php @@ -135,6 +135,22 @@ public static function loadMappings() return $esMapping; } + public function loadDiacriticsMappings() + { + // Find diacritics_mapping.yml + $diacriticsFinder = sfFinder::type('file')->name('diacritics_mapping.yml'); + $diacriticsFiles = array_unique(array_merge( + $diacriticsFinder->in(sfConfig::get('sf_config_dir')), + $diacriticsFinder->in(ProjectConfiguration::getActive()->getPluginSubPaths('/config')) + )); + + if (!count($diacriticsFiles)) { + throw new sfException('You must create a diacritics_mapping.yml file.'); + } + + return sfYaml::load(array_shift($diacriticsFiles)); + } + /** * Optimize index. * @@ -468,6 +484,12 @@ public static function modelClassFromQubitObjectClass($className) */ protected function initialize() { + if (sfConfig::get('app_diacritics')) { + $this->config['index']['configuration']['analysis']['char_filter']['diacritics_lowercase'] = $this->loadDiacriticsMappings(); + } + + $this->loadMappings(); + try { $this->index->open(); } catch (Exception $e) { @@ -479,7 +501,17 @@ protected function initialize() && isset($this->config['index']['configuration']['analysis']['char_filter']['strip_md']) ) { foreach ($this->config['index']['configuration']['analysis']['analyzer'] as $key => $analyzer) { - $this->config['index']['configuration']['analysis']['analyzer'][$key]['char_filter'] = ['strip_md']; + $filters = ['strip_md']; + + if ($this->config['index']['configuration']['analysis']['analyzer'][$key]['char_filter']) { + $filters = array_merge($filters, $this->config['index']['configuration']['analysis']['analyzer'][$key]['char_filter']); + } + + if (sfConfig::get('app_diacritics')) { + $filters = array_merge($filters, ['diacritics_lowercase']); + } + + $this->config['index']['configuration']['analysis']['analyzer'][$key]['char_filter'] = $filters; } }