GenFunctions.php ➔ strtoupper_safe()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
This file is part of Peachy MediaWiki Bot API
5
6
Peachy is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation, either version 3 of the License, or
9
(at your option) any later version.
10
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
/**
21
 * @file
22
 * Stores general functions that do not belong in a class
23
 */
24
25
/**
26
 * Case insensitive in_array function
27
 *
28
 * @param mixed $needle What to search for
29
 * @param array $haystack Array to search in
30
 * @param bool $strict
31
 * @return bool True if $needle is found in $haystack, case insensitive
32
 * @link http://us3.php.net/in_array
33
 */
34
function iin_array( $needle, $haystack, $strict = false ) {
35
	return in_array_recursive( strtoupper_safe( $needle ), array_map( 'strtoupper_safe', $haystack ), $strict );
36
}
37
38
/**
39
 * @return string
40
 */
41
function strtoupper_safe( $str ) {
42
	if( is_string( $str ) ) return strtoupper( $str );
43
	if( is_array( $str ) ) $str = array_map( 'strtoupper_safe', $str );
44
	return $str;
45
}
46
47
/**
48
 * Returns whether or not a string is found in another
49
 * Shortcut for strpos()
50
 *
51
 * @param string $needle What to search for
52
 * @param string $haystack What to search in
53
 * @param bool $insensitive Whether or not to do a case-insensitive search
54
 * @return bool True if $needle is found in $haystack
55
 * @link http://us3.php.net/strpos
56
 */
57
function in_string( $needle, $haystack, $insensitive = false ) {
58
	$fnc = 'strpos';
59
	if( $insensitive ) $fnc = 'stripos';
60
61
	return $fnc( $haystack, $needle ) !== false;
62
}
63
64
/**
65
 * Recursive in_array function
66
 *
67
 * @param string $needle What to search for
68
 * @param array $haystack What to search in
69
 * @param bool $insensitive Whether or not to do a case-insensitive search
70
 * @return bool True if $needle is found in $haystack
71
 * @link http://us3.php.net/in_array
72
 */
73
function in_array_recursive( $needle, $haystack, $insensitive = false ) {
74
	$fnc = 'in_array';
75
	if( $insensitive ) $fnc = 'iin_array';
76
77
	if( $fnc( $needle, $haystack ) ) return true;
78
	foreach( $haystack as $val ){
79
		if( is_array( $val ) ) {
80
			return in_array_recursive( $needle, $val );
81
		}
82
	}
83
	return false;
84
}
85
86
/**
87
 * Recursive glob() function.
88
 *
89
 * @access public
90
 * @param string $pattern . (default: '*')
91
 * @param int $flags . (default: 0)
92
 * @param string $path . (default: '')
93
 * @return array
94
 */
95
function rglob( $pattern = '*', $flags = 0, $path = '' ) {
96
	$paths = glob( $path . '*', GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT );
97
	$files = glob( $path . $pattern, $flags );
98
	foreach( $paths as $path ){
99
		$files = array_merge( $files, rglob( $pattern, $flags, $path ) );
100
	}
101
	return $files;
102
}
103
104
/**
105
 * Detects the presence of a nobots template or one that denies editing by ours
106
 *
107
 * @access    public
108
 * @param    Wiki $wiki Wiki class
109
 * @param    string $text Text of the page to check (default: '')
110
 * @param    string $pgUsername Username to search for in the template (default: null)
111
 * @param    string|null $optout Text to search for in the optout= parameter. (default: null)
112
 * @param    string|null $taskname (default: null)
113
 * @return    bool                    True on match of an appropriate nobots template
114
 */
