Passed
Push — emptyDataTypes ( f4f402...823201 )
by no
07:53 queued 03:45
created

DataTypesModule::getDefinitionSummary()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 9
rs 9.6666
cc 1
eloc 5
nc 1
nop 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
 * @licence GNU GPL v2+
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
73
		if ( !is_string( $dataTypesConfigVarName ) || $dataTypesConfigVarName === '' ) {
74
			throw new Exception(
75
				'The "datatypesconfigvarname" value of the resource definition' .
76
				' has to be a non-empty string value'
77
			);
78
		}
79
80
		return $dataTypesConfigVarName;
81
	}
82
83
	/**
84
	 * @since 0.1
85
	 *
86
	 * @param array $resourceDefinition
87
	 *
88
	 * @return DataTypeFactory
89
	 * @throws Exception If the given resource definition is not sufficient
90
	 */
91
	public static function extractDataTypeFactoryFromResourceDefinition(
92
		array $resourceDefinition
93
	) {
94
		$dataTypeFactory = array_key_exists( 'datatypefactory', $resourceDefinition )
95
			? $resourceDefinition['datatypefactory']
96
			: null;
97
98
		if ( is_callable( $dataTypeFactory ) ) {
99
			$dataTypeFactory = call_user_func( $dataTypeFactory );
100
		}
101
102
		if ( !( $dataTypeFactory instanceof DataTypeFactory ) ) {
103
			throw new Exception(
104
				'The "datatypefactory" value of the resource definition has' .
105
				' to be an instance of DataTypeFactory or a callback returning one'
106
			);
107
		}
108
109
		return $dataTypeFactory;
110
	}
111
112
	/**
113
	 * Returns the name of the config var key under which the data type definition will be available
114
	 * in JavaScript using "mw.config.get( '...' )"
115
	 *
116
	 * @since 0.1
117
	 *
118
	 * @return string
119
	 */
120
	public function getConfigVarName() {
121
		return $this->dataTypesConfigVarName;
122
	}
123
124
	/**
125
	 * Returns the data types factory providing the data type information.
126
	 *
127
	 * @since 0.1
128
	 *
129
	 * @return DataTypeFactory
130
	 */
131
	public function getDataTypeFactory() {
132
		return $this->dataTypeFactory;
133
	}
134
135
	/**
136
	 * Used to propagate available data type ids to JavaScript.
137
	 * Data type ids will be available in 'wbDataTypeIds' config var.
138
	 * @see ResourceLoaderModule::getScript
139
	 *
140
	 * @since 0.1
141
	 *
142
	 * @param ResourceLoaderContext $context
143
	 *
144
	 * @return string
145
	 */
146
	public function getScript( ResourceLoaderContext $context ) {
147
		$configVarName = $this->getConfigVarName();
148
		$typesJson = array();
149
150
		foreach( $this->dataTypes as $dataType ) {
151
			$typesJson[ $dataType->getId() ] = $dataType->toArray();
152
		}
153
		$typesJson = FormatJson::encode( $typesJson );
154
155
		return "mediaWiki.config.set( '$configVarName', $typesJson );";
156
	}
157
158
	/**
159
	 * Returns the message keys of the registered data types.
160
	 * @see ResourceLoaderModule::getMessages
161
	 * @since 0.1
162
	 *
163
	 * @return Array
164
	 */
165
	public function getMessages() {
166
		$messageKeys = array();
167
168
		foreach( $this->dataTypes as $dataType ) {
169
			// TODO: currently we assume that the type is using a message while it does not have to.
170
			//  Either change the system to ensure that a message is used or put the type labels
171
			//  directly into the JSON. Either way, the information should be in DataType::toArray.
172
			$messageKeys[] = 'datatypes-type-' . $dataType->getId();
173
		}
174
175
		return $messageKeys;
176
	}
177
178
	/**
179
	 * @see ResourceLoaderModule::getDefinitionSummary
180
	 *
181
	 * @param ResourceLoaderContext $context
182
	 *
183
	 * @return array
184
	 */
185
	public function getDefinitionSummary( ResourceLoaderContext $context ) {
186
		$summary = parent::getDefinitionSummary( $context );
187
188
		$summary[] = array(
189
			'dataHash' => sha1( json_encode( array_keys( $this->dataTypes ) ) )
190
		);
191
192
		return $summary;
193
	}
194
195
}
196