/src/Solr/Solr.php

https://github.com/silverstripe-labs/silverstripe-fulltextsearch · PHP · 161 lines · 84 code · 20 blank · 57 comment · 6 complexity · 4859ab1849b336060985bbd92a8a9ade MD5 · raw file

  1. <?php
  2. namespace SilverStripe\FullTextSearch\Solr;
  3. use SilverStripe\Control\Director;
  4. use SilverStripe\Core\Injector\Injector;
  5. use SilverStripe\Core\Manifest\Module;
  6. use SilverStripe\Core\Manifest\ModuleLoader;
  7. use SilverStripe\FullTextSearch\Search\FullTextSearch;
  8. use SilverStripe\FullTextSearch\Solr\Services\Solr4Service;
  9. use SilverStripe\FullTextSearch\Solr\Services\Solr3Service;
  10. use SilverStripe\FullTextSearch\Solr\Services\SolrService;
  11. use SilverStripe\FullTextSearch\Solr\Services\SolrService_Core;
  12. class Solr
  13. {
  14. /**
  15. * Configuration on where to find the solr server and how to get new index configurations into it.
  16. *
  17. * Required fields:
  18. * host (default: localhost) - The host or IP Solr is listening on
  19. * port (default: 8983) - The port Solr is listening on
  20. * path (default: /solr) - The suburl the solr service is available on
  21. *
  22. * Optional fields:
  23. * version (default: 4) - The Solr server version. Currently supports 3 and 4 (you can add a sub-version like 4.5 if
  24. * you like, but currently it has no effect)
  25. * service (default: depends on version, Solr3Service for 3, Solr4Service for 4)
  26. * the class that provides actual communcation to the Solr server
  27. * extraspath (default: <basefolder>/fulltextsearch/conf/solr/{version}/extras/) - Absolute path to
  28. * the folder containing templates which are used for generating the schema and field definitions.
  29. * templates (default: <basefolder>/fulltextsearch/conf/solr/{version}/templates/) - Absolute path to
  30. * the configuration default files, e.g. solrconfig.xml.
  31. *
  32. * indexstore => an array with
  33. *
  34. * mode - a classname which implements SolrConfigStore, or 'file', 'webdav' or 'post'
  35. *
  36. * When mode == SolrConfigStore_File or 'file' (indexes should be written on a local filesystem)
  37. * path - The (locally accessible) path to write the index configurations to.
  38. * remotepath (default: the same as indexpath) - The path that the Solr server will read the index configurations from
  39. *
  40. * When mode == SolrConfigStore_Post or 'post' (indexes should stored on a remote Solr server via post)
  41. * This mode will require custom software on the remote solr server which handles receiving the post and
  42. * passing on that information to solr. It is up to the user of this mode to write such software.
  43. * path (default: /solrindex) - The suburl on the solr host that is set up to accept index configurations
  44. * port (default: none) - The port on the remote server which is set up to receive the post information
  45. *
  46. * When mode == SolrConfigStore_WebDAV or 'webdav' (indexes should stored on a remote Solr server via webdav)
  47. * auth (default: none) - A username:password pair string to use to auth against the webdav server
  48. * path (default: /solrindex) - The suburl on the solr host that is set up to accept index configurations via webdav
  49. * port (default: none) - The port for WebDAV if different from the Solr port
  50. * remotepath - The path that the Solr server will read the index configurations from
  51. */
  52. protected static $solr_options = array();
  53. /** A cache of solr_options with the defaults all merged in */
  54. protected static $merged_solr_options = null;
  55. /**
  56. * Update the configuration for Solr. See $solr_options for a discussion of the accepted array keys
  57. * @param array $options - The options to update
  58. */
  59. public static function configure_server($options = array())
  60. {
  61. self::$solr_options = array_merge(self::$solr_options, $options);
  62. self::$merged_solr_options = null;
  63. self::$service_singleton = null;
  64. self::$service_core_singletons = array();
  65. }
  66. /**
  67. * Get the configured Solr options with the defaults all merged in
  68. * @return array - The merged options
  69. */
  70. public static function solr_options()
  71. {
  72. if (self::$merged_solr_options) {
  73. return self::$merged_solr_options;
  74. }
  75. $defaults = array(
  76. 'host' => 'localhost',
  77. 'port' => 8983,
  78. 'path' => '/solr',
  79. 'version' => '4'
  80. );
  81. // Build some by-version defaults
  82. $version = isset(self::$solr_options['version']) ? self::$solr_options['version'] : $defaults['version'];
  83. /** @var Module $module */
  84. $module = ModuleLoader::getModule('silverstripe/fulltextsearch');
  85. $modulePath = $module->getPath();
  86. if (version_compare($version ?? '', '4', '>=')) {
  87. $versionDefaults = [
  88. 'service' => Solr4Service::class,
  89. 'extraspath' => $modulePath . '/conf/solr/4/extras/',
  90. 'templatespath' => $modulePath . '/conf/solr/4/templates/',
  91. ];
  92. } else {
  93. $versionDefaults = [
  94. 'service' => Solr3Service::class,
  95. 'extraspath' => $modulePath . '/conf/solr/3/extras/',
  96. 'templatespath' => $modulePath . '/conf/solr/3/templates/',
  97. ];
  98. }
  99. return (self::$merged_solr_options = array_merge($defaults, $versionDefaults, self::$solr_options));
  100. }
  101. public static function set_service_class($class)
  102. {
  103. user_error('set_service_class is deprecated - pass as part of $options to configure_server', E_USER_WARNING);
  104. self::configure_server(array('service' => $class));
  105. }
  106. /** @var SolrService | null - The instance of SolrService for core management */
  107. protected static $service_singleton = null;
  108. /** @var SolrService_Core[] - The instances of SolrService_Core for each core */
  109. protected static $service_core_singletons = array();
  110. /**
  111. * Get a SolrService
  112. *
  113. * @param string $core Optional name of index class
  114. * @return SolrService|SolrService_Core
  115. */
  116. public static function service($core = null)
  117. {
  118. $options = self::solr_options();
  119. if (!self::$service_singleton) {
  120. self::$service_singleton = Injector::inst()->create(
  121. $options['service'],
  122. $options['host'],
  123. $options['port'],
  124. $options['path']
  125. );
  126. }
  127. if ($core) {
  128. if (!isset(self::$service_core_singletons[$core])) {
  129. self::$service_core_singletons[$core] = self::$service_singleton->serviceForCore(
  130. singleton($core)->getIndexName()
  131. );
  132. }
  133. return self::$service_core_singletons[$core];
  134. }
  135. return self::$service_singleton;
  136. }
  137. public static function get_indexes()
  138. {
  139. return FullTextSearch::get_indexes(SolrIndex::class);
  140. }
  141. }