View source
<?php
namespace Drupal\search_api_solr\Controller;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Controller\ControllerBase;
use Drupal\search_api\ServerInterface;
use Drupal\search_api_solr\SearchApiSolrConflictingEntitiesException;
use Drupal\search_api_solr\SolrBackendInterface;
use Drupal\search_api_solr\Utility\Utility;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
class SolrConfigSetController extends ControllerBase {
use BackendTrait;
public function getSchemaExtraTypesXml(?ServerInterface $search_api_server = NULL) : string {
$list_builder = $this
->getListBuilder('solr_field_type', $search_api_server);
return $list_builder
->getSchemaExtraTypesXml();
}
public function streamSchemaExtraTypesXml(ServerInterface $search_api_server) : Response {
try {
return $this
->streamXml('schema_extra_types.xml', $this
->getSchemaExtraTypesXml($search_api_server));
} catch (SearchApiSolrConflictingEntitiesException $e) {
$this
->messenger()
->addError($this
->t('Some enabled parts of the configuration conflict with others: :conflicts', [
'@conflicts' => new FormattableMarkup($e, []),
]));
}
return new RedirectResponse($search_api_server
->toUrl('canonical')
->toString());
}
public function getSchemaExtraFieldsXml(?ServerInterface $search_api_server = NULL) : string {
$solr_major_version = NULL;
if ($search_api_server) {
$backend = $search_api_server
->getBackend();
$solr_major_version = $backend
->getSolrConnector()
->getSolrMajorVersion();
}
$list_builder = $this
->getListBuilder('solr_field_type', $search_api_server);
return $list_builder
->getSchemaExtraFieldsXml($solr_major_version);
}
public function streamSchemaExtraFieldsXml(ServerInterface $search_api_server) : Response {
try {
return $this
->streamXml('schema_extra_fields.xml', $this
->getSchemaExtraFieldsXml($search_api_server));
} catch (SearchApiSolrConflictingEntitiesException $e) {
$this
->messenger()
->addError($this
->t('Some enabled parts of the configuration conflict with others: @conflicts', [
'@conflicts' => new FormattableMarkup($e, []),
]));
}
return new RedirectResponse($search_api_server
->toUrl('canonical')
->toString());
}
public function getSolrconfigExtraXml(?ServerInterface $search_api_server = NULL) : string {
$solr_field_type_list_builder = $this
->getListBuilder('solr_field_type', $search_api_server);
$solr_request_handler_list_builder = $this
->getListBuilder('solr_request_handler', $search_api_server);
return $solr_field_type_list_builder
->getSolrconfigExtraXml() . $solr_request_handler_list_builder
->getXml();
}
public function streamSolrconfigExtraXml(ServerInterface $search_api_server) : Response {
try {
return $this
->streamXml('solrconfig_extra.xml', $this
->getSolrconfigExtraXml($search_api_server));
} catch (SearchApiSolrConflictingEntitiesException $e) {
$this
->messenger()
->addError($this
->t('Some enabled parts of the configuration conflict with others: @conflicts', [
'@conflicts' => new FormattableMarkup($e, []),
]));
}
return new RedirectResponse($search_api_server
->toUrl('canonical')
->toString());
}
public function getSolrconfigQueryXml(?ServerInterface $search_api_server = NULL) : string {
$list_builder = $this
->getListBuilder('solr_cache', $search_api_server);
return $list_builder
->getXml();
}
public function streamSolrconfigQueryXml(ServerInterface $search_api_server) : Response {
try {
return $this
->streamXml('solrconfig_query.xml', $this
->getSolrconfigQueryXml($search_api_server));
} catch (SearchApiSolrConflictingEntitiesException $e) {
$this
->messenger()
->addError($this
->t('Some enabled parts of the configuration conflict with others: @conflicts', [
'@conflicts' => new FormattableMarkup($e, []),
]));
}
return new RedirectResponse($search_api_server
->toUrl('canonical')
->toString());
}
public function getSolrconfigRequestDispatcherXml(?ServerInterface $search_api_server = NULL) : string {
$list_builder = $this
->getListBuilder('solr_request_dispatcher', $search_api_server);
return $list_builder
->getXml();
}
public function streamSolrconfigRequestDispatcherXml(ServerInterface $search_api_server) : Response {
try {
return $this
->streamXml('solrconfig_requestdispatcher.xml', $this
->getSolrconfigRequestDispatcherXml($search_api_server));
} catch (SearchApiSolrConflictingEntitiesException $e) {
$this
->messenger()
->addError($this
->t('Some enabled parts of the configuration conflict with others: @conflicts', [
'@conflicts' => new FormattableMarkup($e, []),
]));
}
return new RedirectResponse($search_api_server
->toUrl('canonical')
->toString());
}
public function getConfigFiles() : array {
$backend = $this
->getBackend();
$connector = $backend
->getSolrConnector();
$solr_branch = $real_solr_branch = $connector
->getSolrBranch($this->assumedMinimumVersion);
$solr_major_version = $connector
->getSolrMajorVersion($this->assumedMinimumVersion);
$template_path = drupal_get_path('module', 'search_api_solr') . '/solr-conf-templates/';
$solr_configset_template_mapping = [
'6.x' => $template_path . '6.x',
'7.x' => $template_path . '7.x',
'8.x' => $template_path . '7.x',
];
$this
->moduleHandler()
->alter('search_api_solr_configset_template_mapping', $solr_configset_template_mapping);
$search_api_solr_conf_path = $solr_configset_template_mapping[$solr_branch];
$solrcore_properties = parse_ini_file($search_api_solr_conf_path . '/solrcore.properties', FALSE, INI_SCANNER_RAW);
$files = [
'schema_extra_types.xml' => $this
->getSchemaExtraTypesXml(),
'schema_extra_fields.xml' => $this
->getSchemaExtraFieldsXml($backend
->getServer()),
'solrconfig_extra.xml' => $this
->getSolrconfigExtraXml(),
];
if (version_compare($solr_major_version, '7', '>=')) {
$files['solrconfig_query.xml'] = $this
->getSolrconfigQueryXml();
$files['solrconfig_requestdispatcher.xml'] = $this
->getSolrconfigRequestDispatcherXml();
}
$list_builder = $this
->getListBuilder('solr_field_type');
$solr_field_types = $list_builder
->getEnabledEntities();
foreach ($solr_field_types as $solr_field_type) {
$text_files = $solr_field_type
->getTextFiles();
foreach ($text_files as $text_file_name => $text_file) {
$text_file_name = Utility::completeTextFileName($text_file_name, $solr_field_type);
$files[$text_file_name] = $text_file;
$solrcore_properties['solr.replication.confFiles'] .= ',' . $text_file_name;
}
}
$solrcore_properties['solr.luceneMatchVersion'] = $connector
->getLuceneMatchVersion($this->assumedMinimumVersion ?: '');
$solrcore_properties_string = '';
foreach ($solrcore_properties as $property => $value) {
$solrcore_properties_string .= $property . '=' . $value . "\n";
}
$files['solrcore.properties'] = $solrcore_properties_string;
foreach (scandir($search_api_solr_conf_path) as $file) {
if (strpos($file, '.') !== 0) {
foreach (array_keys($files) as $existing_file) {
if ($file == $existing_file) {
continue 2;
}
}
$files[$file] = str_replace([
'SEARCH_API_SOLR_MIN_SCHEMA_VERSION',
'SEARCH_API_SOLR_BRANCH',
], [
SolrBackendInterface::SEARCH_API_SOLR_MIN_SCHEMA_VERSION,
$real_solr_branch,
], file_get_contents($search_api_solr_conf_path . '/' . $file));
}
}
$connector
->alterConfigFiles($files, $solrcore_properties['solr.luceneMatchVersion'], $this->serverId);
$this
->moduleHandler()
->alter('search_api_solr_config_files', $files, $solrcore_properties['solr.luceneMatchVersion'], $this->serverId);
return $files;
}
public function getConfigZip(Archive $archive_options) : ZipStream {
$backend = $this
->getBackend();
$connector = $backend
->getSolrConnector();
$solr_branch = $connector
->getSolrBranch($this->assumedMinimumVersion);
$zip = new ZipStream('solr_' . $solr_branch . '_config.zip', $archive_options);
$files = $this
->getConfigFiles();
foreach ($files as $name => $content) {
$zip
->addFile($name, $content);
}
return $zip;
}
public function streamConfigZip(ServerInterface $search_api_server) : Response {
$this
->setServer($search_api_server);
try {
$archive_options = new Archive();
$archive_options
->setSendHttpHeaders(TRUE);
@ob_clean();
header('X-Accel-Buffering: no');
$zip = $this
->getConfigZip($archive_options);
$zip
->finish();
@ob_end_flush();
exit;
} catch (SearchApiSolrConflictingEntitiesException $e) {
$this
->messenger()
->addError($this
->t('Some enabled parts of the configuration conflict with others: @conflicts', [
'@conflicts' => new FormattableMarkup($e, []),
]));
} catch (\Exception $e) {
watchdog_exception('search_api', $e);
$this
->messenger()
->addError($this
->t('An error occured during the creation of the config.zip. Look at the logs for details.'));
}
return new RedirectResponse($search_api_server
->toUrl('canonical')
->toString());
}
protected function streamXml(string $file_name, string $xml) : Response {
return new Response($xml, 200, [
'Content-Type' => 'application/xml',
'Content-Disposition' => 'attachment; filename=' . $file_name,
]);
}
protected function getListBuilder(string $entity_type_id, ?ServerInterface $search_api_server = NULL) : AbstractSolrEntityListBuilder {
$list_builder = $this
->entityTypeManager()
->getListBuilder($entity_type_id);
if ($search_api_server) {
$list_builder
->setServer($search_api_server);
}
else {
$list_builder
->setBackend($this
->getBackend());
}
return $list_builder;
}
}