Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
TtmServerFactory.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\TtmServer;
5
7use InvalidArgumentException;
9use TTMServer;
10
17 private array $configs;
18 private ?string $default;
19 private const TTMSERVER_CLASSES = [
20 ReadableTtmServer::class,
21 WritableTtmServer::class,
22 SearchableTtmServer::class
23 ];
24
26 public function __construct( array $configs, ?string $default = null ) {
27 $this->configs = $configs;
28 $this->default = $default;
29 }
30
32 public function getNames(): array {
33 $ttmServersIds = [];
34 foreach ( $this->configs as $serviceId => $config ) {
35 $type = $config['type'] ?? '';
36 if ( $type === 'ttmserver' || $type === 'remote-ttmserver' ) {
37 $ttmServersIds[] = $serviceId;
38 }
39
40 // Translation memory configuration may not define a type, in such
41 // cases we determine whether the service is a TTM server using the
42 // interfaces it implements.
43 $serviceClass = $config['class'] ?? null;
44 if ( $serviceClass !== null ) {
45 foreach ( self::TTMSERVER_CLASSES as $ttmClass ) {
46 if ( $serviceClass instanceof $ttmClass ) {
47 $ttmServersIds[] = $serviceId;
48 break;
49 }
50 }
51 }
52 }
53 return $ttmServersIds;
54 }
55
56 public function has( string $name ): bool {
57 $ttmServersIds = $this->getNames();
58 return in_array( $name, $ttmServersIds );
59 }
60
61 public function create( string $name ): TTMServer {
62 if ( !$this->has( $name ) ) {
63 throw new ServiceCreationFailure( "No configuration for name '$name'" );
64 }
65
66 $config = $this->configs[$name];
67 if ( !is_array( $config ) ) {
68 throw new ServiceCreationFailure( "Invalid configuration for name '$name'" );
69 }
70
71 if ( isset( $config['class'] ) ) {
72 $class = $config['class'];
73
74 // TODO: Add a factory to create TTM server instances
75 if ( in_array( $class, [ DatabaseTtmServer::class, 'DatabaseTTMServer', 'DatabaseTtmServer' ] ) ) {
76 return new DatabaseTtmServer( $config );
77 }
78
79 return new $class( $config );
80 } elseif ( isset( $config['type'] ) ) {
81 $type = $config['type'];
82 switch ( $type ) {
83 case 'ttmserver':
84 return new DatabaseTtmServer( $config );
85 case 'remote-ttmserver':
86 return new RemoteTTMServer( $config );
87 default:
88 throw new ServiceCreationFailure( "Unknown type for name '$name': $type" );
89 }
90 }
91
92 throw new ServiceCreationFailure( "Invalid configuration for name '$name': type not specified" );
93 }
94
95 public function getDefaultForQuerying(): ReadableTtmServer {
96 if ( $this->default === null ) {
97 return new FakeTTMServer();
98 }
99
100 if ( $this->configs[ $this->default ][ 'writable' ] ?? false ) {
101 throw new InvalidArgumentException(
102 "Default TTM service {$this->default} cannot be write only"
103 );
104 }
105
106 $service = $this->create( $this->default );
107
108 if ( $service instanceof ReadableTtmServer ) {
109 return $service;
110 }
111
112 throw new InvalidArgumentException(
113 "Default TTM service {$this->default} must implement ReadableTtmServer."
114 );
115 }
116
122 public function getWritable(): array {
123 $writableServers = $readOnlyServers = [];
124 $ttmServerIds = $this->getNames();
125
126 foreach ( $ttmServerIds as $serverId ) {
127 $isWritable = $this->configs[ $serverId ][ 'writable' ] ?? null;
128 $mirrors = $this->configs[ $serverId ][ 'mirrors' ] ?? null;
129
130 if ( $mirrors !== null ) {
131 if ( $isWritable !== null || $writableServers !== [] ) {
132 throw new InvalidArgumentException(
133 "TTM server configurations cannot use both writable and mirrors parameter."
134 );
135 }
136 }
137
138 if ( $isWritable ) {
139 if ( $serverId === $this->default ) {
140 throw new InvalidArgumentException(
141 "Default TTM server {$this->default} cannot be write only"
142 );
143 }
144
145 $server = $this->create( $serverId );
146 if ( !$server instanceof WritableTtmServer ) {
147 throw new InvalidArgumentException(
148 "Server '$serverId' marked writable does not implement WritableTtmServer interface"
149 );
150 }
151 $writableServers[ $serverId ] = $server;
152 } elseif ( $isWritable === false ) {
153 $readOnlyServers[] = $serverId;
154 }
155 }
156
157 if ( $writableServers ) {
158 return $writableServers;
159 }
160
161 // If there are no writable server, check and use the default server and its mirrors
162 if ( $this->default ) {
163 $mirrorIds = [];
164 $defaultTtmServer = $this->create( $this->default );
165
166 if ( $defaultTtmServer instanceof WritableTtmServer ) {
167 if ( !in_array( $this->default, $readOnlyServers ) ) {
168 $writableServers[ $this->default ] = $defaultTtmServer;
169 }
170 $mirrorIds = $defaultTtmServer->getMirrors();
171 }
172
173 foreach ( $mirrorIds as $id ) {
174 if ( !in_array( $id, $readOnlyServers ) ) {
175 $writableServers[ $id ] = $writableServers[ $id ] ?? $this->create( $id );
176 }
177 }
178
179 if ( $writableServers ) {
180 return $writableServers;
181 }
182 }
183
184 // Did not find any writable servers.
185 return [];
186 }
187
189 public function getWriteOnly(): array {
190 $ttmServerIds = $this->getNames();
191 $writableServers = [];
192 foreach ( $ttmServerIds as $serverId ) {
193 if ( $this->configs[ $serverId ][ 'writable' ] ?? false ) {
194 $server = $this->create( $serverId );
195 if ( !$server instanceof WritableTtmServer ) {
196 throw new \InvalidArgumentException(
197 "Server '$serverId' marked writable does not implement WritableTtmServer interface"
198 );
199 }
200 $writableServers[ $serverId ] = $server;
201 }
202 }
203
204 return $writableServers;
205 }
206}
NO-OP version of TTMServer when it is disabled.
getWritable()
Returns writable servers if configured, else returns the default TtmServer with its mirrors,...
__construct(array $configs, ?string $default=null)
Class for handling remote TTMServers over MediaWiki API.
Some general static methods for instantiating TTMServer and helpers.
Definition TTMServer.php:19
Interface for TTMServer that can be updated.