1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace SMW\Services; |
4
|
|
|
|
5
|
|
|
use Onoi\CallbackContainer\ContainerBuilder; |
6
|
|
|
use Onoi\CallbackContainer\Exception\ServiceNotFoundException; |
7
|
|
|
use SMW\DataValues\InfoLinksProvider; |
8
|
|
|
use SMWDataValue as DataValue; |
9
|
|
|
use SMW\DataValues\ValueFormatters\DispatchingDataValueFormatter; |
10
|
|
|
use SMW\DataValues\ValueFormatters\NoValueFormatter; |
11
|
|
|
use SMWStringValue as StringValue; |
12
|
|
|
use SMWNumberValue as NumberValue; |
13
|
|
|
use SMWTimeValue as TimeValue; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* @private |
17
|
|
|
* |
18
|
|
|
* This class provides service and factory functions for DataValue objects and |
19
|
|
|
* are only to be used for those objects. |
20
|
|
|
* |
21
|
|
|
* @license GNU GPL v2+ |
22
|
|
|
* @since 2.5 |
23
|
|
|
* |
24
|
|
|
* @author mwjames |
25
|
|
|
*/ |
26
|
|
|
class DataValueServiceFactory { |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Indicates a DataValue service |
30
|
|
|
*/ |
31
|
|
|
const SERVICE_FILE = 'DataValueServices.php'; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Indicates a DataValue service |
35
|
|
|
*/ |
36
|
|
|
const TYPE_INSTANCE = 'dv.'; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Indicates a ValueParser service |
40
|
|
|
*/ |
41
|
|
|
const TYPE_PARSER = 'dv.parser.'; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Indicates a ValueFormatter service |
45
|
|
|
*/ |
46
|
|
|
const TYPE_FORMATTER = 'dv.formatter.'; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Indicates a ValueValidator service |
50
|
|
|
*/ |
51
|
|
|
const TYPE_VALIDATOR = 'dv.validator.'; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Extraneous service |
55
|
|
|
*/ |
56
|
|
|
const TYPE_EXT_FUNCTION = 'dv.ext.func.'; |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* @var ContainerBuilder |
60
|
|
|
*/ |
61
|
|
|
private $containerBuilder; |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* @var DispatchingDataValueFormatter |
65
|
|
|
*/ |
66
|
|
|
private $dispatchingDataValueFormatter = null; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* @since 2.5 |
70
|
|
|
*/ |
71
|
|
|
public function __construct( ContainerBuilder $containerBuilder ) { |
72
|
|
|
$this->containerBuilder = $containerBuilder; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* @since 2.5 |
77
|
|
|
* |
78
|
|
|
* @param DataValue $dataValue |
79
|
|
|
* |
80
|
|
|
* @return InfoLinksProvider |
81
|
|
|
*/ |
82
|
|
|
public function newInfoLinksProvider( DataValue $dataValue ) { |
83
|
|
|
return new InfoLinksProvider( $dataValue ); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Imported functions registered with DataTypeRegistry::registerExtraneousFunction |
88
|
|
|
* |
89
|
|
|
* @since 2.5 |
90
|
|
|
* |
91
|
|
|
* @param array $extraneousFunctions |
92
|
|
|
*/ |
93
|
|
|
public function importExtraneousFunctions( array $extraneousFunctions ) { |
94
|
|
|
foreach ( $extraneousFunctions as $serviceName => $calllback ) { |
95
|
|
|
$this->containerBuilder->registerCallback( self::TYPE_EXT_FUNCTION . $serviceName, $calllback ); |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* @since 2.5 |
101
|
|
|
* |
102
|
|
|
* @param string $serviceName |
103
|
|
|
* |
104
|
|
|
* @return mixed |
105
|
|
|
*/ |
106
|
|
|
public function newExtraneousFunctionByName( $serviceName, array $parameters = array() ) { |
107
|
|
|
return $this->containerBuilder->create( self::TYPE_EXT_FUNCTION . $serviceName, $parameters ); |
|
|
|
|
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* @since 2.5 |
112
|
|
|
* |
113
|
|
|
* @param string $typeId |
114
|
|
|
* @param string $class |
115
|
|
|
* |
116
|
|
|
* @return DataValue |
117
|
|
|
*/ |
118
|
|
|
public function newDataValueByType( $typeId, $class ) { |
119
|
|
|
|
120
|
|
|
if ( $this->containerBuilder->isRegistered( self::TYPE_INSTANCE . $typeId ) ) { |
121
|
|
|
return $this->containerBuilder->create( self::TYPE_INSTANCE . $typeId, $typeId ); |
|
|
|
|
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
// Legacy invocation, for those that have not been defined yet!s |
125
|
|
|
return new $class( $typeId ); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @since 2.5 |
130
|
|
|
* |
131
|
|
|
* @param DataValue $dataValue |
132
|
|
|
* |
133
|
|
|
* @return ValueParser |
134
|
|
|
*/ |
135
|
|
|
public function getValueParser( DataValue $dataValue ) { |
136
|
|
|
return $this->containerBuilder->singleton( self::TYPE_PARSER . $dataValue->getTypeID() ); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* @since 2.5 |
141
|
|
|
* |
142
|
|
|
* @param DataValue $dataValue |
143
|
|
|
* |
144
|
|
|
* @return ValueFormatter |
145
|
|
|
*/ |
146
|
|
|
public function getValueFormatter( DataValue $dataValue ) { |
147
|
|
|
|
148
|
|
|
$id = self::TYPE_FORMATTER . $dataValue->getTypeID(); |
149
|
|
|
|
150
|
|
|
if ( $this->containerBuilder->isRegistered( $id ) ) { |
151
|
|
|
$dataValueFormatter = $this->containerBuilder->singleton( $id ); |
152
|
|
|
} else { |
153
|
|
|
$dataValueFormatter = $this->getDispatchableValueFormatter( $dataValue ); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
$dataValueFormatter->setDataValue( |
157
|
|
|
$dataValue |
158
|
|
|
); |
159
|
|
|
|
160
|
|
|
return $dataValueFormatter; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* @since 2.5 |
165
|
|
|
* |
166
|
|
|
* @return ConstraintValueValidator |
167
|
|
|
*/ |
168
|
|
|
public function getConstraintValueValidator() { |
169
|
|
|
return $this->containerBuilder->singleton( self::TYPE_VALIDATOR . 'CompoundConstraintValueValidator' ); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* @since 2.5 |
174
|
|
|
* |
175
|
|
|
* @return PropertySpecificationLookup |
176
|
|
|
*/ |
177
|
|
|
public function getPropertySpecificationLookup() { |
178
|
|
|
return $this->containerBuilder->singleton( 'PropertySpecificationLookup' ); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
private function getDispatchableValueFormatter( $dataValue ) { |
182
|
|
|
|
183
|
|
|
if ( $this->dispatchingDataValueFormatter === null ) { |
184
|
|
|
$this->dispatchingDataValueFormatter = $this->newDispatchingDataValueFormatter(); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
return $this->dispatchingDataValueFormatter->getDataValueFormatterFor( $dataValue ); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
private function newDispatchingDataValueFormatter() { |
191
|
|
|
|
192
|
|
|
$dispatchingDataValueFormatter = new DispatchingDataValueFormatter(); |
193
|
|
|
|
194
|
|
|
// To be checked only after DispatchingDataValueFormatter::addDataValueFormatter did |
195
|
|
|
// not match any previous registered DataValueFormatters |
196
|
|
|
$dispatchingDataValueFormatter->addDefaultDataValueFormatter( |
197
|
|
|
$this->containerBuilder->singleton( self::TYPE_FORMATTER . StringValue::TYPE_ID ) |
198
|
|
|
); |
199
|
|
|
|
200
|
|
|
$dispatchingDataValueFormatter->addDefaultDataValueFormatter( |
201
|
|
|
$this->containerBuilder->singleton( self::TYPE_FORMATTER . NumberValue::TYPE_ID ) |
202
|
|
|
); |
203
|
|
|
|
204
|
|
|
$dispatchingDataValueFormatter->addDefaultDataValueFormatter( |
205
|
|
|
$this->containerBuilder->singleton( self::TYPE_FORMATTER . TimeValue::TYPE_ID ) |
206
|
|
|
); |
207
|
|
|
|
208
|
|
|
$dispatchingDataValueFormatter->addDefaultDataValueFormatter( new NoValueFormatter() ); |
209
|
|
|
|
210
|
|
|
return $dispatchingDataValueFormatter; |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
} |
214
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.