TestObjectToString   A
last analyzed

Complexity

Total Complexity 1

Size/Duplication

Total Lines 22
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 0
Metric Value
wmc 1
lcom 0
cbo 1
dl 0
loc 22
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A __toString() 0 3 1
1
<?php
2
/**
3
 * Some generic functions and mock objects for test variables.
4
 *
5
 * @package PHPCheatsheets
6
 *
7
 * @phpcs:disable Generic.Files.OneClassPerFile
8
 */
9
10
// Prevent direct calls to this file.
11
if ( ! defined( 'APP_DIR' ) ) {
12
	header( 'Status: 403 Forbidden' );
13
	header( 'HTTP/1.1 403 Forbidden' );
14
	exit();
15
}
16
17
/**
18
 * Simple object to use for tests with the object variable type.
19
 */
20
class TestObject {
21
22
	/**
23
	 * A property.
24
	 *
25
	 * @var null
26
	 */
27
	var $test1;
28
29
	/**
30
	 * Another property.
31
	 *
32
	 * @var bool
33
	 */
34
	var $test2 = true;
35
36
37
	/**
38
	 * Example method.
39
	 *
40
	 * @param string $var
41
	 */
42
	function print_it( $var ) {
43
		echo htmlspecialchars( $var );
44
	}
45
}
46
47
/**
48
 * Another simple object to use for tests with the object variable type.
49
 */
50
class TestObjectToString extends TestObject {
51
52
	/**
53
	 * A third property.
54
	 *
55
	 * @var string
56
	 */
57
	var $test3 = 'some string';
58
59
60
	/**
61
	 * Example __toString method.
62
	 *
63
	 * @return string
64
	 *
65
	 * @phpcs:disable PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__tostringFound -- Used for demo purposes.
66
	 */
67
	function __toString() {
68
		return $this->test3;
69
	}
70
	// phpcs:enable
71
}
72
73
74
/**
75
 * Helper function to compare strings, compatible with PHP4.
76
 *
77
 * @param mixed  $var1
78
 * @param mixed  $var2
79
 * @param string $function
80
 */
81
function pc_compare_strings( $var1, $var2, $function ) {
82
	$result = $function( $var1, $var2 );
83
	if ( is_int( $result ) ) {
84
		pr_int( $result );
85
	}
86
	else {
87
		pr_var( $result, '', true, true );
88
	}
89
}
90
91
92
/**
93
 * Catch errors to display in appendix.
94
 *
95
 * @param int    $error_no
96
 * @param string $error_str
97
 * @param string $error_file
98
 * @param int    $error_line
99
 *
100
 * @return null|false
101
 */