115
function checkExclusion( Wiki $wiki, $text = '', $pgUsername = null, $optout = null, $taskname = null ) {
116
	if( !$wiki->get_nobots() ) return false;
117
118
	if( in_string( "{{nobots}}", $text ) ) return true;
119
	if( in_string( "{{bots}}", $text ) ) return false;
120
121
	if( preg_match( '/\{\{bots\s*\|\s*allow\s*=\s*(.*?)\s*\}\}/i', $text, $allow ) ) {
122
		if( $allow[1] == "all" ) return false;
123
		if( $allow[1] == "none" ) return true;
124
		$allow = array_map( 'trim', explode( ',', $allow[1] ) );
125
		if( !is_null( $pgUsername ) && in_array( trim( $pgUsername ), $allow ) ) {
126
			return false;
127
		}
128
		return true;
129
	}
130
131
	if( preg_match( '/\{\{(no)?bots\s*\|\s*deny\s*=\s*(.*?)\s*\}\}/i', $text, $deny ) ) {
132
		if( $deny[2] == "all" ) return true;
133
		if( $deny[2] == "none" ) return false;
134
		$allow = array_map( 'trim', explode( ',', $deny[2] ) );
135
		if( ( !is_null( $pgUsername ) && in_array( trim( $pgUsername ), $allow ) ) || ( !is_null( $taskname ) && in_array( trim( $taskname ), $allow ) ) ) {
136
			return true;
137
		}
138
		return false;
139
	}
140
141
	if( !is_null( $optout ) && preg_match( '/\{\{(no)?bots\s*\|\s*optout\s*=\s*(.*?)\s*\}\}/i', $text, $allow ) ) {
142
		if( $allow[1] == "all" ) return true;
143
		$allow = array_map( 'trim', explode( ',', $allow[2] ) );
144
		if( in_array( trim( $optout ), $allow ) ) {
145
			return true;
146
		}
147
		return false;
148
	}
149
	return false;
150
}
151
152
/**
153
 * Outputs text if the given category is in the allowed types
154
 *
155
 * @param string $text Text to display
156
 * @param int $cat Category of text, such as PECHO_WARN, PECHO_NORMAL
157
 * @param string $func
158
 * @return void
159
 */
160
function outputText( $text, $cat = 0, $func = 'echo' ) {
161
	global $pgVerbose;
162
163
	Hooks::runHook( 'OutputText', array( &$text, &$cat, &$func ) );
164
165
	if( in_array( $cat, $pgVerbose ) ) {
166
		if( $func == 'echo' ) {
167
			echo $text;
168
		} else {
169
			$func( $text );
170
		}
171
	}
172
}
173
174
/**
175
 * Shortcut for {@link outputText}
176
 *
177
 * @param string $text Text to display
178
 * @param int $cat Category of text, such as PECHO_WARN, PECHO_NORMAL
179
 * @param string $func
180
 * @link outputText
181
 * @return void
182
 */
183
function pecho( $text, $cat = 0, $func = 'echo' ) {
184
	global $pgWebOutput;
185
	if( $pgWebOutput ) $text = str_replace( "\n", "<br>", $text );
186
	outputText( $text, $cat, $func );
187
}
188
189
/**
190
 * Echo function with color capabilities.
191
 *
192
 * Syntax:
193
 *
194
 * <i>[Text to colorize|NAME] where NAME is the name of a defined style.</i> For example:
195
 *
196
 * <i>This text is standard terminal color. [This text will be yellow.|COMMENT] [This text will be white on red.|ERROR]</i>
197
 *
198
 * Defined styles:
199
 * <ul>
200
 * <li>ERROR: White on red, bold</li>
201
 * <li>INFO: Green text, bold</li>
202
 * <li>PARAMETER: Cyan text</li>
203
 * <li>COMMENT: Yellow text</li>
204
 * <li>GREEN_BAR: White on green, bold</li>
205
 * <li>RED_BAR: White on red, bold</li>
206
 * <li>YELLOW_BAR: Black on yellow, bold</li>
207
 * <li>INFO_BAR: Cyan text, bold</li>
208
 * </ul>
209
 *
210
 * You can define your own styles by using this syntax:
211
 *
212
 *   <code>lime_colorizer::style('STYLE_NAME', array('bg' => 'red', 'fg' => 'white'));</code>
213
 *
214
 * (Available colors: black, red, green, yellow, blue, magenta, cyan, white)
215
 *
216
 * You can also set options for how the text is formatted (not available on all systems):
217
 *
218
 *   <code>lime_colorizer::style('STYLE_NAME', array('bg' => 'red', 'fg' => 'white', 'bold' => true ));</code> (sets bold text)
219
 *
220
 * Available options: bold, underscore, blink, reverse, conceal
221
 *
222
 *
223
 * @access public
224
 * @param string $text
225
 * @param bool $return
226
 * @return string
227
 */
228
function cecho( $text, $return = false ) {
229
	global $pgColorizer;
230
231
	if( !isset( $pgColorizer ) ) $pgColorizer = new lime_colorizer( true );
232
233
	$text = preg_replace_callback( '/\[(.+?)\|(\w+)\]/s', function ($m) {
234
                    global $pgColorizer;
235
                    return $pgColorizer->colorize($m[1], $m[2]);
236
                }, $text );
237
	if( $return ) return $text;
238
239
	echo $text;
240
241
}
242
243
244
/**
245
 * Generates a diff between two strings
246
 *
247
 * @package Text_Diff
248
 * @deprecated since 18 June 2013
249
 */
