View source
<?php
namespace Drupal\search_api_solr\Controller;
use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
use Drupal\Core\Entity\EntityInterface;
use Drupal\search_api\ServerInterface;
use Drupal\search_api_solr\SearchApiSolrException;
use Drupal\search_api_solr\SolrBackendInterface;
use Drupal\search_api_solr\SolrMultilingualBackendInterface;
use Drupal\search_api_solr\Utility\Utility;
use ZipStream\ZipStream;
class SolrFieldTypeListBuilder extends ConfigEntityListBuilder {
protected $backend;
protected $serverId = '';
protected $assumed_minimum_version = '';
public function buildHeader() {
$header = [
'label' => $this
->t('Solr Field Type'),
'minimum_solr_version' => $this
->t('Minimum Solr Version'),
'managed_schema' => $this
->t('Managed Schema Required'),
'langcode' => $this
->t('Language'),
'domains' => $this
->t('Domains'),
'id' => $this
->t('Machine name'),
];
return $header + parent::buildHeader();
}
public function buildRow(EntityInterface $solr_field_type) {
$domains = $solr_field_type
->getDomains();
if (empty($domains)) {
$domains = [
'generic',
];
}
$row = [
'label' => $solr_field_type
->label(),
'minimum_solr_version' => $solr_field_type
->getMinimumSolrVersion(),
'managed_schema' => $solr_field_type
->isManagedSchema(),
'langcode' => $solr_field_type
->getFieldTypeLanguageCode(),
'domains' => implode(', ', $domains),
'id' => $solr_field_type
->id(),
];
return $row + parent::buildRow($solr_field_type);
}
public function load() {
static $entities;
if (!$entities) {
$solr_version = '9999.0.0';
$operator = '>=';
$domain = 'generic';
$multilingual = FALSE;
$warning = FALSE;
try {
$backend = $this
->getBackend();
$domain = $backend
->getDomain();
$multilingual = $backend instanceof SolrMultilingualBackendInterface;
$solr_version = $backend
->getSolrConnector()
->getSolrVersion();
if (version_compare($solr_version, '0.0.0', '==')) {
$solr_version = '9999.0.0';
throw new SearchApiSolrException();
}
} catch (SearchApiSolrException $e) {
$operator = '<=';
$warning = TRUE;
}
$this->limit = FALSE;
$entity_ids = $this
->getEntityIds();
$storage = $this
->getStorage();
$entities = $storage
->loadMultipleOverrideFree($entity_ids);
$selection = [];
foreach ($entities as $key => $solr_field_type) {
if ($multilingual || 'und' == $solr_field_type
->getFieldTypeLanguageCode()) {
$version = $solr_field_type
->getMinimumSolrVersion();
$domains = $solr_field_type
->getDomains();
if ($solr_field_type
->isManagedSchema() != $this
->getBackend()
->isManagedSchema() || version_compare($version, $solr_version, '>') || !in_array($domain, $domains) && !in_array('generic', $domains)) {
unset($entities[$key]);
}
else {
$name = $solr_field_type
->getFieldTypeName();
if (isset($selection[$name])) {
if ('generic' != $domain && 'generic' == $selection[$name]['domain'] && in_array($domain, $domains) || version_compare($version, $selection[$name]['version'], $operator) && in_array($selection[$name]['domain'], $domains)) {
unset($entities[$selection[$name]['key']]);
$selection[$name] = [
'version' => $version,
'key' => $key,
'domain' => in_array($domain, $domains) ? $domain : 'generic',
];
}
else {
unset($entities[$key]);
}
}
else {
$selection[$name] = [
'version' => $version,
'key' => $key,
'domain' => in_array($domain, $domains) ? $domain : 'generic',
];
}
}
}
else {
unset($entities[$key]);
}
}
if ($warning) {
$this->assumed_minimum_version = array_reduce($selection, function ($version, $item) {
if (version_compare($item['version'], $version, '<')) {
return $item['version'];
}
return $version;
}, $solr_version);
\Drupal::messenger()
->addWarning($this
->t('Unable to reach the Solr server (yet). Therefore the lowest supported Solr version %version is assumed.' . ' Once the connection works and the real Solr version could be detected it might be necessary to deploy an adjusted config to the server to get the best search results.' . ' If the server does not start using the downloadable config, you should edit the server and manually set the Solr version override temporarily that fits your server best and download the config again. But it is recommended to remove this override once the server is running.', [
'%version' => $this->assumed_minimum_version,
]));
}
uasort($entities, [
$this->entityType
->getClass(),
'sort',
]);
}
return $entities;
}
public function getDefaultOperations(EntityInterface $solr_field_type) {
$operations = parent::getDefaultOperations($solr_field_type);
if ($solr_field_type
->access('view') && $solr_field_type
->hasLinkTemplate('export-form')) {
$operations['export'] = [
'title' => $this
->t('Export'),
'weight' => 10,
'url' => $solr_field_type
->toUrl('export-form'),
];
}
return $operations;
}
public function getSchemaExtraTypesXml() {
$xml = '';
foreach ($this
->load() as $solr_field_type) {
if (!$solr_field_type
->isManagedSchema()) {
$xml .= $solr_field_type
->getFieldTypeAsXml();
}
}
return $xml;
}
public function getSchemaExtraFieldsXml() {
$multilingual = $this
->getBackend() instanceof SolrMultilingualBackendInterface;
$xml = '';
foreach ($this
->load() as $solr_field_type) {
if (!$solr_field_type
->isManagedSchema()) {
foreach ($solr_field_type
->getDynamicFields($multilingual) as $dynamic_field) {
$xml .= '<dynamicField ';
foreach ($dynamic_field as $attribute => $value) {
$xml .= $attribute . '="' . (is_bool($value) ? $value ? 'true' : 'false' : $value) . '" ';
}
$xml .= "/>\n";
}
foreach ($solr_field_type
->getCopyFields() as $copy_field) {
$xml .= '<copyField ';
foreach ($copy_field as $attribute => $value) {
$xml .= $attribute . '="' . (is_bool($value) ? $value ? 'true' : 'false' : $value) . '" ';
}
$xml .= "/>\n";
}
}
}
return $xml;
}
public function getSolrconfigExtraXml() {
$search_components = [];
foreach ($this
->load() as $solr_field_type) {
if (!$solr_field_type
->isManagedSchema()) {
$xml = $solr_field_type
->getSolrConfigsAsXml();
if (preg_match_all('@(<searchComponent name="[^"]+"[^>]*?>)(.*?)</searchComponent>@sm', $xml, $matches)) {
foreach ($matches[1] as $key => $search_component) {
$search_components[$search_component][] = $matches[2][$key];
}
}
}
}
$xml = '';
foreach ($search_components as $search_component => $details) {
$xml .= $search_component;
foreach ($details as $detail) {
$xml .= $detail;
}
$xml .= "</searchComponent>\n";
}
return $xml;
}
public function getConfigFiles() {
$backend = $this
->getBackend();
$connector = $backend
->getSolrConnector();
$solr_branch = $connector
->getSolrBranch($this->assumed_minimum_version);
$search_api_solr_conf_path = drupal_get_path('module', 'search_api_solr') . '/solr-conf/' . $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(),
'solrconfig_extra.xml' => $this
->getSolrconfigExtraXml(),
];
$solr_field_types = $this
->load();
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->assumed_minimum_version ?: '');
$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] = 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() {
$backend = $this
->getBackend();
$connector = $backend
->getSolrConnector();
$solr_branch = $connector
->getSolrBranch($this->assumed_minimum_version);
$zip = new ZipStream('solr_' . $solr_branch . '_config.zip');
$files = $this
->getConfigFiles();
foreach ($files as $name => $content) {
$zip
->addFile($name, $content);
}
return $zip;
}
public function setServer(ServerInterface $server) {
$this
->setBackend($server
->getBackend());
$this->serverId = $server
->id();
}
public function setBackend(SolrBackendInterface $backend) {
$this->backend = $backend;
}
protected function getBackend() {
return $this->backend;
}
}