102
function do_handle_errors( $error_no, $error_str, $error_file, $error_line ) {
103
	if ( ! ( error_reporting() & $error_no ) ) {
104
		return;
105
	}
106
107
	if ( ! defined( 'E_STRICT' ) ) {
108
		define( 'E_STRICT', 2048 );
109
	}
110
	if ( ! defined( 'E_RECOVERABLE_ERROR' ) ) {
111
		define( 'E_RECOVERABLE_ERROR', 4096 );
112
	}
113
	if ( ! defined( 'E_DEPRECATED' ) ) {
114
		define( 'E_DEPRECATED', 8192 );
115
	}
116
	if ( ! defined( 'E_USER_DEPRECATED' ) ) {
117
		define( 'E_USER_DEPRECATED', 16384 );
118
	}
119
120
	switch ( $error_no ) {
121
		case E_ERROR: // 1 //
122
		case E_CORE_ERROR: // 16 //
123
		case E_COMPILE_ERROR: // 64 //
124
			$type  = 'Fatal error';
125
			$class = 'error';
126
			break;
127
128
		case E_USER_ERROR: // 256 //
129
			$type  = 'Fatal error';
130
			$class = 'error';
131
			break;
132
133
		case E_WARNING: // 2 //
134
		case E_CORE_WARNING: // 32 //
135
		case E_COMPILE_WARNING: // 128 //
136
			$type  = 'Warning';
137
			$class = 'warning';
138
			break;
139
140
		case E_USER_WARNING: // 512 //
141
			$type  = 'Warning';
142
			$class = 'warning';
143
			break;
144
145
		case E_PARSE: // 4 //
146
			$type  = 'Parse error';
147
			$class = 'error';
148
			break;
149
150
		case E_NOTICE: // 8 //
151
		case E_USER_NOTICE: // 1024 //
152
			$type  = 'Notice';
153
			$class = 'notice';
154
			break;
155
156
		case E_STRICT: // 2048 //
157
			$type  = 'Strict warning';
158
			$class = 'warning';
159
			break;
160
161
		case E_RECOVERABLE_ERROR: // 4096 //
162
			$type  = '(Catchable) Fatal error';
163
			$class = 'error';
164
			break;
165
166
		case E_DEPRECATED: // 8192 //
167
		case E_USER_DEPRECATED: // 16384 //
168
			$type  = 'Deprecated';
169
			$class = 'notice';
170
			break;
171
172
		default:
173
			$type  = 'Unknown error ( ' . $error_no . ' )';
174
			$class = 'error';
175
			break;
176
	}
177
178
179
	// Group some messages.
180
	$search = array(
181
		'array_key_exists() expects parameter 2 to be array',
182
		'key() expects parameter 1 to be array',
183
		'current() expects parameter 1 to be array',
184
		'array_filter() expects parameter 1 to be array',
185
		'preg_match() expects parameter 2 to be string',
186
		'strlen() expects parameter 1 to be string',
187
		'count_chars() expects parameter 1 to be string',
188
		'mb_strlen() expects parameter 1 to be string',
189
		'trim() expects parameter 1 to be string',
190
		'get_class() expects parameter 1 to be object',
191
		'get_resource_type() expects parameter 1 to be resource',
192
	);
193
194
	$replace = array(
195
		'array_key_exists() expects parameter 2 to be array, <em>null/boolean/integer/double/string/object/resource</em> given',
196
		'key() expects parameter 1 to be array, <em>null/boolean/integer/double/string/object/resource</em> given',
197
		'current() expects parameter 1 to be array, <em>null/boolean/integer/double/string/object/resource</em> given',
198
		'array_filter() expects parameter 1 to be array, <em>null/boolean/integer/double/string/object/resource</em> given',
199
		'preg_match() expects parameter 2 to be string, <em>array/object/resource</em> given',
200
		'strlen() expects parameter 1 to be string, <em>array/object/resource</em> given',
201
		'count_chars() expects parameter 1 to be string, <em>array/object/resource</em> given',
202
		'mb_strlen() expects parameter 1 to be string, <em>array/object/resource</em> given',
203
		'trim() expects parameter 1 to be string, <em>array/object/resource</em> given',
204
		'get_class() expects parameter 1 to be object, <em>boolean/integer/double/string/array/resource</em> given',
205
		'get_resource_type() expects parameter 1 to be resource, <em>null/boolean/integer/double/string/array/object</em> given',
206
	);
207
208
	// Group some more messages and make error message links work.
209
	$preg_search  = array(
210
		'`^(bc(?:add|sub|mul|div|mod|comp)|str(?:case|natcase|nat)?cmp|strcoll|similar_text|levenshtein)\(\) expects parameter ([12]) to be string, (?:array|object|resource) given$`',
211
		'`^fmod\(\) expects parameter ([12]) to be (double|float), (?:string|array|object|resource) given$`',
212
		'`^(is_(?:nan|(?:in)?finite))\(\) expects parameter ([12]) to be (double|float), (?:string|array|object|resource) given$`',
213
		'`^Object of class [A-Za-z]+ could not be converted to (int|double|float|string|number)$`',
214
		'`^Object of class [A-Za-z]+ to string conversion$`',
215
		'`^Cannot use object of type [A-Za-z]+ as array$`',
216
		'`<a href=(["\'])function\.`',
217
		'`^intdiv\(\) expects parameter ([12]) to be int(eger)?, (?:float|string|array|object|resource) given$`',
218
	);
219
	$preg_replace = array(
220
		'$1() expects parameter $2 to be string, <em>array/object/resource</em> given',
221
		'fmod() expects parameter $1 to be $2, <em>string/array/object/resource</em> given',
222
		'$1() expects parameter $2 to be $3, <em>string/array/object/resource</em> given',
223
		'Object of class <em>stdClass/TestObject/TestObjectToString</em> could not be converted to $1',
224
		'Object of class <em>stdClass/TestObject/TestObjectToString</em> to string conversion',
225
		'Cannot use object of type <em>stdClass/TestObject/TestObjectToString</em> as array',
226
		'<a href=$1https://php.net/function.',
227
		'intdiv() expects parameter $1 to be int$2, <em>float/string/array/object/resource</em> given',
228
	);
229
230
	foreach ( $search as $k => $s ) {
231
		if ( strpos( $error_str, $s ) === 0 ) {
232
			$error_str = $replace[ $k ];
233
			break;
234
		}
235
	}
236
	$error_str = preg_replace( $preg_search, $preg_replace, $error_str );
237
238
239
	$message = '<span class="' . $class . '">' . $type . '</span>: ' . $error_str;
240
241
	if ( isset( $GLOBALS['encountered_errors'] ) ) {
242
		// Ignore strict warnings (can't avoid having them if I want to keep this sheet working with PHP4).
243
		if ( $error_no !== E_STRICT ) {
244
			$key = get_error_key( $message );
245
246
			if ( $class === 'notice' || $class === 'warning' ) {
247
				$GLOBALS['has_error'][]['msg'] = ' (&nbsp;<span class="' . $class . '"><a href="#' . $GLOBALS['test'] . '-errors">#' . ( $key + 1 ) . '</a></span>&nbsp;)';
248
				return;
249
			}
250
			else if ( $class === 'error' ) {
251
				$GLOBALS['has_error'][]['msg'] = ' <span class="error">' . $type . ' (&nbsp;<a href="#' . $GLOBALS['test'] . '-errors">#' . ( $key + 1 ) . '</a>&nbsp;)</span>';
252
				return;
253
			}
254
			else {
255
				echo $message, ' in ', $error_file, ' on line ', $error_line, "<br />\n";
256
			}
257
		}
258
		else {
259
			return;
260
		}
261
	}
262
	else {
263
		if ( $error_no !== E_STRICT ) {
264
			echo $message, ' in ', $error_file, ' on line ', $error_line, "<br />\n";
265
		}
266
		else {
267
			return;
268
		}
269
	}
270
271
	return false; // Make sure it plays nice with other error handlers (remove if no other error handlers are set).
272
}
273
274
275
/**
276
 * Get the index key for an error message and add the error message to the global array if it doesn't exist yet.
277
 *
278
 * @param string $message
279
 *
280
 * @return int
281
 */
