You are here

search_api_solr.install in Search API Solr 8.2

File

search_api_solr.install
View source
<?php

use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\InstallStorage;
use Drupal\search_api_solr\SolrMultilingualBackendInterface;
use Drupal\Core\Url;

/**
 * Implements hook_requirements().
 */
function search_api_solr_requirements($phase) {
  $requirements = [];
  if ($phase == 'install') {
    if (!class_exists('\\Solarium\\Core\\Client\\Request')) {
      $requirements['search_api_solr_library'] = [
        'description' => t('Solr search requires the solarium/solarium library.'),
        'severity' => REQUIREMENT_ERROR,
      ];
    }
  }
  elseif ($phase == 'runtime') {
    $servers = search_api_solr_get_servers();
    $count = 0;
    $unavailable = 0;
    $multiple_indexes = 0;
    $last = NULL;
    foreach ($servers as $server_id => $server) {
      if (!$server
        ->getBackend()
        ->isAvailable()) {
        ++$unavailable;
        $last = $server;
      }
      $indexes = $server
        ->getIndexes();
      if (count($indexes) > 1) {
        $active = 0;
        foreach ($indexes as $index) {
          if ($index
            ->status()) {
            ++$active;
          }
        }
        if ($active > 1) {
          ++$multiple_indexes;
        }
      }
      ++$count;
    }
    if (!$count) {
      return [];
    }
    $requirements['search_api_solr'] = [
      'title' => \Drupal::translation()
        ->translate('Solr servers'),
      'value' => \Drupal::translation()
        ->formatPlural($count, '1 server', '@count servers'),
    ];
    if ($unavailable) {
      if ($unavailable == 1) {
        $requirements['search_api_solr']['description'] = \Drupal::translation()
          ->translate('The Solr server of <a href=":url">%name</a> could not be reached.', [
          ':url' => Url::fromRoute('entity.search_api_server.canonical', [
            'search_api_server' => $last
              ->id(),
          ])
            ->toString(),
          '%name' => $last
            ->label(),
        ]);
      }
      else {
        $requirements['search_api_solr']['description'] = \Drupal::translation()
          ->translate('@count Solr servers could not be reached.', [
          '@count' => $unavailable,
        ]);
      }
      $requirements['search_api_solr']['severity'] = REQUIREMENT_ERROR;
    }
    else {
      $requirements['search_api_solr']['description'] = \Drupal::translation()
        ->formatPlural($count, 'The Solr server could be reached.', 'All @count Solr servers could be reached.');
      $requirements['search_api_solr']['severity'] = REQUIREMENT_OK;
    }
    $requirements['search_api_solr_multiple_indexes'] = [
      'title' => \Drupal::translation()
        ->translate('Solr servers with multiple indexes'),
      'value' => \Drupal::translation()
        ->formatPlural($count, '1 server', '@count servers'),
    ];
    if ($multiple_indexes) {

      // @todo Warn if autocomplete uses an implementation that is not suitable
      // for multiple indexes per core. But we need the possibility to turn that
      // off if the user acknowledged it because he might really want to have
      // it like this as a feature.
    }
    foreach ($servers as $server) {
      $backend = $server
        ->getBackend();
      if ($backend instanceof SolrMultilingualBackendInterface) {
        $key = 'search_api_solr_multilingual_' . $server
          ->id();
        $requirements[$key] = [
          'title' => t('Multilingual Solr Server'),
          'value' => t('Schema complete'),
          'severity' => REQUIREMENT_OK,
          'description' => t('Schema on server <a href=":url">@server</a> contains all required language-specific fields.', [
            ':url' => $server
              ->toUrl('canonical')
              ->toString(),
            '@server' => $server
              ->label(),
          ]),
        ];
        if ($backend
          ->isAvailable()) {
          $stats = $backend
            ->getSchemaLanguageStatistics();
          if ($missing_languages = array_filter($stats, function ($state) {
            return !$state;
          })) {
            $requirements[$key]['value'] = t('Schema incomplete');
            $requirements[$key]['severity'] = $backend
              ->hasLanguageUndefinedFallback() ? REQUIREMENT_WARNING : REQUIREMENT_ERROR;
            $requirements[$key]['description'] = t('There are some language-specific field types missing in schema of Solr server <a href=":url">@server</a>: @languages.', [
              ':url' => $server
                ->toUrl('canonical')
                ->toString(),
              '@server' => $server
                ->label(),
              '@languages' => implode(', ', array_keys($missing_languages)),
            ]);
          }
        }
        else {
          $requirements[$key]['value'] = t('Not reachable');
          $requirements[$key]['severity'] = REQUIREMENT_ERROR;
          $requirements[$key]['description'] = t('Solr server <a href=":url">@server</a> is not reachable.', [
            ':url' => $server
              ->toUrl('canonical')
              ->toString(),
            '@server' => $server
              ->label(),
          ]);
        }
      }
    }
  }
  return $requirements;
}

