DataTypesModule   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 2
dl 0
loc 171
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A extractDataTypesConfigVarNameFromResourceDefinition() 0 16 4
A extractDataTypeFactoryFromResourceDefinition() 0 20 4
A getConfigVarName() 0 3 1
A getDataTypeFactory() 0 3 1
A getScript() 0 11 2
A getMessages() 0 12 2
A getDefinitionSummary() 0 9 1
1
<?php
2
3
namespace DataTypes\Modules;
4
5
use DataTypes\DataType;
6
use DataTypes\DataTypeFactory;
7
use Exception;
8
use FormatJson;
9
use ResourceLoaderContext;
10
use ResourceLoaderModule;
11
12
/**
13
 * Resource loader module for defining resources that will create a MW config var in JavaScript
14
 * holding information about all data types known to a given DataTypeFactory.
15
 *
16
 * The resource definition requires the following additional keys:
17
 * - (string) datatypesconfigvarname: Name of the "mw.config.get( '...' )" config variable.
18
 * - (Function|DataTypeFactory) datatypefactory: Provider for the data types. Can be a callback
19
 *   returning a DataTypeFactory instance.
20
 *
21
 * @license GPL-2.0+
22
 * @author Daniel Werner < [email protected] >
23
 */
24
class DataTypesModule extends ResourceLoaderModule {
25
26
	/**
27
	 * @var DataType[]
28
	 */
29
	protected $dataTypes;
30
31
	/**
32
	 * @var string
33
	 */
34
	protected $dataTypesConfigVarName;
35
36
	/**
37
	 * @var DataTypeFactory
38
	 */
39
	protected $dataTypeFactory;
40
41
	/**
42
	 * @since 0.1
43
	 *
44
	 * @param array $resourceDefinition
45
	 */
46
	public function __construct( array $resourceDefinition ) {
47
		$this->dataTypesConfigVarName =
48
			static::extractDataTypesConfigVarNameFromResourceDefinition( $resourceDefinition );
49
50
		$this->dataTypeFactory =
51
			static::extractDataTypeFactoryFromResourceDefinition( $resourceDefinition );
52
53
		$dataTypeFactory = $this->getDataTypeFactory();
54
		$this->dataTypes = $dataTypeFactory->getTypes();
55
	}
56
57
	/**
58
	 * @since 0.1
59
	 *
60
	 * @param array $resourceDefinition
61
	 *
62
	 * @return string
63
	 * @throws Exception If the given resource definition is not sufficient
64
	 */
65
	public static function extractDataTypesConfigVarNameFromResourceDefinition(
66
		array $resourceDefinition
67
	) {
68
		$dataTypesConfigVarName = array_key_exists( 'datatypesconfigvarname', $resourceDefinition )
69
			? $resourceDefinition['datatypesconfigvarname']
70
			: null;
71
72
		if ( !is_string( $dataTypesConfigVarName ) || $dataTypesConfigVarName === '' ) {
73
			throw new Exception(
74
				'The "datatypesconfigvarname" value of the resource definition' .
75
				' has to be a non-empty string value'
76
			);
77
		}
78
79
		return $dataTypesConfigVarName;
80
	}
81
82
	/**
83
	 * @since 0.1
84
	 *
85
	 * @param array $resourceDefinition
86
	 *
87
	 * @return DataTypeFactory
88
	 * @throws Exception If the given resource definition is not sufficient
89
	 */
90
	public static function extractDataTypeFactoryFromResourceDefinition(
91
		array $resourceDefinition
92
	) {
93
		$dataTypeFactory = array_key_exists( 'datatypefactory', $resourceDefinition )
94
			? $resourceDefinition['datatypefactory']
95
			: null;
96
97
		if ( is_callable( $dataTypeFactory ) ) {
98
			$dataTypeFactory = call_user_func( $dataTypeFactory );
99
		}
100
101
		if ( !( $dataTypeFactory instanceof DataTypeFactory ) ) {
102
			throw new Exception(
103
				'The "datatypefactory" value of the resource definition has' .
104
				' to be an instance of DataTypeFactory or a callback returning one'
105
			);
106
		}
107
108
		return $dataTypeFactory;
109
	}
110
111
	/**
112
	 * Returns the name of the config var key under which the data type definition will be available
113
	 * in JavaScript using "mw.config.get( '...' )"
114
	 *
115
	 * @since 0.1
116
	 *
117
	 * @return string
118
	 */
119
	public function getConfigVarName() {
120
		return $this->dataTypesConfigVarName;
121
	}
122
123
	/**
124
	 * Returns the data types factory providing the data type information.
125
	 *
126
	 * @since 0.1
127
	 *
128
	 * @return DataTypeFactory
129
	 */
130
	public function getDataTypeFactory() {
131
		return $this->dataTypeFactory;
132
	}
133
134
	/**
135
	 * Used to propagate available data type ids to JavaScript.
136
	 * Data type ids will be available in 'wbDataTypeIds' config var.
137
	 * @see ResourceLoaderModule::getScript
138
	 *
139
	 * @since 0.1
140
	 *
141
	 * @param ResourceLoaderContext $context
142
	 *
143
	 * @return string
144
	 */
145
	public function getScript( ResourceLoaderContext $context ) {
146
		$configVarName = $this->getConfigVarName();
147
		$typesJson = [];
148
149
		foreach ( $this->dataTypes as $dataType ) {
150
			$typesJson[ $dataType->getId() ] = $dataType->toArray();
151
		}
152
		$typesJson = FormatJson::encode( $typesJson );
153
154
		return "mediaWiki.config.set( '$configVarName', $typesJson );";
155
	}
156
157
	/**
158
	 * Returns the message keys of the registered data types.
159
	 * @see ResourceLoaderModule::getMessages
160
	 * @since 0.1
161
	 *
162
	 * @return string[]
163
	 */
164
	public function getMessages() {
165
		$messageKeys = [];
166
167
		foreach ( $this->dataTypes as $dataType ) {
168
			// TODO: currently we assume that the type is using a message while it does not have to.
169
			//  Either change the system to ensure that a message is used or put the type labels
170
			//  directly into the JSON. Either way, the information should be in DataType::toArray.
171
			$messageKeys[] = 'datatypes-type-' . $dataType->getId();
172
		}
173
174
		return $messageKeys;
175
	}
176
177
	/**
178
	 * @see ResourceLoaderModule::getDefinitionSummary
179
	 *
180
	 * @param ResourceLoaderContext $context
181
	 *
182
	 * @return array
183
	 */
184
	public function getDefinitionSummary( ResourceLoaderContext $context ) {
185
		$summary = parent::getDefinitionSummary( $context );
186
187
		$summary[] = [
188
			'dataHash' => sha1( json_encode( array_keys( $this->dataTypes ) ) )
189
		];
190
191
		return $summary;
192
	}
193
194
}
195