282
function get_error_key( $message ) {
283
	$key = array_search( $message, $GLOBALS['encountered_errors'], true );
284
	if ( $key === false ) {
285
		$GLOBALS['encountered_errors'][] = $message;
286
		$key                             = array_search( $message, $GLOBALS['encountered_errors'], true );
287
	}
288
	return $key;
289
}
290
291
292
/**
293
 * Determine the base url to use.
294
 *
295
 * @return string
296
 */
297
function determine_base_uri() {
298
	$valid_hosts = array(
299
		'phpcheatsheets.com',
300
		'phpcheatsheet.com',
301
		'phpcheatsheets.localdev',
302
		'localhost',
303
	);
304
305
	$base_uri = 'https://phpcheatsheets.com/';
306
307
	if ( isset( $_SERVER['HTTP_HOST'] ) && in_array( $_SERVER['HTTP_HOST'], $valid_hosts, true ) ) {
308
		$base_uri = 'https://' . $_SERVER['HTTP_HOST'] . determine_script_path();
309
	}
310
	else if ( isset( $_SERVER['SERVER_NAME'] ) && in_array( $_SERVER['SERVER_NAME'], $valid_hosts, true ) ) {
311
		$base_uri = 'https://' . $_SERVER['SERVER_NAME'] . determine_script_path();
312
	}
313
314
	return $base_uri;
315
}
316
317
318
/**
319
 * Determine the script path part of the base url.
320
 *
321
 * @return string
322
 */