/**
 * Implements hook_uninstall().
 *
 * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
 * @throws \Drupal\search_api\SearchApiException
 */
function search_api_solr_uninstall() {
  \Drupal::state()
    ->delete('search_api_solr.last_optimize');
  \Drupal::state()
    ->delete('search_api_solr.endpoint.data');
  foreach (search_api_solr_get_servers() as $server) {
    foreach ($server
      ->getIndexes() as $index) {
      \Drupal::state()
        ->delete('search_api_solr.' . $index
        ->id() . '.last_update');
    }
  }
}

/**
 * Gets all backend configs for active Solr servers.
 *
 * @param string $pattern
 *
 * @return array
 *   All backend configs for active Solr servers keyed by server name.
 */
function search_api_solr_update_helper_get_backend_configs($pattern = 'solr') {
  $config_factory = \Drupal::configFactory();
  $backend_configs = [];
  foreach ($config_factory
    ->listAll('search_api.server.') as $server_name) {
    $server = $config_factory
      ->get($server_name);

    // Covers search_api_solr_multilingual, too.
    if (strpos($server
      ->get('backend'), $pattern) !== FALSE) {
      $backend_configs[$server_name] = $server
        ->get('backend_config');
    }
  }
  return $backend_configs;
}

/**
 * Saves a modified backend config for a given Solr server.
 *
 * @param string $server_name
 * @param array $backend_config
 * @param bool $trusted_data
 */
function search_api_solr_update_helper_save_backend_config($server_name, array $backend_config, $trusted_data = TRUE) {
  \Drupal::configFactory()
    ->getEditable($server_name)
    ->set('backend_config', $backend_config)
    ->save($trusted_data);
}

/**
 * Gets all index third party settings for active Solr servers.
 *
 * @param string $pattern
 *
 * @return array
 *   All backend configs for active Solr servers keyed by server name.
 */
function search_api_solr_update_helper_get_index_third_party_settings($pattern = 'solr') {
  $config_factory = \Drupal::configFactory();
  $index_third_party_settings = [];
  foreach ($config_factory
    ->listAll('search_api.index.') as $index_id) {
    $index = $config_factory
      ->get($index_id);
    $backend_configs = search_api_solr_update_helper_get_backend_configs($pattern);
    if (isset($backend_configs[$index
      ->get('server')])) {

      // This index belongs to a Solr server.
      $index_third_party_settings[$index_id] = $index
        ->get('third_party_settings.search_api_solr');
    }
  }
  return $index_third_party_settings;
}

/**
 * Saves a modified backend config for a given Solr server.
 *
 * @param string $index_id
 * @param array $third_party_settings
 * @param bool $trusted_data
 */
function search_api_solr_update_helper_save_index_third_party_settings($index_id, array $third_party_settings, $trusted_data = TRUE) {
  \Drupal::configFactory()
    ->getEditable($index_id)
    ->set('third_party_settings.search_api_solr', $third_party_settings)
    ->save($trusted_data);
}

/**
 * Gets all solr field type configs.
 *
 * @return array
 *   All solr field type configs.
 */
function search_api_solr_update_helper_get_field_type_configs() {
  $config_factory = \Drupal::configFactory();
  $field_type_configs = [];
  foreach ($config_factory
    ->listAll('search_api_solr.solr_field_type.') as $field_type_name) {
    $field_type_configs[$field_type_name] = $config_factory
      ->get($field_type_name)
      ->getRawData();
  }
  return $field_type_configs;
}

/**
 * Saves a modified solr field type config.
 *
 * @param string $field_type_name
 * @param array $field_type_config
 * @param bool $trusted_data
 */
function search_api_solr_update_helper_save_field_type_config($field_type_name, array $field_type_config, $trusted_data = TRUE) {
  \Drupal::configFactory()
    ->getEditable($field_type_name)
    ->setData($field_type_config)
    ->save($trusted_data);
}

/**
 * Helper function to install all new configs.
 *
 * @param string $directory
 */
