Completed
Push — address-as-title ( 9b6eeb...601934 )
by Peter
11:07
created

MapsMappingServices   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 227
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 22
c 1
b 0
f 0
lcom 1
cbo 1
dl 0
loc 227
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A registerService() 0 7 2
A registerServiceFeature() 0 10 2
A getServiceInstance() 0 19 4
A getValidServiceInstance() 0 3 1
B getValidServiceName() 0 29 4
A getServiceIdentifiers() 0 3 1
A getMainServiceName() 0 14 4
A getAllServiceValues() 0 12 2
A getAllObjects() 0 9 2
1
<?php
2
3
/**
4
 * Class for interaction with MappingService objects.
5
 * 
6
 * @since 0.6.6
7
 *
8
 * @licence GNU GPL v2+
9
 * @author Jeroen De Dauw < [email protected] >
10
 */
11
final class MapsMappingServices {
12
	
13
	/**
14
	 * Associative array containing service identifiers as keys and the names
15
	 * of service classes as values.
16
	 * 
17
	 * @since 0.6.6
18
	 * 
19
	 * @var string[]
20
	 */
21
	protected static $registeredServices = [];
22
	
23
	/**
24
	 * Associative with service identifiers as keys containing instances of
25
	 * the mapping service classes. 
26
	 * 
27
	 * Note: This list only contains the instances, so is not to be used for
28
	 * looping over all available services, as not all of them are guaranteed 
29
	 * to have an instance already, use $registeredServices for this purpose.
30
	 * 
31
	 * @since 0.6.6
32
	 * 
33
	 * @var iMappingService[]
34
	 */
35
	protected static $services = [];
36
	
37
	/**
38
	 * Registers a service class linked to an identifier.
39
	 * Also allows automatic registration of a list of features for this service.
40
	 * 
41
	 * @since 0.6.6
42
	 * 
43
	 * @param $serviceIdentifier String: internal service identifier
44
	 * @param $serviceClassName String
45
	 * @param $features Array
46
	 */
47
	public static function registerService( $serviceIdentifier, $serviceClassName, array $features = [] ) {
48
		self::$registeredServices[$serviceIdentifier] = $serviceClassName;
49
		
50
		foreach( $features as $featureName => $featureClassName ) {
51
			self::registerServiceFeature( $serviceIdentifier, $featureName, $featureClassName );
52
		}
53
	}
54
	
55
	/**
56
	 * Registeres a feature for a service object.
57
	 * Registers a warning when the service is not registered, but does not give an error.
58
	 * 
59
	 * @since 0.6.6
60
	 * 
61
	 * @param $serviceIdentifier String: internal service identifier
62
	 * @param $featureName String
63
	 * @param $featureClassName String
64
	 */
65
	public static function registerServiceFeature( $serviceIdentifier, $featureName, $featureClassName ) {
66
		if ( array_key_exists( $serviceIdentifier, self::$registeredServices ) ) {
67
			$service = self::getServiceInstance( $serviceIdentifier );
68
			$service->addFeature( $featureName, $featureClassName );			
69
		}
70
		else {
71
			// If the feature is not registered, register a warning. This is not an error though!
72
			wfWarn( "Tried to register feature '$featureName' with class '$featureClassName' to non-registered service '$serviceIdentifier'." );
73
		}
74
	}
75
	
76
	/**
77
	 * Returns the instance of a service class. This method takes
78
	 * care of creating the instance if this is not done yet.
79
	 * 
80
	 * @since 0.6.6
81
	 * 
82
	 * @param $serviceIdentifier String: internal service identifier
83
	 * 
84
	 * @return iMappingService
85
	 */
86
	public static function getServiceInstance( $serviceIdentifier ) {
87
		if ( !array_key_exists( $serviceIdentifier, self::$services ) ) {
88
			if ( array_key_exists( $serviceIdentifier, self::$registeredServices ) ) {
89
				$service = new self::$registeredServices[$serviceIdentifier]( $serviceIdentifier );
90
				
91
				if ( $service instanceof iMappingService ) {
92
					self::$services[$serviceIdentifier] = $service;
93
				}
94
				else {
95
					throw new MWException( 'The service object linked to service identifier ' . $serviceIdentifier . ' does not implement iMappingService.' );
96
				}
97
			}
98
			else {
99
				throw new MWException( 'There is no service object linked to service identifier ' . $serviceIdentifier . '.' );
100
			}
101
		}
102
103
		return self::$services[$serviceIdentifier];
104
	}
105
	
106
	/**
107
	 * Retuns an instance of a MapsMappingService. The service name is validated
108
	 * and aliases are resolved and a check is made if the feature is supported.
109
	 * If the feature is not supported, or the service does not exist, defaulting
110
	 * will be used.
111
	 * 
112
	 * @since 0.6.6
113
	 * 
114
	 * @param $service String: service name or alias, does not need to be secure
115
	 * @param $feature String
116
	 * 
117
	 * @return iMappingService
118
	 */
119
	public static function getValidServiceInstance( $service, $feature ) {
120
		return self::getServiceInstance( self::getValidServiceName( $service, $feature ) );
121
	}
122
	
123
	/**
124
	 * Returns a valid service. When an invalid service is provided, the default one will be returned.
125
	 * Aliases are also changed into the main service names @see MapsMappingServices::getMainServiceName.
126
	 *
127
	 * @since 0.6.6
128
	 *
129
	 * @param $service String: service name or alias, does not need to be secure
130
	 * @param $feature String
131
	 *
132
	 * @return string
133
	 */
134
	public static function getValidServiceName( $service, $feature ) {
135
		global $egMapsDefaultService, $egMapsDefaultServices;
136
137
		// Get rid of any aliases.
138
		// Also rely on this to instantiate all registered services.
139
		$service = self::getMainServiceName( $service );
140
		
141
		// Check if there is a mathing instance.
142
		$shouldChange = !array_key_exists( $service, self::$services );
143
		
144
		// If it should not be changed, ensure the service supports this feature.
145
		if ( !$shouldChange ) {
146
			$shouldChange = self::getServiceInstance( $service )->getFeature( $feature ) === false;
147
		}
148
149
		// Change the service to the most specific default value available.
150
		// Note: the default services should support their corresponding features.
151
		// If they don't, a fatal error will occur later on.
152
		if ( $shouldChange ) {
153
			if ( array_key_exists( $feature, $egMapsDefaultServices ) ) {
154
				$service = $egMapsDefaultServices[$feature];
155
			}
156
			else {
157
				$service = $egMapsDefaultService;
158
			}
159
		}
160
161
		return $service;
162
	}
163
164
	/**
165
	 * Returns an array with the identifiers for all registered services.
166
	 * 
167
	 * @since 0.6.6
168
	 * 
169
	 * @return array
170
	 */
171
	public static function getServiceIdentifiers() {
172
		return array_keys( self::$registeredServices );
173
	}
174
	
175
	/**
176
	 * Checks if the service name is an alias for an actual service,
177
	 * and changes it into the main service name if this is the case.
178
	 *
179
	 * @since 0.6.6
180
	 *
181
	 * @param $serviceName String: service name or alias, does not need to be secure
182
	 * 
183
	 * @return string
184
	 */
185
	protected static function getMainServiceName( $serviceName ) {
186
		if ( !array_key_exists( $serviceName, self::$services ) ) {
187
			foreach ( self::getServiceIdentifiers() as $serviceIdentifier ) {
188
				$service = self::getServiceInstance( $serviceIdentifier );
189
190
				if ( $service->hasAlias( $serviceName ) ) {
191
					 $serviceName = $service->getName();
192
					 break;
193
				}
194
			}
195
		}
196
		
197
		return $serviceName;
198
	}
199
	
200
	/**
201
	 * Returns an array containing all the possible values for the service parameter, including aliases.
202
	 *
203
	 * @since 0.6.6
204
	 *
205
	 * @return array of string
206
	 */
207
	public static function getAllServiceValues() {
208
		global $egMapsAvailableServices;
209
210
		$allServiceValues = [];
211
212
		foreach ( $egMapsAvailableServices as $availableService ) {
213
			$allServiceValues[] = $availableService;
214
			$allServiceValues = array_merge( $allServiceValues, self::getServiceInstance( $availableService )->getAliases() );
215
		}
216
217
		return $allServiceValues;
218
	}
219
	
220
	/**
221
	 * Returns an array with an instance of a MappingService object for every available mapping service.
222
	 * 
223
	 * @since 0.7.3
224
	 * 
225
	 * @return array of MappingService
226
	 */
227
	public static function getAllObjects() {
228
		$objects = [];
229
		
230
		foreach ( self::$registeredServices as $service => $class ) {
231
			$objects[] = self::getServiceInstance( $service );
232
		}
233
		
234
		return $objects;
235
	} 
236
	
237
}
238