These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace SRF; |
||
4 | |||
5 | use File; |
||
6 | use FormatJson; |
||
7 | use Html; |
||
8 | use Skin; |
||
9 | use SMW\ResultPrinter; |
||
10 | use SMWDataItem; |
||
11 | use SMWDataValue; |
||
12 | use SMWOutputs; |
||
13 | use SMWQueryResult; |
||
14 | use SRFUtils; |
||
15 | use Title; |
||
16 | |||
17 | /** |
||
18 | * HTML5 Audio / Video media query printer |
||
19 | * |
||
20 | * This printer integrates jPlayer which is a HTML5 Audio / Video |
||
21 | * Javascript libray under GPL/MIT license. |
||
22 | * |
||
23 | * @see http://www.semantic-mediawiki.org/wiki/Help:Media_format |
||
24 | * |
||
25 | * @since 1.9 |
||
26 | * |
||
27 | * @file |
||
28 | * @ingroup SRF |
||
29 | * @ingroup QueryPrinter |
||
30 | * |
||
31 | * @licence GNU GPL v2 or later |
||
32 | * @author mwjames |
||
33 | */ |
||
34 | |||
35 | /** |
||
36 | * This printer integrates jPlayer which is a HTML5 Audio / Video |
||
37 | * Javascript libray under GPL/MIT license. |
||
38 | * |
||
39 | * @ingroup SRF |
||
40 | * @ingroup QueryPrinter |
||
41 | */ |
||
42 | class MediaPlayer extends ResultPrinter { |
||
43 | |||
44 | /** |
||
45 | * Specifies valid mime types supported by jPlayer |
||
46 | * |
||
47 | * @var array |
||
48 | */ |
||
49 | protected $validMimeTypes = [ 'mp3', 'mp4', 'webm', 'webma', 'webmv', 'ogg', 'oga', 'ogv', 'm4v', 'm4a' ]; |
||
50 | |||
51 | /** |
||
52 | * @see SMWResultPrinter::getName |
||
53 | * @return string |
||
54 | */ |
||
55 | public function getName() { |
||
56 | return $this->msg( 'srf-printername-media' )->text(); |
||
57 | } |
||
58 | |||
59 | /** |
||
60 | * @see SMWResultPrinter::getResultText |
||
61 | * |
||
62 | * @param SMWQueryResult $result |
||
63 | * @param $outputMode |
||
64 | * |
||
65 | * @return string |
||
66 | */ |
||
67 | protected function getResultText( SMWQueryResult $result, $outputMode ) { |
||
68 | |||
69 | // Data processing |
||
70 | $data = $this->getResultData( $result, $outputMode ); |
||
71 | |||
72 | // Check if the data processing returned any results otherwise just bailout |
||
73 | if ( $data === [] ) { |
||
74 | if ( $this->params['default'] !== '' ) { |
||
75 | return $this->params['default']; |
||
76 | } else { |
||
77 | $result->addErrors( [ $this->msg( 'srf-no-results' )->inContentLanguage()->text() ] ); |
||
78 | return ''; |
||
79 | } |
||
80 | } else { |
||
81 | // Return formatted results |
||
82 | return $this->getFormatOutput( $data ); |
||
83 | } |
||
84 | } |
||
85 | |||
86 | /** |
||
87 | * Returns an array with data |
||
88 | * |
||
89 | * @since 1.9 |
||
90 | * |
||
91 | * @param SMWQueryResult $result |
||
92 | * @param $outputMode |
||
93 | * |
||
94 | * @return array |
||
95 | */ |
||
96 | protected function getResultData( SMWQueryResult $result, $outputMode ) { |
||
97 | |||
98 | $data = []; |
||
99 | |||
100 | /** |
||
101 | * Get all values for all rows that belong to the result set |
||
102 | * |
||
103 | * @var SMWResultArray $rows |
||
104 | */ |
||
105 | while ( $rows = $result->getNext() ) { |
||
106 | $rowData = []; |
||
107 | $mediaType = null; |
||
108 | $mimeType = null; |
||
109 | |||
110 | /** |
||
111 | * @var SMWResultArray $field |
||
112 | * @var SMWDataValue $dataValue |
||
113 | */ |
||
114 | foreach ( $rows as $field ) { |
||
115 | |||
116 | // Label for the current property |
||
117 | $propertyLabel = $field->getPrintRequest()->getLabel(); |
||
118 | |||
119 | // Label for the current subject |
||
120 | $subjectLabel = $field->getResultSubject()->getTitle()->getFullText(); |
||
121 | |||
122 | if ( $propertyLabel === '' || $propertyLabel === '-' ) { |
||
123 | $propertyLabel = 'subject'; |
||
124 | } elseif ( $propertyLabel === 'poster' ) { |
||
0 ignored issues
–
show
|
|||
125 | // Label "poster" is a special case where we set the media type to video in order |
||
126 | // to use the same resources that can display video and cover art |
||
127 | // $data['mediaTypes'][] = 'video'; |
||
128 | } |
||
129 | |||
130 | // Check if the subject itself is a media source |
||
131 | if ( $field->getResultSubject()->getTitle()->getNamespace() === NS_FILE && $mimeType === null ) { |
||
132 | list( $mediaType, $mimeType, $source ) = $this->getMediaSource( |
||
133 | $field->getResultSubject()->getTitle() |
||
134 | ); |
||
135 | $rowData[$mimeType] = $source; |
||
136 | } |
||
137 | |||
138 | while ( ( $dataValue = $field->getNextDataValue() ) !== false ) { |
||
139 | // Get other data value item details |
||
140 | $value = $this->getDataValueItem( |
||
141 | $propertyLabel, |
||
142 | $dataValue->getDataItem()->getDIType(), |
||
143 | $dataValue, |
||
144 | $mediaType, |
||
145 | $mimeType, |
||
146 | $rowData |
||
147 | ); |
||
148 | $rowData[$propertyLabel] = $value; |
||
149 | } |
||
150 | } |
||
151 | |||
152 | // Only select relevant source data that match the validMimeTypes |
||
153 | if ( $mimeType !== '' && in_array( $mimeType, $this->validMimeTypes ) ) { |
||
154 | $data['mimeTypes'][] = $mimeType; |
||
155 | $data['mediaTypes'][] = $mediaType; |
||
156 | $data[$subjectLabel] = $rowData; |
||
0 ignored issues
–
show
The variable
$subjectLabel does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
Loading history...
|
|||
157 | } |
||
158 | } |
||
159 | |||
160 | return $data; |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Returns media source information |
||
165 | * |
||
166 | * @since 1.9 |
||
167 | * |
||
168 | * @param Title $title |
||
169 | */ |
||
170 | private function getMediaSource( Title $title ) { |
||
171 | |||
172 | // Find the file source |
||
173 | $source = wfFindFile( $title ); |
||
174 | if ( $source ) { |
||
175 | // $source->getExtension() returns ogg even though it is a ogv/oga (same goes for m4p) file |
||
176 | // this doesn't help much therefore we do it ourselves |
||
177 | $extension = $source->getExtension(); |
||
178 | |||
179 | if ( in_array( $extension, [ 'ogg', 'oga', 'ogv' ] ) ) { |
||
180 | $extension = strtolower( substr( $source->getName(), strrpos( $source->getName(), '.' ) + 1 ) ); |
||
181 | |||
182 | // Xiph.Org recommends that .ogg only be used for Ogg Vorbis audio files |
||
183 | $extension = $extension === 'ogg' ? 'oga' : $extension; |
||
184 | |||
185 | $params = [ $extension === 'ogv' ? 'video' : 'audio', $extension, $source->getUrl() ]; |
||
186 | } elseif ( in_array( $extension, [ 'm4v', 'm4a', 'm4p' ] ) ) { |
||
187 | $params = [ $extension === 'm4v' ? 'video' : 'audio', $extension, $source->getUrl() ]; |
||
188 | } else { |
||
189 | list( $major, $minor ) = File::splitMime( $source->getMimeType() ); |
||
0 ignored issues
–
show
The assignment to
$minor is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
Loading history...
|
|||
190 | $params = [ $major, $extension, $source->getUrl() ]; |
||
191 | } |
||
192 | } else { |
||
193 | $params = []; |
||
194 | } |
||
195 | return $params; |
||
196 | } |
||
197 | |||
198 | /** |
||
199 | * Returns single data value item |
||
200 | * |
||
201 | * @since 1.9 |
||
202 | * |
||
203 | * @param string $label |
||
204 | * @param integer $type |
||
205 | * @param SMWDataValue $dataValue |
||
206 | * @param string $mediaType |
||
207 | * @param string $mimeType |
||
208 | * |
||
209 | * @return mixed |
||
210 | */ |
||
211 | private function getDataValueItem( &$label, $type, SMWDataValue $dataValue, &$mediaType, &$mimeType, &$rowData ) { |
||
212 | |||
213 | if ( $type == SMWDataItem::TYPE_WIKIPAGE && $dataValue->getTitle()->getNamespace() === NS_FILE ) { |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
SMWDataValue as the method getTitle() does only exist in the following sub-classes of SMWDataValue : SMWWikiPageValue . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
214 | |||
215 | if ( $label === 'source' && $mimeType === null ) { |
||
216 | |||
217 | // Identify the media source |
||
218 | // and get media information |
||
219 | list( $mediaType, $mimeType, $source ) = $this->getMediaSource( $dataValue->getTitle() ); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
SMWDataValue as the method getTitle() does only exist in the following sub-classes of SMWDataValue : SMWWikiPageValue . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
220 | $label = $mimeType; |
||
221 | return $source; |
||
222 | } elseif ( $label === 'poster' ) { |
||
223 | $mediaType = 'video'; |
||
224 | |||
225 | // Get the cover art image url |
||
226 | $source = wfFindFile( $dataValue->getTitle() ); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
SMWDataValue as the method getTitle() does only exist in the following sub-classes of SMWDataValue : SMWWikiPageValue . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
227 | return $source->getUrl(); |
||
228 | } |
||
229 | } |
||
230 | |||
231 | if ( $type == SMWDataItem::TYPE_URI ) { |
||
232 | |||
233 | $source = $dataValue->getDataItem()->getURI(); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
SMWDataItem as the method getURI() does only exist in the following sub-classes of SMWDataItem : SMWDIUri . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
Loading history...
|
|||
234 | $mimeType = ''; |
||
235 | |||
236 | // Get file extension from the URI |
||
237 | $extension = strtolower( substr( $source, strrpos( $source, '.' ) + 1 ) ); |
||
238 | |||
239 | // Xiph.Org recommends that .ogg only be used for Ogg Vorbis audio files |
||
240 | if ( in_array( $extension, [ 'ogg', 'oga', 'ogv' ] ) ) { |
||
241 | $mimeType = $extension === 'ogg' ? 'oga' : $extension; |
||
242 | $mediaType = $extension === 'ogv' ? 'video' : 'audio'; |
||
243 | } elseif ( in_array( $extension, [ 'm4v', 'm4a', 'm4p' ] ) ) { |
||
244 | $mimeType = $extension; |
||
245 | $mediaType = $extension === 'm4v' ? 'video' : 'audio'; |
||
246 | } else { |
||
247 | $mimeType = $extension; |
||
248 | $mediaType = strpos( $extension, 'v' ) !== false ? 'video' : 'audio'; |
||
249 | } |
||
250 | |||
251 | if ( $mimeType !== '' ) { |
||
252 | $rowData[$mimeType] = $source; |
||
253 | } |
||
254 | |||
255 | return $source; |
||
256 | } |
||
257 | |||
258 | return $dataValue->getWikiValue(); |
||
259 | } |
||
260 | |||
261 | /** |
||
262 | * Prepare data for the output |
||
263 | * |
||
264 | * @since 1.9 |
||
265 | * |
||
266 | * @param array $data |
||
267 | * |
||
268 | * @return string |
||
269 | */ |
||
270 | protected function getFormatOutput( $data ) { |
||
271 | |||
272 | $ID = 'srf-' . uniqid(); |
||
273 | $this->isHTML = true; |
||
274 | |||
275 | // Get the media/mime types |
||
276 | if ( in_array( 'video', $data['mediaTypes'] ) ) { |
||
277 | $mediaType = 'video'; |
||
278 | } else { |
||
279 | $mediaType = 'audio'; |
||
280 | } |
||
281 | unset( $data['mediaTypes'] ); |
||
282 | |||
283 | $mimeTypes = array_unique( $data['mimeTypes'] ); |
||
284 | unset( $data['mimeTypes'] ); |
||
285 | |||
286 | // Reassign output array |
||
287 | $output = [ |
||
288 | 'data' => $data, |
||
289 | 'count' => count( $data ), |
||
290 | 'mediaType' => $mediaType, |
||
291 | 'mimeTypes' => implode( ',', $mimeTypes ), |
||
292 | 'inspector' => $this->params['inspector'] |
||
293 | ]; |
||
294 | |||
295 | $requireHeadItem = [ $ID => FormatJson::encode( $output ) ]; |
||
296 | SMWOutputs::requireHeadItem( $ID, Skin::makeVariablesScript( $requireHeadItem ) ); |
||
297 | |||
298 | SMWOutputs::requireResource( 'ext.jquery.jplayer.skin.' . $this->params['theme'] ); |
||
299 | SMWOutputs::requireResource( 'ext.srf.formats.media' ); |
||
300 | |||
301 | $processing = SRFUtils::htmlProcessingElement(); |
||
302 | |||
303 | return Html::rawElement( |
||
304 | 'div', |
||
305 | [ |
||
306 | 'class' => $this->params['class'] !== '' ? 'srf-media ' . $this->params['class'] : 'srf-media' |
||
307 | ], |
||
308 | $processing . Html::element( |
||
309 | 'div', |
||
310 | [ |
||
311 | 'id' => $ID, |
||
312 | 'class' => 'media-container', |
||
313 | 'style' => 'display:none;' |
||
314 | ], |
||
315 | null |
||
316 | ) |
||
317 | ); |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * @see SMWResultPrinter::getParamDefinitions |
||
322 | * |
||
323 | * @since 1.9 |
||
324 | * |
||
325 | * @param $definitions array of IParamDefinition |
||
326 | * |
||
327 | * @return array of IParamDefinition|array |
||
328 | */ |
||
329 | public function getParamDefinitions( array $definitions ) { |
||
330 | $params = parent::getParamDefinitions( $definitions ); |
||
331 | |||
332 | $params['class'] = [ |
||
333 | 'message' => 'srf-paramdesc-class', |
||
334 | 'default' => '', |
||
335 | ]; |
||
336 | |||
337 | $params['theme'] = [ |
||
338 | 'message' => 'srf-paramdesc-theme', |
||
339 | 'default' => 'blue.monday', |
||
340 | 'values' => [ 'blue.monday', 'morning.light' ], |
||
341 | ]; |
||
342 | |||
343 | $params['inspector'] = [ |
||
344 | 'type' => 'boolean', |
||
345 | 'message' => 'srf-paramdesc-mediainspector', |
||
346 | 'default' => false, |
||
347 | ]; |
||
348 | |||
349 | return $params; |
||
350 | } |
||
351 | } |
||
352 |
This check looks for the bodies of
elseif
statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
elseif
bodies can be removed. If you have an empty elseif but statements in theelse
branch, consider inverting the condition.