function search_api_solr_update_helper_install_configs($directory = InstallStorage::CONFIG_OPTIONAL_DIRECTORY) {

  /** @var \Drupal\Core\Config\ConfigInstallerInterface $config_installer */
  $config_installer = \Drupal::service('config.installer');
  $config_installer
    ->installDefaultConfig('module', 'search_api_solr');
  $optional_install_path = \Drupal::moduleHandler()
    ->getModule('search_api_solr')
    ->getPath() . '/' . $directory;
  if (is_dir($optional_install_path)) {

    // Install any optional config the module provides.
    $storage = new FileStorage($optional_install_path, StorageInterface::DEFAULT_COLLECTION);
    $config_installer
      ->installOptionalConfig($storage);
  }
  $restrict_by_dependency = [
    'module' => 'search_api_solr',
  ];
  $config_installer
    ->installOptionalConfig(NULL, $restrict_by_dependency);
}

/**
 * Split Solr paths stored in configurations into server and core parts.
 */
function search_api_solr_update_8001() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    $parts = explode('/', $backend_config['path']);
    if (count($parts) > 2) {
      $backend_config['core'] = array_pop($parts);
      $backend_config['path'] = implode('/', $parts);
      search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
    }
  }
}

/**
 * Convert http_user and http_pass to username and password config for Solarium.
 */
function search_api_solr_update_8002() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    $backend_config['username'] = $backend_config['http_user'];
    $backend_config['password'] = $backend_config['http_pass'];
    unset($backend_config['http_user'], $backend_config['http_pass']);
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
}

/**
 * Add default timeout settings to existing configs.
 */
function search_api_solr_update_8003() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    $backend_config['timeout'] = 5;
    $backend_config['index_timeout'] = 5;
    $backend_config['optimize_timeout'] = 10;
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
}

/**
 * Migrate existing backend configurations to the basic auth connector plugin.
 */
function search_api_solr_update_8004() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    $backend_config['connector'] = 'basic_auth';
    $backend_config['connector_config'] = [];
    foreach ([
      'scheme',
      'host',
      'port',
      'path',
      'core',
      'timeout',
      'index_timeout',
      'optimize_timeout',
      'solr_version',
      'http_method',
      'username',
      'password',
    ] as $key) {
      $backend_config['connector_config'][$key] = $backend_config[$key];
      unset($backend_config[$key]);
    }
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
}

/**
 * Add commit_within settings to existing connector configs.
 */
function search_api_solr_update_8005() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    $backend_config['connector_config']['commit_within'] = 1000;
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
}

/**
 * Add autocomplete settings to existing configs.
 */
function search_api_solr_update_8006() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    $backend_config['suggest_suffix'] = TRUE;
    $backend_config['suggest_corrections'] = TRUE;
    $backend_config['suggest_words'] = FALSE;
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
}

/**
 * Remove old autocomplete settings in existing configs.
 */
function search_api_solr_update_8007() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    unset($backend_config['autocorrect_spell']);
    unset($backend_config['autocorrect_suggest_words']);
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
}

/**
 * Remove obsolete settings in existing configs.
 */
function search_api_solr_update_8008() {
  $config_factory = \Drupal::configFactory();
  foreach ($config_factory
    ->listAll('search_api_solr.settings.') as $setting) {
    $config = $config_factory
      ->getEditable($setting);
    $data = $config
      ->getRawData();
    unset($data['autocomplete_max_occurrences']);
    unset($data['http_get_max_length']);
    $config
      ->setData($data);
    $config
      ->save(TRUE);
  }
}

/**
 * Remove Search API Multilingual Solr Search left-overs.
 */
function search_api_solr_update_8200() {
  $database = Drupal::database();
  $database
    ->delete('key_value')
    ->condition('collection', 'system.schema')
    ->condition('name', 'search_api_solr_multilingual')
    ->execute();
}

/**
 * Fix suggester field type.
 */
function search_api_solr_update_8201() {
  foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
    if (!empty($field_type_config['solr_configs']) && !empty($field_type_config['solr_configs']['searchComponents'])) {
      foreach ($field_type_config['solr_configs']['searchComponents'] as &$component) {
        if ($component['name'] == 'suggest') {
          foreach ($component['lst'] as &$lst) {
            foreach ($lst['str'] as &$str) {
              foreach ($lst['str'] as &$entry) {
                if ($entry['name'] == 'field') {
                  $entry['VALUE'] = 'twm_suggest';
                  search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
                  break;
                }
              }
            }
          }
        }
      }
    }
  }
}

/**
 * Enable support for targeted domains for all backends and add custom codes.
 */
