View source
<?php
namespace Drupal\search_api_attachments\Form;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Component\Utility\Html;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
use Drupal\search_api_attachments\TextExtractorPluginManager;
class TextExtractorFormSettings extends ConfigFormBase {
const CONFIGNAME = 'search_api_attachments.admin_config';
private $textExtractorPluginManager;
protected $entityTypeManager;
public function __construct(ConfigFactoryInterface $config_factory, TextExtractorPluginManager $text_extractor_plugin_manager, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($config_factory);
$this->textExtractorPluginManager = $text_extractor_plugin_manager;
$this->entityTypeManager = $entity_type_manager;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('config.factory'), $container
->get('plugin.manager.search_api_attachments.text_extractor'), $container
->get('entity_type.manager'));
}
protected function getEditableConfigNames() {
return [
static::CONFIGNAME,
];
}
public function getFormId() {
return 'search_api_attachments_admin_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$config = $this
->config(static::CONFIGNAME);
$form['extraction_method'] = [
'#type' => 'select',
'#title' => $this
->t('Extraction method'),
'#description' => $this
->t('Select the extraction method you want to use.'),
'#empty_value' => '',
'#options' => $this
->getExtractionPluginInformations()['labels'],
'#default_value' => $config
->get('extraction_method'),
'#required' => TRUE,
'#ajax' => [
'callback' => [
get_class($this),
'buildAjaxTextExtractorConfigForm',
],
'wrapper' => 'search-api-attachments-extractor-config-form',
'method' => 'replace',
'effect' => 'fade',
],
];
$this
->buildTextExtractorConfigForm($form, $form_state);
$trigger = $form_state
->getTriggeringElement();
if (!empty($trigger['#is_button'])) {
$this
->buildTextExtractorTestResultForm($form, $form_state);
}
$url = Url::fromRoute('system.performance_settings')
->toString();
$form['preserve_cache'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Preserve cached extractions across cache clears.'),
'#default_value' => $config
->get('preserve_cache'),
'#description' => $this
->t('When checked, <a href=":url">clearing the sitewide cache</a> will not clear the cache of extracted files.', [
':url' => $url,
]),
];
$form['read_text_files_directly'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Get contents of text attachments directly using file_get_contents.'),
'#default_value' => $config
->get('read_text_files_directly'),
'#description' => $this
->t('When checked, get contents of text files directly using file_get_contents, rather than sending the whole file to Solr. This may cause problems when reading non-UTF-8 text files.'),
];
$form['actions']['submit']['#value'] = $this
->t('Submit and test extraction');
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
$config = $this
->config(static::CONFIGNAME);
$extractor_plugin_id = $form_state
->getValue('extraction_method');
if ($extractor_plugin_id) {
$configuration = $config
->get($extractor_plugin_id . '_configuration');
$extractor_plugin = $this
->getTextExtractorPluginManager()
->createInstance($extractor_plugin_id, $configuration);
if (!empty($form['text_extractor_config']['extraction_method']['#value']) && $form['text_extractor_config']['extraction_method']['#value'] == $extractor_plugin_id) {
$extractor_plugin
->validateConfigurationForm($form, $form_state);
}
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this
->config(static::CONFIGNAME);
$extractor_plugin_id = $form_state
->getValue('extraction_method');
if ($extractor_plugin_id) {
$configuration = $config
->get($extractor_plugin_id . '_configuration');
$extractor_plugin = $this
->getTextExtractorPluginManager()
->createInstance($extractor_plugin_id, $configuration);
$extractor_plugin
->submitConfigurationForm($form, $form_state);
}
$config = $this
->configFactory()
->getEditable(static::CONFIGNAME);
$config
->set('extraction_method', $extractor_plugin_id);
$config
->set('read_text_files_directly', $form_state
->getValue('read_text_files_directly'));
$config
->set('preserve_cache', $form_state
->getValue('preserve_cache'));
$config
->save();
$file = $this
->getTestFile();
$error = '';
$extracted_data = NULL;
try {
$extracted_data = $extractor_plugin
->extract($file);
} catch (\Exception $e) {
$error = $e
->getMessage();
}
$file
->delete();
if (empty($extracted_data)) {
if (empty($error)) {
$error = $this
->t('No error message was catched');
}
$data = [
'message' => $this
->t("Unfortunately, the extraction doesn't seem to work with this configuration! (@error)", [
'@error' => $error,
]),
'type' => 'error',
];
}
else {
$data = [
'message' => $this
->t('Extracted data: %extracted_data', [
'%extracted_data' => $extracted_data,
]),
'type' => 'ok',
];
}
$storage = [
'extracted_test_text' => $data,
];
$form_state
->setStorage($storage);
$form_state
->setRebuild();
}
public function getExtractionPluginInformations() {
$options = [
'labels' => [],
'descriptions' => [],
];
foreach ($this
->getTextExtractorPluginManager()
->getDefinitions() as $plugin_id => $plugin_definition) {
$options['labels'][$plugin_id] = Html::escape($plugin_definition['label']);
$options['descriptions'][$plugin_id] = Html::escape($plugin_definition['description']);
}
return $options;
}
public function buildTextExtractorConfigForm(array &$form, FormStateInterface $form_state) {
$form['text_extractor_config'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'search-api-attachments-extractor-config-form',
],
'#tree' => TRUE,
];
$config = $this
->config(static::CONFIGNAME);
if ($form_state
->getValue('extraction_method') != '') {
$extractor_plugin_id = $form_state
->getValue('extraction_method');
}
else {
$extractor_plugin_id = $config
->get('extraction_method');
$ajax_submitted_empty_value = $form_state
->getValue('form_id');
}
$form['text_extractor_config']['#type'] = 'details';
$form['text_extractor_config']['#open'] = TRUE;
if (isset($ajax_submitted_empty_value) || $extractor_plugin_id == '') {
$form['text_extractor_config']['#title'] = $this
->t('Please make a choice');
$form['text_extractor_config']['#description'] = $this
->t('Please choose an extraction method in the list above.');
}
else {
$configuration = $config
->get($extractor_plugin_id . '_configuration');
$extractor_plugin = $this
->getTextExtractorPluginManager()
->createInstance($extractor_plugin_id, $configuration);
$form['text_extractor_config']['#title'] = $this
->t('@extractor_plugin_label configuration', [
'@extractor_plugin_label' => $this
->getExtractionPluginInformations()['labels'][$extractor_plugin_id],
]);
$text_extractor_form = $extractor_plugin
->buildConfigurationForm([], $form_state);
$form['text_extractor_config']['extraction_method'] = [
'#type' => 'value',
'#value' => $extractor_plugin_id,
];
$form['text_extractor_config'] += $text_extractor_form;
}
}
public function buildTextExtractorTestResultForm(array &$form, FormStateInterface $form_state) {
if (isset($form['text_extractor_config'])) {
$extractor_plugin_id = $form_state
->getValue('extraction_method');
$form['text_extractor_config']['test_result']['#type'] = 'details';
$form['text_extractor_config']['test_result']['#title'] = $this
->t('Test extractor %plugin', [
'%plugin' => $this
->getExtractionPluginInformations()['labels'][$extractor_plugin_id],
]);
$form['text_extractor_config']['test_result']['#open'] = TRUE;
$storage = $form_state
->getStorage();
if (empty($storage)) {
$storage = [
'extracted_test_text' => [
'message' => $this
->t("Extraction doesn't seem to work."),
'type' => 'error',
],
];
$form_state
->setStorage($storage);
}
$form['text_extractor_config']['test_result']['test_file_path_result'] = [
'#theme' => 'saa',
'#message' => $storage['extracted_test_text']['message'],
'#type' => $storage['extracted_test_text']['type'],
'#attached' => [
'library' => [
'search_api_attachments/extractor_status',
],
],
];
}
}
public static function buildAjaxTextExtractorConfigForm(array $form, FormStateInterface $form_state) {
return $form['text_extractor_config'];
}
public function getTestFile() {
$filepath = 'public://search_api_attachments_test_extraction.pdf';
$values = [
'uri' => $filepath,
];
$file = $this->entityTypeManager
->getStorage('file')
->loadByProperties($values);
if (empty($file)) {
$source = drupal_get_path('module', 'search_api_attachments');
$source .= '/data/search_api_attachments_test_extraction.pdf';
copy($source, $filepath);
$file = File::create([
'uri' => $filepath,
'uid' => $this
->currentUser()
->id(),
]);
$file
->save();
}
else {
$file = reset($file);
}
return $file;
}
protected function getTextExtractorPluginManager() {
return $this->textExtractorPluginManager ?: \Drupal::service('plugin.manager.search_api_attachments.text_extractor');
}
}