Issues (165)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

Includes/Image.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
class Image {
4
5
	/**
6
	 * Wiki class
7
	 *
8
	 * @var Wiki
9
	 * @access protected
10
	 */
11
	protected $wiki;
12
13
	/**
14
	 * Page class
15
	 *
16
	 * @var Page
17
	 * @access protected
18
	 */
19
	protected $page;
20
21
	/**
22
	 * MIME type of image
23
	 *
24
	 * @var string
25
	 * @access protected
26
	 */
27
	protected $mime;
28
29
	/**
30
	 * Bitdepth of image
31
	 *
32
	 * @var int
33
	 * @access protected
34
	 */
35
	protected $bitdepth;
36
37
	/**
38
	 * SHA1 hash of image
39
	 *
40
	 * @var string
41
	 * @access protected
42
	 */
43
	protected $hash;
44
45
	/**
46
	 * Size of image
47
	 *
48
	 * @var int
49
	 * @access protected
50
	 */
51
	protected $size;
52
53
	/**
54
	 * Metadata stored in the image
55
	 *
56
	 * @var array
57
	 * @access protected
58
	 */
59
	protected $metadata = array();
60
61
	/**
62
	 * URL to direct image
63
	 *
64
	 * @var string
65
	 * @access protected
66
	 */
67
	protected $url;
68
69
	/**
70
	 * Timestamp that of the most recent upload
71
	 *
72
	 * @var string
73
	 * @access protected
74
	 */
75
	protected $timestamp;
76
77
	/**
78
	 * Username of the most recent uploader
79
	 *
80
	 * @var string
81
	 * @access protected
82
	 */
83
	protected $user;
84
85
	/**
86
	 * Width of image
87
	 *
88
	 * @var int
89
	 * @access protected
90
	 */
91
	protected $width;
92
93
	/**
94
	 * Height of image
95
	 *
96
	 * @var int
97
	 * @access protected
98
	 */
99
	protected $height;
100
101
	/**
102
	 * Sanitized name for local storage (namespace, colons, etc all removed)
103
	 *
104
	 * @var string
105
	 * @access protected
106
	 */
107
	protected $localname;
108
109
	/**
110
	 * Image name, with namespace
111
	 *
112
	 * @var string
113
	 * @access protected
114
	 */
115
	protected $title;
116
117
	/**
118
	 * Image name, without namespace
119
	 *
120
	 * @var string
121
	 * @access protected
122
	 */
123
	protected $rawtitle;
124
125
	/**
126
	 * List of pages where the image is used
127
	 *
128
	 * @var array
129
	 * @access protected
130
	 */
131
	protected $usage = array();
132
133
	/**
134
	 * List of previous uploads
135
	 *
136
	 * @var array
137
	 * @access protected
138
	 */
139
	protected $history = array();
140
141
	/**
142
	 * Other images with identical SHA1 hashes
143
	 *
144
	 * @var array
145
	 * @access protected
146
	 */
147
	protected $duplicates = array();
148
149
	/**
150
	 * Whether image itself exists or not
151
	 *
152
	 * @var bool
153
	 * @access protected
154
	 */
155
	protected $exists = true;
156
157
	/**
158
	 * Construction method for the Image class
159
	 *
160
	 * @access public
161
	 * @param Wiki &$wikiClass The Wiki class object
162
	 * @param string $title The title of the image
163
	 * @param int $pageid The ID of the image page (optional)
164
	 * @return Image
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
165
	 */
166
	public function __construct( Wiki &$wikiClass, $title = null, $pageid = null ) {
167
168
		$this->wiki = & $wikiClass;
169
		$this->title = $title;
170
171
		if( $this->wiki->removeNamespace( $title ) == $title ) {
172
			$namespaces = $this->wiki->get_namespaces();
173
			$this->title = $namespaces[6] . ':' . $title;
174
		}
175
176
		$ii = $this->imageinfo();
177
178
		if( is_array( $ii ) ) {
179
			$ii = $ii[0];
180
181
			$this->title = $ii['canonicaltitle'];
182
			$this->rawtitle = $this->wiki->removeNamespace( $this->title );
183
			$this->localname = str_replace( array( ' ', '+' ), array( '_', '_' ), urlencode( $this->rawtitle ) );
184
			$this->page = & $this->wiki->initPage( $this->title, $pageid );
185
			$this->mime = $ii['mime'];
186
			$this->bitdepth = $ii['bitdepth'];
187
			$this->hash = $ii['sha1'];
188
			$this->size = $ii['size'];
189
			$this->width = $ii['width'];
190
			$this->height = $ii['height'];
191
			$this->url = $ii['url'];
192
			$this->timestamp = $ii['timestamp'];
193
			$this->user = $ii['user'];
194
195
			if( is_array( $ii['metadata'] ) ) {
196
				foreach( $ii['metadata'] as $metadata ){
197
					$this->metadata[$metadata['name']] = $metadata['value'];
198
				}
199
200
        		}
201
                } else {
202
                        $this->exists = false;
203
		}
204
205
	}
206
207
	/**
208
	 *
209
	 * @access public
210
	 * @link https://www.mediawiki.org/wiki/API:Properties#imageinfo_.2F_ii
211
	 * @param int $limit Number of results to limit to. Default 50.
212
	 * @param array $prop What image information to get.  Default all values.
213
	 * @return array|bool False if not found, otherwise array of info indexed by revision
214
	 */
215
	public function get_stashinfo( $limit = 50, $prop = array(
216
        'timestamp', 'user', 'comment', 'url', 'size', 'dimensions', 'sha1', 'mime', 'metadata', 'archivename',
217
        'bitdepth'
218
    ) ) {
219
220
		$stasharray = array(
221
			'prop'     => 'stashimageinfo',
222
			'siiprop'  => implode( '|', $prop ),
223
			'titles'   => $this->title,
224
			'_code'    => 'sii',
225
			'_limit'   => $limit,
226
			'_lhtitle' => 'stashimageinfo'
227
		);
228
229
		$stashinfo = $this->wiki->listHandler( $stasharray );
230
		if( is_array( $stashinfo ) ) {
231
			return $stashinfo[0];
232
		} else {
233
			return false;
234
		}
235
	}
236
237
	/**
238
	 * Returns various information about the image
239
	 *
240
	 * @access public
241
	 * @param int $limit Number of revisions to get info about. Default 1
242
	 * @param int $width Width of image. Default -1 (no width)
243
	 * @param int $height Height of image. Default -1 (no height)
244
	 * @param string $start Timestamp to start at. Default null
245
	 * @param string $end Timestamp to end at. Default null
246
	 * @param string[] $prop Properties to retrieve. Default array( 'timestamp', 'user', 'comment', 'url', 'size', 'sha1', 'mime', 'metadata', 'archivename', 'bitdepth' )
247
	 * @param string $version Version of metadata to use. Default 'latest'
248
	 * @param string $urlparam A handler specific parameter string. Default null
249
	 * @param bool $localonly Look only for files in the local repository. Default false
250
	 * @return array|bool False if file does not exist, otherwise array of info indexed by revision
251
	 */
252
	public function imageinfo( $limit = 1, $width = -1, $height = -1, $start = null, $end = null, $prop = array(
253
		'canonicaltitle', 'timestamp', 'userid', 'user', 'comment', 'parsedcomment', 'url', 'size', 'dimensions', 'sha1', 'mime',
254
		'thumbmime', 'mediatype', 'metadata', 'archivename', 'bitdepth'
255
	), $version = 'latest', $urlparam = null, $localonly = false ) {
256
257
		$imageInfoArray = array(
258
			'prop'              => 'imageinfo',
259
			'_code'             => 'ii',
260
			'_limit'            => $limit,
261
			'iiprop'            => implode( '|', $prop ),
262
			'iiurlwidth'        => $width,
263
			'iiurlheight'       => $height,
264
			'titles'            => $this->title,
265
			'iimetadataversion' => $version,
266
			'_lhtitle'          => 'imageinfo'
267
		);
268
269
		if( !is_null( $start ) ) $imageInfoArray['iistart'] = $start;
270
		if( !is_null( $end ) ) $imageInfoArray['iiend'] = $end;
271
		if( !is_null( $urlparam ) ) $imageInfoArray['iiurlparam'] = $urlparam;
272
		if( $localonly ) $imageInfoArray['iilocalonly'] = 'yes';
273
274
		pecho( "Getting image info for {$this->title}...\n\n", PECHO_NORMAL );
275
276
		$imageInfo = $this->wiki->listHandler( $imageInfoArray );
277
		if( count( $imageInfo ) > 0 ) {
278
			return $imageInfo;
279
		} else {
280
			// Does not exist
281
			return false;
282
		}
283
	}
284
285
	/**
286
	 * Returns the upload history of the image. If function was already called earlier in the script, it will return the local cache unless $force is set to true.
287
	 *
288
	 * @access public
289
	 * @param string $dir Which direction to go. Default 'older'
290
	 * @param int $limit Number of revisions to get. Default null (all revisions)
291
	 * @param bool $force Force generation of the cache. Default false (use cache).
292
	 * @return array Upload history.
293
	 */
294
	public function get_history( $dir = 'older', $limit = null, $force = false ) {
295
		if( !count( $this->history ) || $force ) {
296
			$this->history = $this->page->history( $limit, $dir );
297
		}
298
		return $this->history;
299
	}
300
301
	/**
302
	 * Returns all pages where the image is used. If function was already called earlier in the script, it will return the local cache unless $force is set to true.
303
	 *
304
	 * @access public
305
	 * @param string|array $namespace Namespaces to look in. If set as a string, must be set in the syntax "0|1|2|...". If an array, simply the namespace IDs to look in. Default null.
306
	 * @param string $redirects How to filter for redirects. Options are "all", "redirects", or "nonredirects". Default "all".
307
	 * @param bool $followRedir If linking page is a redirect, find all pages that link to that redirect as well. Default false.
308
	 * @param int|null $limit
309
	 * @param bool $force Force regeneration of the cache. Default false (use cache).
310
	 * @return array
311
	 */
312
	public function get_usage( $namespace = null, $redirects = "all", $followRedir = false, $limit = null, $force = false ) {
313
314
		if( $force || !count( $this->usage ) ) {
315
316
			$iuArray = array(
317
				'list'          => 'imageusage',
318
				'_code'         => 'iu',
319
				'_lhtitle'      => 'title',
320
				'iutitle'       => $this->title,
321
				'iufilterredir' => $redirects,
322
			);
323
324
			if( !is_null( $namespace ) ) {
325
326
				if( is_array( $namespace ) ) {
327
					$namespace = implode( '|', $namespace );
328
				}
329
				$iuArray['iunamespace'] = $namespace;
330
			}
331
332
			if( !is_null( $limit ) ) $iuArray['iulimit'] = $limit;
333
334
			if( $followRedir ) $iuArray['iuredirect'] = 'yes';
335
336
			pecho( "Getting image usage for {$this->title}..\n\n", PECHO_NORMAL );
337
338
			$this->usage = $this->wiki->listHandler( $iuArray );
339
340
		}
341
342
		return $this->usage;
343
	}
344
345
	/**
346
	 * Returns an array of all files with identical sha1 hashes
347
	 *
348
	 * @param int $limit Number of duplicates to get. Default null (all)
349
	 * @param bool $force Force regeneration of the cache. Default false (use cache).
350
	 * @return array Duplicate files
351
	 */
352
	public function get_duplicates( $limit = null, $force = false ) {
353
354
		if( $force || !count( $this->duplicates ) ) {
355
356
			if( !$this->get_exists() ) {
357
				return $this->duplicates;
358
			}
359
360
			$dArray = array(
361
				'action'  => 'query',
362
				'prop'    => 'duplicatefiles',
363
				'dflimit' => ( ( is_null( $limit ) ? $this->wiki->get_api_limit() + 1 : $limit ) ),
364
				'titles'  => $this->title
365
			);
366
367
			$continue = null;
368
369
			pecho( "Getting duplicate images of {$this->title}..\n\n", PECHO_NORMAL );
370
371
			while( 1 ){
372
				if( !is_null( $continue ) ) $dArray['dfcontinue'] = $continue;
373
374
				$dRes = $this->wiki->apiQuery( $dArray );
375
376
				foreach( $dRes['query']['pages'] as $x ){
377
					if( isset( $x['duplicatefiles'] ) ) {
378
						foreach( $x['duplicatefiles'] as $y ){
379
							$this->duplicates[] = $y['name'];
380
						}
381
					}
382
				}
383
384
				if( isset( $dRes['query-continue'] ) ) {
385
					foreach( $dRes['query-continue'] as $z ){
386
						$continue = $z['dfcontinue'];
387
					}
388
				} else {
389
					break;
390
				}
391
392
393
			}
394
395
		}
396
397
		return $this->duplicates;
398
	}
399
400
	/**
401
	 * Revert a file to an old version
402
	 *
403
	 * @access public
404
	 * @param string $comment Comment for inthe upload in logs (default: '')
405
	 * @param string $revertto Archive name of the revision to revert to.  Default null.
406
	 * @return boolean
407
	 */
408
	public function revert( $comment = '', $revertto = null ) {
409
		global $pgNotag, $pgTag;
410
		$tokens = $this->wiki->get_tokens();
411
412
		if( !$pgNotag ) $comment .= $pgTag;
413
		$apiArray = array(
414
			'action'   => 'filerevert',
415
			'token'    => $tokens['edit'],
416
			'comment'  => $comment,
417
			'filename' => $this->rawtitle
418
		);
419
420
		if( !is_null( $revertto ) ) {
421
			$apiArray['archivename'] = $revertto;
422
			pecho( "Reverting to $revertto" . "...\n\n", PECHO_NOTICE );
423
		} else {
424
			$ii = $this->imageinfo( 2, -1, -1, null, null, array( 'archivename' ) );
425
			if( is_array( $ii ) ) $apiArray['archivename'] = $ii[1]['archivename'];
426
			pecho( "Reverting to prior upload...\n\n", PECHO_NOTICE );
427
		}
428
429
		try{
430
			$this->preEditChecks( "Revert" );
431
		} catch( EditError $e ){
432
			pecho( "Error: $e\n\n", PECHO_FATAL );
433
			return false;
434
		}
435
436
		$result = $this->wiki->apiQuery( $apiArray, true );
437
438
		if( isset( $result['filerevert'] ) ) {
439
			if( isset( $result['filerevert']['result'] ) && $result['filerevert']['result'] == "Success" ) {
440
				$this->__construct( $this->wiki, $this->title );
441
				return true;
442
			} else {
443
				pecho( "Revert error...\n\n" . print_r( $result['filerevert'], true ) . "\n\n", PECHO_FATAL );
444
				return false;
445
			}
446
		} else {
447
			pecho( "Revert error...\n\n" . print_r( $result, true ), PECHO_FATAL );
448
			return false;
449
		}
450
	}
451
452
	/**
453
	 * Rotate the image clockwise a certain degree.
454
	 *
455
	 * @param integer $degree Degrees to rotate image clockwise
456
	 * @return boolean
457
	 */
458
	public function rotate( $degree = 90 ) {
459
		$tokens = $this->wiki->get_tokens();
460
461
		$apiArray = array(
462
			'action' => 'imagerotate',
463
			'token'  => $tokens['edit'],
464
			'titles' => $this->title
465
		);
466
		pecho( "Rotating image(s) $degree degrees...\n\n", PECHO_NOTICE );
467
468
		try{
469
			$this->preEditChecks( "Rotate" );
470
		} catch( EditError $e ){
471
			pecho( "Error: $e\n\n", PECHO_FATAL );
472
			return false;
473
		}
474
475
		$result = $this->wiki->apiQuery( $apiArray, true );
476
477
		if( isset( $result['imagerotate'] ) ) {
478
			if( isset( $result['imagerotate']['result'] ) && $result['imagerotate']['result'] == "Success" ) {
479
				$this->__construct( $this->wiki, $this->title );
480
				return true;
481
			} else {
482
				pecho( "Rotate error...\n\n" . print_r( $result['imagerotate'], true ) . "\n\n", PECHO_FATAL );
483
				return false;
484
			}
485
		} else {
486
			pecho( "Rotate error...\n\n" . print_r( $result, true ), PECHO_FATAL );
487
			return false;
488
		}
489
	}
490
491
	/**
492
	 * Upload an image to the wiki
493
	 *
494
	 * @access public
495
	 * @param string $file Identifier of a file. Flexible format (local path, URL)
496
	 * @param string $text Text on the image file page (default: '')
497
	 * @param string $comment Comment for inthe upload in logs (default: '')
498
	 * @param bool $watch Should the upload be added to the watchlist (default: false)
499
	 * @param bool $ignorewarnings Ignore warnings about the upload (default: true)
500
	 * @param bool $async Make potentially large file operations asynchronous when possible.  Default false.
501
	 * @throws BadEntryError
502
	 * @return boolean
503
	 */
504
	public function upload( $file, $text = '', $comment = '', $watch = null, $ignorewarnings = true, $async = false ) {
505
		global $pgIP, $pgNotag, $pgTag;
506
507
		if( !$pgNotag ) $comment .= $pgTag;
508
		if( !is_array( $file ) ) {
509
			if( !preg_match( '@((http(s)?:\/\/)?([-\w]+\.[-\w\.]+)+\w(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)*)@', $file ) ) {
510
				if( !is_file( $file ) ) {
511
512
					if( is_file( $pgIP . 'Images/' . $file ) ) {
513
						$file = $pgIP . 'Images/' . $file;
514
					}
515
516
					if( !is_file( $file ) ) {
517
						throw new BadEntryError( "FileNotFound", "The given file, or file chunks, was not found or an invalid URL was specified." );
518
					}
519
				}
520
			}
521
			pecho( "Uploading $file to {$this->title}..\n\n", PECHO_NOTICE );
522
		} else {
523
			$i = 0;
524
			foreach( $file as $chunk ){
525
				if( !is_file( $chunk ) ) {
526
527
					if( is_file( $pgIP . 'Images/' . $chunk ) ) {
528
						$file[$i] = $pgIP . 'Images/' . $chunk;
529
					}
530
531
					if( !is_file( $file[$i] ) ) {
532
						throw new BadEntryError( "FileNotFound", "The given chunk file was not found." );
533
					}
534
				}
535
				$i++;
536
			}
537
			pecho( "Uploading chunk files to {$this->title}..\n\n", PECHO_NOTICE );
538
		}
539
540
		try{
541
			$this->preEditChecks( "Uploads" );
542
		} catch( EditError $e ){
543
			pecho( "Error: $e\n\n", PECHO_FATAL );
544
			return false;
545
		}
546
547
		return $this->api_upload( $file, $text, $comment, $watch, $ignorewarnings, $async );
548
549
	}
550
551
	/**
552
	 * Upload an image to the wiki using api.php
553
	 *
554
	 * @access public
555
	 * @param mixed $file Absolute path to the image, a URL, or an array containing file chunks for a chunk upload.
556
	 * @param string $text Text on the image file page (default: '')
557
	 * @param string $comment Comment for inthe upload in logs (default: '')
558
	 * @param bool $watch Should the upload be added to the watchlist (default: false)
559
	 * @param bool $ignorewarnings Ignore warnings about the upload (default: true)
560
	 * @param bool $async Make potentially large file operations asynchronous when possible.  Default false.
561
	 * @param string $filekey Key that identifies a previous upload that was stashed temporarily. Default null.
562
	 * @notice This feature is not yet fully developed.  Manual stashing is not allowed at this time.  This will be corrected during the final release of Peachy 2.
563
	 * @return bool
564
	 */
565
	public function api_upload( $file, $text = '', $comment = '', $watch = null, $ignorewarnings = true, $async = false, $filekey = null ) {
566
567
		$tokens = $this->wiki->get_tokens();
568
569
		$apiArr = array(
570
			'action'         => 'upload',
571
			'filename'       => $this->rawtitle,
572
			'comment'        => $comment,
573
			'text'           => $text,
574
			'token'          => $tokens['edit'],
575
			'ignorewarnings' => intval( $ignorewarnings )
576
		);
577
578
		if( !is_null( $filekey ) ) $apiArr['filekey'] = $filekey;
579
580
		if( !is_null( $watch ) ) {
581
			if( $watch ) {
582
				$apiArr['watchlist'] = 'watch';
583
			} elseif( !$watch ) $apiArr['watchlist'] = 'nochange';
584
			elseif( in_array(
585
				$watch, array(
586
					'watch', 'unwatch', 'preferences', 'nochange'
587
				)
588
			) ) {
589
				$apiArr['watchlist'] = $watch;
590
			} else pecho( "Watch parameter set incorrectly.  Omitting...\n\n", PECHO_WARN );
591
		}
592
593
		if( !is_array( $file ) ) {
594
			if( is_file( $file ) ) {
595
				if( $async ) $apiArr['async'] = 'yes';
596
				$localfile = $file;
597
				$apiArr['file'] = "@$localfile";
598
			} else {
599
				$apiArr['url'] = $file;
600
				if( $async ) {
601
					$apiArr['asyncdownload'] = 'yes';
602
					$apiArr['leavemessage'] = 'yes';
603
				}
604
			}
605
		} else {
606
			$apiArr['stash'] = 'yes';
607
			$apiArr['offset'] = 0;
608
			$apiArr['filesize'] = 0;
609
			foreach( $file as $chunk ){
610
				$apiArr['filesize'] = $apiArr['filesize'] + filesize( $chunk );
611
			}
612
			foreach( $file as $chunk ){
613
				$apiArr['chunk'] = "@$chunk";
614
				pecho( "Uploading $chunk\n\n", PECHO_NOTICE );
615
				$result = $this->wiki->apiQuery( $apiArr, true );
616
				if( isset( $result['upload']['result'] ) && $result['upload']['result'] == "Continue" ) {
617
					$apiArr['filekey'] = $result['upload']['filekey'];
618
					$apiArr['offset'] = $result['upload']['offset'];
619
				} elseif( isset( $result['upload']['result'] ) && $result['upload']['result'] == "Success" ) {
620
					$apiArr['filekey'] = $result['upload']['filekey'];
621
					unset( $apiArr['offset'] );
622
					unset( $apiArr['chunk'] );
623
					unset( $apiArr['stash'] );
624
					unset( $apiArr['filesize'] );
625
					pecho( "Chunks uploaded successfully!\n\n", PECHO_NORMAL );
626
					break;
627
				} else {
628
					pecho( "Upload error...\n\n" . print_r( $result, true ) . "\n\n", PECHO_FATAL );
629
					return false;
630
				}
631
			}
632
		}
633
634
		Hooks::runHook( 'APIUpload', array( &$apiArr ) );
635
636
		$result = $this->wiki->apiQuery( $apiArr, true );
637
638
		if( isset( $result['upload'] ) ) {
639
			if( isset( $result['upload']['result'] ) && $result['upload']['result'] == "Success" ) {
640
				$this->__construct( $this->wiki, $this->title );
641
				return true;
642
			} else {
643
				pecho( "Upload error...\n\n" . print_r( $result['upload'], true ) . "\n\n", PECHO_FATAL );
644
				return false;
645
			}
646
		} else {
647
			pecho( "Upload error...\n\n" . print_r( $result, true ), PECHO_FATAL );
648
			return false;
649
		}
650
651
	}
652
653
	/**
654
	 * Downloads an image to the local disk
655
	 *
656
	 * @param string $localname Filename to store image as. Default null.
657
	 * @param int $width Width of image to download. Default -1.
658
	 * @param int $height Height of image to download. Default -1.
659
	 * @return void
660
	 */
661
	public function download( $localname = null, $width = -1, $height = -1 ) {
662
		global $pgIP;
663
664
		if( !$this->get_exists() ) {
665
			pecho( "Attempted to download a non-existant file.", PECHO_NOTICE );
666
		}
667
668
		$ii = $this->imageinfo( 1, $width, $height );
669
670
		if( is_array( $ii ) ) {
671
			$ii = $ii[0];
672
673
			if( $width != -1 ) {
674
				$url = $ii['thumburl'];
675
			} else {
676
				$url = $ii['url'];
677
			}
678
679
			if( is_null( $localname ) ) {
680
				$localname = $pgIP . 'Images/' . $this->localname;
681
			}
682
683
			Hooks::runHook( 'DownloadImage', array( &$url, &$localname ) );
684
685
			pecho( "Downloading {$this->title} to $localname..\n\n", PECHO_NOTICE );
686
687
			$this->wiki->get_http()->download( $url, $localname );
688
		} else {
689
			pecho( "Error in getting image URL.\n\n" . print_r( $ii ) . "\n\n", PECHO_FATAL );
690
		}
691
	}
692
693
	/**
694
	 * Resize an image
695
	 *
696
	 * @access public
697
	 * @param int $width Width of resized image. Default null
698
	 * @param int $height Height of resized image. Default null.
699
	 * @param bool $reupload Whether or not to automatically upload the image again. Default false
700
	 * @param string $text Text to use for the image name
701
	 * @param string $comment Upload comment.
702
	 * @param bool $watch Whether or not to watch the image on uploading
703
	 * @param bool $ignorewarnings Whether or not to ignore upload warnings
704
	 * @throws DependencyError Relies on GD PHP plugin
705
	 * @throws BadEntryError
706
	 * @return boolean|void False on failure
707
	 */
708
	public function resize( $width = null, $height = null, $reupload = false, $text = '', $comment = '', $watch = null, $ignorewarnings = true ) {
709
		global $pgIP, $pgNotag, $pgTag;
710
711
		try{
712
			$this->preEditChecks( "Resize" );
713
		} catch( EditError $e ){
714
			pecho( "Error: $e\n\n", PECHO_FATAL );
715
			return false;
716
		}
717
718
		if( !$pgNotag ) $comment .= $pgTag;
719
		if( !function_exists( 'ImageCreateTrueColor' ) ) {
720
			throw new DependencyError( "GD", "http://us2.php.net/manual/en/book.image.php" );
0 ignored issues
show
'http://us2.php.net/manual/en/book.image.php' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
721
		}
722
		echo "1\n";
723
		if( !is_null( $width ) && !is_null( $height ) ) {
724
			$this->download();
725
726
			$type = substr( strrchr( $this->mime, '/' ), 1 );
727
728
			switch( $type ){
729
				case 'jpeg':
730
					$image_create_func = 'ImageCreateFromJPEG';
731
					$image_save_func = 'ImageJPEG';
732
					break;
733
734
				case 'png':
735
					$image_create_func = 'ImageCreateFromPNG';
736
					$image_save_func = 'ImagePNG';
737
					break;
738
739
				case 'bmp':
740
					$image_create_func = 'ImageCreateFromBMP';
741
					$image_save_func = 'ImageBMP';
742
					break;
743
744
				case 'gif':
745
					$image_create_func = 'ImageCreateFromGIF';
746
					$image_save_func = 'ImageGIF';
747
					break;
748
749
				case 'vnd.wap.wbmp':
750
					$image_create_func = 'ImageCreateFromWBMP';
751
					$image_save_func = 'ImageWBMP';
752
					break;
753
754
				case 'xbm':
755
					$image_create_func = 'ImageCreateFromXBM';
756
					$image_save_func = 'ImageXBM';
757
					break;
758
759
				default:
760
					$image_create_func = 'ImageCreateFromJPEG';
761
					$image_save_func = 'ImageJPEG';
762
			}
763
			echo "2\n";
764
			$image = imagecreatetruecolor( $width, $height );
765
			echo "3\n";
766
			$new_image = $image_create_func( $pgIP . 'Images/' . $this->localname );
767
768
			$info = getimagesize( $pgIP . 'Images/' . $this->localname );
769
770
			imagecopyresampled( $image, $new_image, 0, 0, 0, 0, $width, $height, $info[0], $info[1] );
771
772
			$image_save_func( $image, $pgIP . 'Images/' . $this->localname );
773
774
		} elseif( !is_null( $width ) ) {
775
			$this->download( null, $width );
776
		} elseif( !is_null( $height ) ) {
777
			$this->download( null, $height + 100000, $height );
778
		} else {
779
			throw new BadEntryError( "NoParams", "No parameters given" );
780
		}
781
782
		if( $reupload ) {
783
			return $this->upload( null, $text, $comment, $watch, $ignorewarnings );
784
		}
785
	}
786
787
	/**
788
	 * Returns the normalized image name
789
	 *
790
	 * @param bool $namespace Whether or not to include the File: part of the name. Default true.
791
	 * @return string
792
	 */
793
	public function get_title( $namespace = true ) {
794
		if( $namespace ) {
795
			return $this->title;
796
		} else {
797
			return $this->rawtitle;
798
		}
799
	}
800
801
	/**
802
	 * Deletes the image and page.
803
	 *
804
	 * @param string $reason A reason for the deletion. Defaults to null (blank).
805
	 * @param string|bool $watch Unconditionally add or remove the page from your watchlist, use preferences or do not change watch. Default preferences.
806
	 * @param string $oldimage The name of the old image to delete as provided by iiprop=archivename
807
	 * @return bool True on success
808
	 */
809
	public function delete( $reason = null, $watch = null, $oldimage = null ) {
810
		return $this->page->delete( $reason, $watch, $oldimage );
811
	}
812
813
	/*
814
	 * Performs new message checking, etc
815
	 *
816
	 * @access public
817
	 * @return void
818
	 */
819
	protected function preEditChecks( $action = "Edit" ) {
820
		$this->wiki->preEditChecks( $action );
821
	}
822
823
	/**
824
	 * Returns the sanitized local disk name
825
	 *
826
	 * @return string
827
	 */
828
	public function get_localname() {
829
		return $this->localname;
830
	}
831
832
	/**
833
	 * Whether or not the image exists
834
	 *
835
	 * @return bool
836
	 */
837
	public function get_exists() {
838
		return $this->exists;
839
	}
840
841
	/**
842
	 * Returns a page class for the image
843
	 *
844
	 * @return Page
845
	 */
846
	public function &get_page() {
847
		return $this->page;
848
	}
849
850
	/**
851
	 * Returns the MIME type of the image
852
	 *
853
	 * @return string
854
	 */
855
	public function get_mime() {
856
		return $this->mime;
857
	}
858
859
	/**
860
	 * Returns the bitdepth of the image
861
	 *
862
	 * @return int
863
	 */
864
	public function get_bitdepth() {
865
		return $this->bitdepth;
866
	}
867
868
	/**
869
	 * Returns the SHA1 hash of the image
870
	 *
871
	 * @return string
872
	 */
873
	public function get_hash() {
874
		return $this->hash;
875
	}
876
877
	/**
878
	 * Returns the size of the image, in bytes
879
	 *
880
	 * @return int
881
	 */
882
	public function get_size() {
883
		return $this->size;
884
	}
885
886
	/**
887
	 * Returns the metadata of the image
888
	 *
889
	 * @return array
890
	 */
891
	public function get_metadata() {
892
		return $this->metadata;
893
	}
894
895
	/**
896
	 * Returns the direct URL of the image
897
	 *
898
	 * @return string
899
	 */
900
	public function get_url() {
901
		return $this->url;
902
	}
903
904
	/**
905
	 * Returns the timestamp that of the most recent upload
906
	 *
907
	 * @return string
908
	 */
909
	public function get_timestamp() {
910
		return $this->timestamp;
911
	}
912
913
	/**
914
	 * Returns the username of the most recent uploader
915
	 *
916
	 * @return string
917
	 */
918
	public function get_user() {
919
		return $this->user;
920
	}
921
922
	/**
923
	 * Returns the width of the image
924
	 *
925
	 * @return int
926
	 */
927
	public function get_width() {
928
		return $this->width;
929
	}
930
931
	/**
932
	 * Returns the height of the image
933
	 *
934
	 * @return int
935
	 */
936
	public function get_height() {
937
		return $this->height;
938
	}
939
940
}
941