MediaWiki REL1_35
ExternalStoreFactory.php
Go to the documentation of this file.
1<?php
7use Psr\Log\LoggerAwareInterface;
8use Psr\Log\LoggerInterface;
9use Psr\Log\NullLogger;
10use Wikimedia\Assert\Assert;
11
15class ExternalStoreFactory implements LoggerAwareInterface {
17 private $protocols;
23 private $logger;
24
31 public function __construct(
32 array $externalStores,
33 array $defaultStores,
34 $localDomainId,
35 LoggerInterface $logger = null
36 ) {
37 Assert::parameterType( 'string', $localDomainId, '$localDomainId' );
38
39 $this->protocols = array_map( 'strtolower', $externalStores );
40 $this->writeBaseUrls = $defaultStores;
41 $this->localDomainId = $localDomainId;
42 $this->logger = $logger ?: new NullLogger();
43 }
44
45 public function setLogger( LoggerInterface $logger ) {
46 $this->logger = $logger;
47 }
48
53 public function getProtocols() {
54 return $this->protocols;
55 }
56
61 public function getWriteBaseUrls() {
62 return $this->writeBaseUrls;
63 }
64
77 public function getStore( $proto, array $params = [] ) {
78 $protoLowercase = strtolower( $proto ); // normalize
79 if ( !$this->protocols || !in_array( $protoLowercase, $this->protocols ) ) {
80 throw new ExternalStoreException( "Protocol '$proto' is not enabled." );
81 }
82
83 $class = 'ExternalStore' . ucfirst( $proto );
84 if ( isset( $params['wiki'] ) ) {
85 $params += [ 'domain' => $params['wiki'] ]; // b/c
86 }
87 if ( !isset( $params['domain'] ) || $params['domain'] === false ) {
88 $params['domain'] = $this->localDomainId; // default
89 $params['isDomainImplicit'] = true; // b/c for ExternalStoreDB
90 }
91 // @TODO: ideally, this class should not hardcode what classes need what backend factory
92 // objects. For now, inject the factory instances into __construct() for those that do.
93 if ( $protoLowercase === 'db' ) {
94 $params['lbFactory'] = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
95 } elseif ( $protoLowercase === 'mwstore' ) {
96 $params['fbGroup'] = MediaWikiServices::getInstance()->getFileBackendGroup();
97 }
98 $params['logger'] = $this->logger;
99
100 if ( !class_exists( $class ) ) {
101 throw new ExternalStoreException( "Class '$class' is not defined." );
102 }
103
104 // Any custom modules should be added to $wgAutoLoadClasses for on-demand loading
105 return new $class( $params );
106 }
107
121 public function getStoreForUrl( $url, array $params = [] ) {
122 list( $proto, $path ) = self::splitStorageUrl( $url );
123 if ( $path == '' ) { // bad URL
124 throw new ExternalStoreException( "Invalid URL '$url'" );
125 }
126
127 return $this->getStore( $proto, $params );
128 }
129
138 public function getStoreLocationFromUrl( $url ) {
139 list( , $location ) = self::splitStorageUrl( $url );
140 if ( $location == '' ) { // bad URL
141 throw new ExternalStoreException( "Invalid URL '$url'" );
142 }
143
144 return $location;
145 }
146
153 public function getUrlsByProtocol( array $urls ) {
154 $urlsByProtocol = [];
155 foreach ( $urls as $url ) {
156 list( $proto, ) = self::splitStorageUrl( $url );
157 $urlsByProtocol[$proto][] = $url;
158 }
159
160 return $urlsByProtocol;
161 }
162
168 private static function splitStorageUrl( $storeUrl ) {
169 $parts = explode( '://', $storeUrl );
170 if ( count( $parts ) != 2 || $parts[0] === '' || $parts[1] === '' ) {
171 throw new ExternalStoreException( "Invalid storage URL '$storeUrl'" );
172 }
173
174 return $parts;
175 }
176}
setLogger(LoggerInterface $logger)
__construct(array $externalStores, array $defaultStores, $localDomainId, LoggerInterface $logger=null)
string[] $protocols
List of storage access protocols.
string $localDomainId
Default database domain to store content under.
static splitStorageUrl( $storeUrl)
getStore( $proto, array $params=[])
Get an external store object of the given type, with the given parameters.
getStoreForUrl( $url, array $params=[])
Get the ExternalStoreMedium for a given URL.
string[] $writeBaseUrls
List of base storage URLs that define locations for writes.
getStoreLocationFromUrl( $url)
Get the location within the appropriate store for a given a URL.
MediaWikiServices is the service locator for the application scope of MediaWiki.