function search_api_solr_update_8202() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    if (!isset($backend_config['domain'])) {
      if (isset($backend_config['sasm_domain'])) {
        $backend_config['domain'] = $backend_config['sasm_domain'];
        unset($backend_config['sasm_domain']);
      }
      else {
        $backend_config['domain'] = 'generic';
      }
    }
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
  foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
    if (!isset($field_type_config['custom_code'])) {
      $field_type_config['custom_code'] = '';
    }
    search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
  }
}

/**
 * Install new essential Solr field types.
 */
function search_api_solr_update_8203() {

  // Removed.
}

/**
 * Enable phrase suggestions support.
 */
function search_api_solr_update_8204() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    if (!isset($backend_config['suggest_phrases'])) {
      $backend_config['suggest_phrases'] = FALSE;
    }
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
}

/**
 * Drop never implemented word suggestions support.
 */
function search_api_solr_update_8205() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    if (isset($backend_config['suggest_words'])) {
      unset($backend_config['suggest_words']);
    }
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
}

/**
 * Remove obsolete autocomplete settings.
 */
function search_api_solr_update_8206() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    unset($backend_config['suggest_suffix']);
    unset($backend_config['suggest_corrections']);
    unset($backend_config['suggest_phrases']);
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
}

/**
 * Fix language undefined field types.
 */
function search_api_solr_update_8207() {
  foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
    if (strpos($field_type_name, 'text_und') === 0) {
      if (!empty($field_type_config['field_type']) && !empty($field_type_config['field_type']['analyzers'])) {
        foreach ($field_type_config['field_type']['analyzers'] as &$component) {
          foreach ($component['filters'] as &$filter) {
            foreach ($filter as &$entry) {
              if ($entry['class'] == 'solr.SnowballPorterFilterFactory') {
                unset($entry);
              }
            }
          }
        }
      }
      search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
    }
  }
}

/**
 * Enable new highlighter.
 */
function search_api_solr_update_8208() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    if (isset($backend_config['excerpt'])) {
      unset($backend_config['excerpt']);
    }
    search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
  }
  $config_factory = \Drupal::configFactory();
  $config = $config_factory
    ->getEditable('search_api_solr.standard_highlighter');
  $data = $config
    ->getRawData();
  unset($data['excerpt']);
  $data['highlight']['snippets'] = 3;
  $data['highlight']['fragsize'] = 0;
  $config
    ->setData($data);
  $config
    ->save(TRUE);
}

/**
 * Install missing configs for 8.x-2.0-alpha3.
 */
function search_api_solr_update_8209() {

  // search_api_solr_update_helper_install_configs(InstallStorage::CONFIG_INSTALL_DIRECTORY);
}

/**
 * Install missing configs for 8.x-2.0-beta1.
 */
function search_api_solr_update_8210() {

  // search_api_solr_update_helper_install_configs(InstallStorage::CONFIG_OPTIONAL_DIRECTORY);
}

/**
 * Add default finalize timeout settings to existing configs.
 */
function search_api_solr_update_8211() {
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    if (!isset($backend_config['finalize_timeout'])) {
      $backend_config['finalize_timeout'] = 30;
      search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
    }
  }
}

/**
 * Configure highlighter individually per index and remove global config.
 */
function search_api_solr_update_8212() {
  $config_factory = \Drupal::configFactory();
  $config = $config_factory
    ->getEditable('search_api_solr.standard_highlighter');
  $data = $config
    ->getRawData();
  foreach (search_api_solr_update_helper_get_index_third_party_settings() as $index_id => $third_party_settings) {
    if (!isset($third_party_settings['highlighter'])) {
      $third_party_settings['highlighter'] = $data;
    }
    search_api_solr_update_helper_save_index_third_party_settings($index_id, $third_party_settings);
  }
  $config
    ->delete();
}

/**
 * Configure index prefixes individually per server and index.
 */
function search_api_solr_update_8213() {
  $config_factory = \Drupal::configFactory();
  $config = $config_factory
    ->getEditable('search_api_solr.settings');
  $data = $config
    ->getRawData();
  foreach (search_api_solr_update_helper_get_index_third_party_settings() as $index_id => $third_party_settings) {
    if (!isset($third_party_settings['advanced']) && !isset($third_party_settings['advanced']['index_prefix'])) {
      $third_party_settings['advanced']['index_prefix'] = isset($data['index_prefix_' . $index_id]) ? $data['index_prefix_' . $index_id] : '';
      unset($data['index_prefix_' . $index_id]);
    }
    search_api_solr_update_helper_save_index_third_party_settings($index_id, $third_party_settings);
  }
  foreach (search_api_solr_update_helper_get_backend_configs() as $server_name => $backend_config) {
    if (!isset($backend_config['server_prefix'])) {
      $backend_config['server_prefix'] = isset($data['index_prefix']) ? $data['index_prefix'] : '';
      search_api_solr_update_helper_save_backend_config($server_name, $backend_config);
    }
  }
  unset($data['index_prefix']);
  $config
    ->setData($data);
  $config
    ->save(TRUE);
}