323
function determine_script_path() {
324
	if ( ! empty( $_SERVER['SCRIPT_NAME'] ) && stripos( $_SERVER['SCRIPT_NAME'], 'index.php' ) !== false ) {
325
		return substr( $_SERVER['SCRIPT_NAME'], 0, stripos( $_SERVER['SCRIPT_NAME'], 'index.php' ) );
326
	}
327
	else if ( ! empty( $_SERVER['REQUEST_URI'] ) && stripos( $_SERVER['REQUEST_URI'], 'index.php' ) !== false ) {
328
		return substr( $_SERVER['REQUEST_URI'], 0, stripos( $_SERVER['REQUEST_URI'], 'index.php' ) );
329
	}
330
	else {
331
		return '/';
332
	}
333
}
334
335
336
/**
337
 * PHP4 compat.
338
 */
339
if ( ! function_exists( 'stripos' ) ) {
340
	/**
341
	 * Make an equivalent to the PHP5 stripos() function available in PHP4.
342
	 *
343
	 * @param string $haystack
344
	 * @param string $needle
345
	 *
346
	 * @return int|false
347
	 */
348
	function stripos( $haystack, $needle ) {
349
		$haystack = strtolower( $haystack );
350
		$needle   = strtolower( $needle );
351
		return strpos( $haystack, $needle );
352
	}
353
}
354
355
356
/**
357
 * Generate dropdown list of available static versions.
358
 *
359
 * @return string
360
 */
361
function generate_version_dropdown() {
362
363
	$available = glob( APP_DIR . '/static_results/' . $GLOBALS['type'] . '/php*.html' );
364
	usort( $available, 'version_compare' );
365
	$available = array_reverse( $available );
366
367
	$optgroup = 100;
368
	$options  = array();
369
370
	$options_html          = '';
371
	$optgroup_html_pattern = '
372
					<optgroup label="PHP %1$s">%2$s' . "\n\t\t\t\t\t</optgroup>";
373
374
	$regex = sprintf(
375
		'`^%1$s/static_results/%2$s/php(([457]\.[0-9]+)\.[0-9-]+(?:(?:alpha|beta|RC)(?:[0-9])?)?)\.html$`',
376
		preg_quote( APP_DIR, '`' ),
377
		preg_quote( $GLOBALS['type'], '`' )
378
	);
379
380
	foreach ( $available as $file ) {
381
		if ( preg_match( $regex, $file, $match ) ) {
382
			if ( $options !== array() && ( version_compare( $optgroup, $match[2], '>' ) && $optgroup !== 100 ) ) {
383
				$options_html .= sprintf( $optgroup_html_pattern, $optgroup, implode( "\n", $options ) );
384
				$options       = array();
385
			}
386
			$optgroup = $match[2];
387
388
389
			$selected = '';
390
			if ( ( isset( $GLOBALS['autogen'] ) && $GLOBALS['autogen'] === true ) && $match[1] === PHP_VERSION ) {
391
				$selected = ' selected="selected"';
392
			}
393
			$options[] = sprintf(
394
				'
395
						<option value="php%1$s"%2$s>PHP %1$s</option>',
396
				htmlspecialchars( $match[1], ENT_QUOTES, 'UTF-8' ),
397
				$selected
398
			);
399
		}
400
	}
401
	// Add last group.
402
	if ( $options !== array() ) {
403
		$options_html .= sprintf( $optgroup_html_pattern, $optgroup, implode( "\n", $options ) );
404
	}
405
406
	$dropdown = sprintf(
407
		'
408
			<form action="%6$sindex.php" method="get" id="choose-version">
409
				<input type="hidden" name="page" value="%1$s" />
410
				<input type="hidden" id="phpv-tab" name="tab" value="%2$s" />
411
				<select id="phpversion-dropdown" name="phpversion">
412
					<optgroup label="Live">
413
						<option value="live" %3$s >PHP %4$s</option>
414
					</optgroup>
415
					%5$s
416
				</select>
417
			</form>',
418
		htmlspecialchars( $GLOBALS['type'], ENT_QUOTES, 'UTF-8' ),
419
		htmlspecialchars( $GLOBALS['tab'], ENT_QUOTES, 'UTF-8' ),
420
		( ( ! isset( $GLOBALS['autogen'] ) || $GLOBALS['autogen'] !== true ) ? ' selected="selected"' : '' ),
421
		htmlspecialchars( PHP_VERSION, ENT_QUOTES, 'UTF-8' ),
422
		$options_html,
423
		htmlspecialchars( BASE_URI, ENT_QUOTES, 'UTF-8' )
424
	);
425
426
	return $dropdown;
427
}
428