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..b815b8bace --- /dev/null +++ b/apps/qubit/modules/settings/actions/diacriticsAction.class.php @@ -0,0 +1,106 @@ +. + */ + +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' => QubitSetting::getByName('diacritics')->getValue(['sourceCulture' => true]), + ]; + } + + public function execute($request) + { + DefaultEditAction::execute($request); + + if ($request->isMethod('post')) { + $this->form->bind($request->getPostParameters(), $request->getFiles()); + + if ($this->form->isValid()) { + // Check that a diacritics mapping yaml file is uploaded when enabling + if (0 === intval($request->getPostParameters()['diacritics']) || (1 === intval($request->getPostParameters()['diacritics']) && 0 !== $request->getFiles()['mappings']['size'])) { + $this->processForm($request); + $this->uploadDiacritics($request); + } else { + $this->getUser()->setFlash('error', $this->context->i18n->__('Error: Unable to upload diacritics mapping.')); + } + + $this->redirect(['module' => 'settings', 'action' => 'diacritics']); + } + } + } + + public function processForm($request) + { + sfConfig::set('app_diacritics', $request->getPostParameters()['diacritics']); + QubitSetting::findAndSave('diacritics', $request->getPostParameters()['diacritics'], ['sourceCulture' => true]); + } + + 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/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..9185b46e00 --- /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/data/fixtures/settings.yml b/data/fixtures/settings.yml index 15a39bb244..a31bb37e03 100644 --- a/data/fixtures/settings.yml +++ b/data/fixtures/settings.yml @@ -1351,6 +1351,11 @@ QubitSetting: Qubit_Settings_defaultArchivalDescriptionBrowseView: name: default_archival_description_browse_view value: table + Qubit_Settings_diacritics: + name: diacritics + editable: 1 + deleteable: 0 + value: 0 Qubit_Settings_digitalObjectDerivativesPdfPageNumber: name: digital_object_derivatives_pdf_page_number value: 1 diff --git a/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php b/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php index 39862e184d..15cd3658d6 100644 --- a/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php +++ b/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php @@ -1,5 +1,12 @@ 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 +491,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 +508,12 @@ 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 (sfConfig::get('app_diacritics')) { + $filters = array_merge($filters, ['diacritics_lowercase']); + } + + $this->config['index']['configuration']['analysis']['analyzer'][$key]['char_filter'] = $filters; } }