Completed
Push — master ( fc9c20...b71285 )
by
unknown
01:52
created

DataTypesModule::getDefinitionSummary()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 8
rs 9.4285
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
namespace DataTypes\Modules;
4
5
use DataTypes\DataTypeFactory;
6
use Exception;
7
use FormatJson;
8
use ResourceLoaderContext;
9
use ResourceLoaderModule;
10
11
/**
12
 * Resource loader module for defining resources that will create a MW config var in JavaScript
13
 * holding information about all data types known to a given DataTypeFactory.
14
 *
15
 * The resource definition requires the following additional keys:
16
 * - (string) datatypesconfigvarname: Name of the "mw.config.get( '...' )" config variable.
17
 * - (Function|DataTypeFactory) datatypefactory: Provider for the data types. Can be a callback
18
 *   returning a DataTypeFactory instance.
19
 *
20
 * @licence GNU GPL v2+
21
 * @author Daniel Werner < [email protected] >
22
 */
23
class DataTypesModule extends ResourceLoaderModule {
24
25
	/**
26
	 * @var DataType[]
27
	 */
28
	protected $dataTypes;
29
30
	/**
31
	 * @var string
32
	 */
33
	protected $dataTypesConfigVarName;
34
35
	/**
36
	 * @var DataTypeFactory
37
	 */
38
	protected $dataTypeFactory;
39
40
	/**
41
	 * @since 0.1
42
	 *
43
	 * @param array $resourceDefinition
44
	 */
45
	public function __construct( array $resourceDefinition ) {
46
		$this->dataTypesConfigVarName =
47
			static::extractDataTypesConfigVarNameFromResourceDefinition( $resourceDefinition );
48
49
		$this->dataTypeFactory =
50
			static::extractDataTypeFactoryFromResourceDefinition( $resourceDefinition );
51
52
		$dataTypeFactory = $this->getDataTypeFactory();
53
		$this->dataTypes = $dataTypeFactory->getTypes();
0 ignored issues
show
Documentation Bug introduced by Daniel Werner
It seems like $dataTypeFactory->getTypes() of type array<integer,object<DataTypes\DataType>> is incompatible with the declared type array<integer,object<DataTypes\Modules\DataType>> of property $dataTypes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
54
	}
55
56
	/**
57
	 * @since 0.1
58
	 *
59
	 * @param array $resourceDefinition
60
	 *
61
	 * @return string
62
	 * @throws Exception If the given resource definition is not sufficient
63
	 */
64
	public static function extractDataTypesConfigVarNameFromResourceDefinition(
65
		array $resourceDefinition
66
	) {
67
		$dataTypesConfigVarName = array_key_exists( 'datatypesconfigvarname', $resourceDefinition )
68
			? $resourceDefinition['datatypesconfigvarname']
69
			: null;
70
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 = array();
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 Array
163
	 */
164
	public function getMessages() {
165
		$messageKeys = array();
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
		$summary[] = array(
187
			'dataHash' => sha1( json_encode( array_keys( $this->dataTypes ) ) )
188
		);
189
190
		return $summary;
191
	}
192
193
}
194