250
function getTextDiff() {
251
	Peachy::deprecatedWarn( 'getTextDiff()', 'Diff::load()' );
252
	$args = func_get_args();
253
	return call_user_func_array( array( 'Diff', 'load' ), $args );
254
}
255
256
/**
257
 * Gets the first defined Wiki object
258
 *
259
 * @return Wiki|bool
260
 * @package initFunctions
261
 */
262
function &getSiteObject() {
0 ignored issues
show
Coding Style introduced by
getSiteObject uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
263
264
	foreach( $GLOBALS as $var ){
265
		if( is_object( $var ) ) {
266
			if( get_class( $var ) == "Wiki" ) {
267
				return $var;
268
			}
269
		}
270
	}
271
272
	return false;
273
}
274
275
/**
276
 * Returns an instance of the Page class as specified by $title or $pageid
277
 *
278
 * @param mixed $title Title of the page (default: null)
279
 * @param mixed $pageid ID of the page (default: null)
280
 * @param bool $followRedir Should it follow a redirect when retrieving the page (default: true)
281
 * @param bool $normalize Should the class automatically normalize the title (default: true)
282
 * @return Page
283
 * @package initFunctions
284
 */
285
function &initPage( $title = null, $pageid = null, $followRedir = true, $normalize = true ) {
286
	$wiki = getSiteObject();
287
	if( !$wiki ) return false;
288
289
	$page = new Page( $wiki, $title, $pageid, $followRedir, $normalize );
290
	return $page;
291
}
292
293
/**
294
 * Returns an instance of the User class as specified by $pgUsername
295
 *
296
 * @param mixed $pgUsername Username
297
 * @return User|false
298
 * @package initFunctions
299
 */
300
function &initUser( $pgUsername ) {
301
	$wiki = getSiteObject();
302
	if( !$wiki ) return false;
303
	return new User( $wiki, $pgUsername );
304
}
305
306
/**
307
 * Returns an instance of the Image class as specified by $filename or $pageid
308
 *
309
 * @param string $filename Filename
310
 * @return Image
311
 * @package initFunctions
312
 */