/**
 * All pre-configured Solr field type configurations will be re-installed as
 * delivered by the module! Please export your existing config before running
 * the update and compare the changes manually, if you modified these configs by
 * yourself!
 */
function search_api_solr_update_8214() {
  $config_factory = \Drupal::configFactory();
  $settings = $config_factory
    ->get('search_api_solr.settings');
  $raw_data = $settings
    ->getRawData();

  // Unfortunately this function will overwrite search_api_solr.settings, too.
  // Therfore we save it's values bafore and restore them afterwards. In 3.x
  // this "config" is completely migrated to Drupal states.
  search_api_solr_update_helper_install_configs();
  $settings = $config_factory
    ->getEditable('search_api_solr.settings');
  $settings
    ->setData($raw_data)
    ->save(TRUE);
  foreach (search_api_solr_update_helper_get_field_type_configs() as $field_type_name => $field_type_config) {
    if (version_compare($field_type_config['minimum_solr_version'], '7.0.0', '>=') && !empty($field_type_config['field_type']) && !empty($field_type_config['field_type']['analyzers'])) {
      foreach ($field_type_config['field_type']['analyzers'] as &$component) {
        foreach ($component['filters'] as &$filter) {
          switch ($filter['class']) {
            case 'solr.WordDelimiterFilterFactory':
              $filter['class'] = 'solr.WordDelimiterGraphFilterFactory';
              break;
            case 'solr.SynonymFilterFactory':
              $filter['class'] = 'solr.SynonymGraphFilterFactory';
              break;
            case 'solr.StopFilterFactory':
              unset($filter['enablePositionIncrements']);
              break;
          }
        }
      }
    }
    search_api_solr_update_helper_save_field_type_config($field_type_name, $field_type_config);
  }
}

Functions

Namesort descending Description
search_api_solr_requirements Implements hook_requirements().
search_api_solr_uninstall Implements hook_uninstall().
search_api_solr_update_8001 Split Solr paths stored in configurations into server and core parts.
search_api_solr_update_8002 Convert http_user and http_pass to username and password config for Solarium.
search_api_solr_update_8003 Add default timeout settings to existing configs.
search_api_solr_update_8004 Migrate existing backend configurations to the basic auth connector plugin.
search_api_solr_update_8005 Add commit_within settings to existing connector configs.
search_api_solr_update_8006 Add autocomplete settings to existing configs.
search_api_solr_update_8007 Remove old autocomplete settings in existing configs.
search_api_solr_update_8008 Remove obsolete settings in existing configs.
search_api_solr_update_8200 Remove Search API Multilingual Solr Search left-overs.
search_api_solr_update_8201 Fix suggester field type.
search_api_solr_update_8202 Enable support for targeted domains for all backends and add custom codes.
search_api_solr_update_8203 Install new essential Solr field types.
search_api_solr_update_8204 Enable phrase suggestions support.
search_api_solr_update_8205 Drop never implemented word suggestions support.
search_api_solr_update_8206 Remove obsolete autocomplete settings.
search_api_solr_update_8207 Fix language undefined field types.
search_api_solr_update_8208 Enable new highlighter.
search_api_solr_update_8209 Install missing configs for 8.x-2.0-alpha3.
search_api_solr_update_8210 Install missing configs for 8.x-2.0-beta1.
search_api_solr_update_8211 Add default finalize timeout settings to existing configs.
search_api_solr_update_8212 Configure highlighter individually per index and remove global config.
search_api_solr_update_8213 Configure index prefixes individually per server and index.
search_api_solr_update_8214 All pre-configured Solr field type configurations will be re-installed as delivered by the module! Please export your existing config before running the update and compare the changes manually, if you modified these configs by yourself!
search_api_solr_update_helper_get_backend_configs Gets all backend configs for active Solr servers.
search_api_solr_update_helper_get_field_type_configs Gets all solr field type configs.
search_api_solr_update_helper_get_index_third_party_settings Gets all index third party settings for active Solr servers.
search_api_solr_update_helper_install_configs Helper function to install all new configs.
search_api_solr_update_helper_save_backend_config Saves a modified backend config for a given Solr server.
search_api_solr_update_helper_save_field_type_config Saves a modified solr field type config.
search_api_solr_update_helper_save_index_third_party_settings Saves a modified backend config for a given Solr server.