313
function &initImage( $filename = null ) {
314
315
	$wiki = getSiteObject();
316
	if( !$wiki ) return false;
317
318
	$image = new Image( $wiki, $filename );
319
	return $image;
320
}
321
322
if( !function_exists( 'mb_strlen' ) ) {
323
324
	/**
325
	 * Fallback implementation of mb_strlen.
326
	 *
327
	 * @link http://svn.wikimedia.org/svnroot/mediawiki/trunk/phase3/includes/GlobalFunctions.php
328
	 * @param string $str String to get
329
	 * @return int
330
	 * @package Fallback
331
	 */
332
	function mb_strlen( $str ) {
333
		$counts = count_chars( $str );
334
		$total = 0;
335
336
		// Count ASCII bytes
337
		for( $i = 0; $i < 0x80; $i++ ){
338
			$total += $counts[$i];
339
		}
340
341
		// Count multibyte sequence heads
342
		for( $i = 0xc0; $i < 0xff; $i++ ){
343
			$total += $counts[$i];
344
		}
345
346
		return $total;
347
	}
348
}
349
350
if( !function_exists( 'mb_substr' ) ) {
351
	/**
352
	 * Fallback implementation for mb_substr. This is VERY slow, from 5x to 100x slower. Use only if necessary.
353
	 * @link http://svn.wikimedia.org/svnroot/mediawiki/trunk/phase3/includes/GlobalFunctions.php
354
	 * @package Fallback
355
	 */
356
	function mb_substr( $str, $start, $count = 'end' ) {
357
		if( $start != 0 ) {
358
			$split = mb_substr_split_unicode( $str, intval( $start ) );
359
			$str = substr( $str, $split );
360
		}
361
362
		if( $count !== 'end' ) {
363
			$split = mb_substr_split_unicode( $str, intval( $count ) );
364
			$str = substr( $str, 0, $split );
365
		}
366
367
		return $str;
368
	}
369
370
	/**
371
	 * Continuing support for mb_substr. Do not use.
372
	 * @link http://svn.wikimedia.org/svnroot/mediawiki/trunk/phase3/includes/GlobalFunctions.php
373
	 * @package Fallback
374
	 * @param integer $splitPos
375
	 * @return int
376
	 */
377
	function mb_substr_split_unicode( $str, $splitPos ) {
378
		if( $splitPos == 0 ) {
379
			return 0;
380
		}
381
382
		$byteLen = strlen( $str );
383
384
		if( $splitPos > 0 ) {
385
			if( $splitPos > 256 ) {
386
				// Optimize large string offsets by skipping ahead N bytes.
387
				// This will cut out most of our slow time on Latin-based text,
388
				// and 1/2 to 1/3 on East European and Asian scripts.
389
				$bytePos = $splitPos;
390
				while( $bytePos < $byteLen && $str{$bytePos} >= "\x80" && $str{$bytePos} < "\xc0" ){
391
					++$bytePos;
392
				}
393
				$charPos = mb_strlen( substr( $str, 0, $bytePos ) );
394
			} else {
395
				$charPos = 0;
396
				$bytePos = 0;
397
			}
398
399
			while( $charPos++ < $splitPos ){
400
				++$bytePos;
401
				// Move past any tail bytes
402
				while( $bytePos < $byteLen && $str{$bytePos} >= "\x80" && $str{$bytePos} < "\xc0" ){
403
					++$bytePos;
404
				}
405
			}
406
		} else {
407
			$splitPosX = $splitPos + 1;
408
			$charPos = 0; // relative to end of string; we don't care about the actual char position here
409
			$bytePos = $byteLen;
410
			while( $bytePos > 0 && $charPos-- >= $splitPosX ){
411
				--$bytePos;
412
				// Move past any tail bytes
413
				while( $bytePos > 0 && $str{$bytePos} >= "\x80" && $str{$bytePos} < "\xc0" ){
414
					--$bytePos;
415
				}
416
			}
417
		}
418
419
		return $bytePos;
420
	}
421
}
422
423
if( !function_exists( 'iconv' ) ) {
424
	/**
425
	 * Fallback iconv function.
426
	 *
427
	 * iconv support is not in the default configuration and so may not be present.
428
	 * Assume will only ever use utf-8 and iso-8859-1.
429
	 * This will *not* work in all circumstances.
430
	 *
431
	 * @access public
432
	 * @param mixed $from
433
	 * @param mixed $to
434
	 * @param mixed $string
435
	 * @return void
436
	 * @package Fallback
437
	 */
438
	function iconv( $from, $to, $string ) {
439
		if( substr( $to, -8 ) == '//IGNORE' ) $to = substr( $to, 0, strlen( $to ) - 8 );
440
		if( strcasecmp( $from, $to ) == 0 ) return $string;
441
		if( strcasecmp( $from, 'utf-8' ) == 0 ) return utf8_decode( $string );
442
		if( strcasecmp( $to, 'utf-8' ) == 0 ) return utf8_encode( $string );
443
		return $string;
444
	}
445
}
446
447
if( !function_exists( 'istainted' ) ) {
448
449
	/**
450
	 * Fallback istainted function.
451
	 *
452
	 * @access public
453
	 * @param mixed $var
454
	 * @return integer
455
	 * @package Fallback
456
	 */
457
	function istainted( $var ) {
0 ignored issues
show
Unused Code introduced by
The parameter $var is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
458
		return 0;
459
	}
460
461
	/**
462
	 * Fallback taint function.
463
	 *
464
	 * @access public
465
	 * @param mixed $var
466
	 * @param int $level
467
	 * @return void
468
	 * @package Fallback
469
	 */
470
	function taint( $var, $level = 0 ) { }
0 ignored issues
show
Unused Code introduced by
The parameter $var is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $level is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
471
472
	/**
473
	 * Fallback untaint function.
474
	 *
475
	 * @access public
476
	 * @param mixed $var
477
	 * @param int $level
478
	 * @return void
479
	 * @package Fallback
480
	 */
481
	function untaint( $var, $level = 0 ) { }
0 ignored issues
show
Unused Code introduced by
The parameter $var is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $level is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
482
483
	/**
484
	 * @package Fallback
485
	 */
486
	define( 'TC_HTML', 1 );
487
488
	/**
489
	 * @package Fallback
490
	 */
491
	define( 'TC_SHELL', 1 );
492
493
	/**
494
	 * @package Fallback
495
	 */
496
	define( 'TC_MYSQL', 1 );
497
498
	/**
499
	 * @package Fallback
500
	 */
501
	define( 'TC_PCRE', 1 );
502
503
	/**
504
	 * @package Fallback
505
	 */
506
	define( 'TC_SELF', 1 );
507
}
508