Vartype   F
last analyzed

Complexity

Total Complexity 95

Size/Duplication

Total Lines 693
Duplicated Lines 5.19 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 36
loc 693
rs 1.907
c 0
b 0
f 0
wmc 95
lcom 1
cbo 2

25 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 26 4
A vartype() 0 3 1
A merge_tests() 0 8 3
A get_tab_title() 8 8 4
A get_tab_list() 0 3 1
A do_page() 0 11 3
A get_test_group() 0 7 2
A run_test() 0 8 1
A set_test_data() 0 23 3
A sort_test_data() 0 38 5
A clean_up() 0 15 6
A print_tabs() 8 24 4
A print_tables() 0 14 2
C print_table() 11 80 12
B create_table_header() 0 32 7
A get_table_header_group_label() 0 10 3
A get_table_header_note_indicators() 0 17 6
A get_table_header_cell_class() 0 12 5
A print_tabletop() 0 12 1
A print_row_cells() 0 20 2
A get_table_row_cell_class() 6 16 5
A print_row_cell_error_refs() 3 9 6
A generate_value() 0 6 2
A print_error_footnotes() 0 14 3
A print_other_footnotes() 0 16 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Vartype often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Vartype, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Generic variable testing parent class.
4
 *
5
 * @package PHPCheatsheets
6
 */
7
8
// Prevent direct calls to this file.
9
if ( ! defined( 'APP_DIR' ) ) {
10
	header( 'Status: 403 Forbidden' );
11
	header( 'HTTP/1.1 403 Forbidden' );
12
	exit();
13
}
14
15
/**
16
 * Generic variable testing parent class.
17
 */
18
class Vartype {
19
20
	/**
21
	 * Placeholder for test data.
22
	 *
23
	 * @var array
24
	 */
25
	var $test_data = array();
26
27
	/**
28
	 * Placeholder for test data labels.
29
	 *
30
	 * @var array
31
	 */
32
	var $test_legend = array();
33
34
	/**
35
	 * Placeholder for test data key array.
36
	 *
37
	 * @var array
38
	 */
39
	var $test_data_keys = array();
40
41
42
	/**
43
	 * At which point in the tables to repeat headers.
44
	 *
45
	 * @var array
46
	 */
47
	var $header_repeat = array( 's', 'a', 'o', 'p' );
48
49
50
	/**
51
	 * Tests to be run, added in child class.
52
	 *
53
	 * @var array
54
	 */
55
	var $tests = array();
56
57
	/**
58
	 * Placeholder for grouping of the tests.
59
	 *
60
	 * @var array
61
	 */
62
	var $test_groups = array();
63
64
65
	/**
66
	 * Placeholder for test notes.
67
	 *
68
	 * @var array
69
	 */
70
	var $table_notes = array();
71
72
73
	/**
74
	 * Helper array to determine which class(es) should be used in table header cells.
75
	 *
76
	 * @var array Key is where to look in the test_group, value is the classname to add.
77
	 */
78
	var $table_header_class_map = array(
79
		'best'     => 'best',
80
		'good'     => 'good',
81
		'break_at' => 'end',
82
	);
83
84
85
	/**
86
	 * Constructor.
87
	 */
88
	function __construct() {
89
90
		/**
91
		 * Replace selected PHP4 specific tests with their PHP5 equivalents to avoid parse errors
92
		 * when running the tests in PHP4.
93
		 */
94
		if ( PHP_VERSION_ID >= 50000 ) {
95
			include_once APP_DIR . '/class.vartype-php5.php';
96
			$this->merge_tests( VartypePHP5::get_tests() );
97
		}
98
99
		/**
100
		 * Add some PHP7 specific tests.
101
		 */
102
		if ( PHP_VERSION_ID >= 70000 ) {
103
			include_once APP_DIR . '/class.vartype-php7.php';
104
			$this->merge_tests( VartypePHP7::get_tests() );
105
		}
106
107
		// Create the actual test functions.
108
		foreach ( $this->tests as $key => $array ) {
109
			// The cheatsheets are still compatible with PHP < 5.3, so there is no way round this.
110
			// phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.create_functionDeprecated,Generic.PHP.DeprecatedFunctions.Deprecated,WordPress.PHP.RestrictedPHPFunctions.create_function_create_function,WordPress.PHP.NoSilencedErrors.Discouraged
111
			$this->tests[ $key ]['test'] = @create_function( $array['arg'], $array['function'] );
112
		}
113
	}
114
115
116
	/**
117
	 * PHP4 compatibility constructor.
118
	 */
119
	function vartype() {
120
		$this->__construct();
121
	}
122
123
124
	/**
125
	 * Overwrite selected entries in the original test array with PHP-version specific function code.
126
	 *
127
	 * @param array $overload_tests Array of test entries to use in the overloading.
128
	 */
129
	function merge_tests( $overload_tests ) {
130
131
		foreach ( $overload_tests as $key => $array ) {
132
			if ( isset( $this->tests[ $key ], $this->tests[ $key ]['function'], $array['function'] ) ) {
133
				$this->tests[ $key ]['function'] = $array['function'];
134
			}
135
		}
136
	}
137
138
139
	/**
140
	 * Get the tab title for the initial tab for use in the page header.
141
	 *
142
	 * @param string $tab
143
	 *
144
	 * @return string
145
	 */
146 View Code Duplication
	function get_tab_title( $tab ) {
147
		if ( isset( $this->test_groups[ $tab ]['title'] ) && is_string( $this->test_groups[ $tab ]['title'] ) && $this->test_groups[ $tab ]['title'] !== '' ) {
148
			return $this->test_groups[ $tab ]['title'];
149
		}
150
		else {
151
			return '';
152
		}
153
	}
154
155
156
	/**
157
	 * Get a list of all tabs which this class will create.
158
	 *
159
	 * Helper function for the sitemap.
160
	 *
161
	 * @return array
162
	 */
163
	function get_tab_list() {
164
		return array_keys( $this->test_groups );
165
	}
166
167
168
	/**
169
	 * Generate a cheatsheet page.
170
	 *
171
	 * @param bool $all
172
	 */
173
	function do_page( $all = false ) {
174
175
		echo '<div id="tabs">';
176
177
		$this->print_tabs( $all );
178
179
		if ( isset( $all ) && $all === true ) {
180
			$this->print_tables();
181
		}
182
		echo "\n", '</div><!-- end of div#tabs -->';
183
	}
184
185
186
	/**
187
	 * Determine which tests to run.
188
	 *
189
	 * @param string|null $test_group The current subsection.
190
	 *
191
	 * @return string
192
	 */
193
	function get_test_group( $test_group = null ) {
194
		$key = key( $this->test_groups ); // Set the first test group as the default if no test group given.
195
		if ( isset( $test_group, $this->test_groups[ $test_group ] ) ) {
196
			$key = $test_group;
197
		}
198
		return $key;
199
	}
200
201
202
	/**
203
	 * Run all the tests for one specific testgroup.
204
	 *
205
	 * @param string|null $test_group The current subsection.
206
	 */
207
	function run_test( $test_group = null ) {
208
209
		$test_group = $this->get_test_group( $test_group );
210
211
		$this->set_test_data( $test_group );
212
		$this->print_table( $test_group );
213
		$this->clean_up();
214
	}
215
216
217
	/**
218
	 * Prepare the test data (the variables) for use in the tests.
219
	 *
220
	 * @param string|null $test_group The current subsection.
221
	 */
222
	function set_test_data( $test_group = null ) {
223
224
		$GLOBALS['test'] = $test_group;
225
226
		include APP_DIR . '/include/vars-to-test.php';
227
		$this->test_data   = $test_array;
228
		$this->test_legend = $legend_array;
229
230
		// Merge test group specific variables into the test array.
231
		if ( isset( $extra_variables[ $test_group ] ) && $extra_variables[ $test_group ] !== array() ) {
232
			$this->test_data = array_merge( $this->test_data, $extra_variables[ $test_group ] );
233
		}
234
235
		$keys = array_keys( $this->test_data );
236
		usort( $keys, array( $this, 'sort_test_data' ) );
237
238
239
		$this->test_data_keys   = array();
240
		$this->test_data_keys[] = 'notset';
241
		$this->test_data_keys   = array_merge( $this->test_data_keys, $keys );
242
243
		unset( $test_array, $legend_array, $key_array );
244
	}
245
246
247
	/**
248
	 * Sort the test data via a set order - callback method.
249
	 *
250
	 * @param mixed $var_a
251
	 * @param mixed $var_b
252
	 *
253
	 * @return int
254
	 */
255
	function sort_test_data( $var_a, $var_b ) {
256
		$primary_order = array(
257
			'n', // Type null.
258
			'b', // Type boolean.
259
			'i', // Type integer.
260
			'f', // Type float.
261
			's', // Type string.
262
			'a', // Type array.
263
			'o', // Type object.
264
			'r', // Type resource.
265
			'p', // Type SPL_Types object.
266
		);
267
268
		// phpcs:disable WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine -- for readability.
269
		$secondary_order = array(
270
			'e', // Empty.
271
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
272
			'a', 'b', 'c', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
273
			'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
274
		);
275
		// phpcs:enable WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine
276
277
		$primary_a = array_search( substr( $var_a, 0, 1 ), $primary_order, true );
278
		$primary_b = array_search( substr( $var_b, 0, 1 ), $primary_order, true );
279
280
		if ( $primary_a !== $primary_b ) {
281
			return ( ( $primary_a < $primary_b ) ? -1 : 1 );
282
		}
283
284
		$secondary_a = array_search( substr( $var_a, 1 ), $secondary_order, true );
285
		$secondary_b = array_search( substr( $var_b, 1 ), $secondary_order, true );
286
287
		if ( $secondary_a !== $secondary_b ) {
288
			return ( ( $secondary_a < $secondary_b ) ? -1 : 1 );
289
		}
290
291
		return 0;
292
	}
293
294
295
	/**
296
	 * Housekeeping so the variables can be re-initiated properly.
297
	 */
298
	function clean_up() {
299
		$clean_this = array(
300
			'r1' => 'fclose',
301
			'r2' => 'imagedestroy',
302
		);
303
304
		foreach ( $clean_this as $key => $function ) {
305
			if ( isset( $GLOBALS['test_array'], $GLOBALS['test_array'][ $key ] ) && is_resource( $GLOBALS['test_array'][ $key ] ) ) {
306
				$function( $GLOBALS['test_array'][ $key ] );
307
			}
308
			if ( isset( $this->test_data, $this->test_data[ $key ] ) && is_resource( $this->test_data[ $key ] ) ) {
309
				$function( $this->test_data[ $key ] );
310
			}
311
		}
312
	}
313
314
315
	/**
316
	 * Generate the subsection tabs (at the top of the page) for the cheatsheet.
317
	 *
318
	 * @param bool $all
319
	 */
320
	function print_tabs( $all = false ) {
321
		echo '
322
	<ul>';
323
324
		foreach ( $this->test_groups as $key => $test_group ) {
325
			$active_class = '';
326
			if ( $GLOBALS['tab'] === $key ) {
327
				$active_class = ' class="ui-tabs-active ui-state-active"';
328
			}
329
330 View Code Duplication
			if ( $all === true ) {
331
				echo '
332
		<li><a href="#', $key, '" data-tab="', $key, '" data-tab-title="', $test_group['title'], '"><strong>', $test_group['title'], '</strong></a></li>';
333
			}
334
			else {
335
				echo '
336
		<li', $active_class, '><a href="', BASE_URI, $GLOBALS['type'], '/', $key, '/ajax" data-tab="', $key, '" data-tab-title="', $test_group['title'], '"><strong>', $test_group['title'], '</strong></a></li>';
337
			}
338
		}
339
		unset( $key, $test_group );
340
341
		echo '
342
	</ul>';
343
	}
344
345
346
	/**
347
	 * Print all tables for the cheatsheet.
348
	 */
349
	function print_tables() {
350
351
		echo '
352
	<div class="tables">';
353
354
		foreach ( $this->test_groups as $key => $group_settings ) {
355
			$this->set_test_data( $key );
356
			$this->print_table( $key );
357
		}
358
		unset( $key, $group_settings );
359
360
		echo '
361
	</div><!-- end of div.tables -->';
362
	}
363
364
365
	/**
366
	 * Generate the table for one specific subsection of a cheatsheet.
367
	 *
368
	 * @param string $test_group The current subsection.
369
	 */
370
	function print_table( $test_group ) {
371
372
		if ( isset( $this->test_groups[ $test_group ] ) ) {
373
			$GLOBALS['encountered_errors'] = array();
374
375
			echo '
376
		<div id="', $test_group, '">';
377
378
			if ( isset( $this->test_groups[ $test_group ]['urls'] ) && ( is_array( $this->test_groups[ $test_group ]['urls'] ) && count( $this->test_groups[ $test_group ]['urls'] ) > 0 ) ) {
379
				echo '<p>References:</p><ul>';
380
				foreach ( $this->test_groups[ $test_group ]['urls'] as $url ) {
381
					printf( '<li><a href="%1$s" target="_blank">%1$s</a></li>', $url );
382
				}
383
				unset( $url );
384
				echo '</ul>';
385
			}
386
387
388
			$this->print_tabletop( $test_group );
389
390
			$last_key = null;
391
392
			foreach ( $this->test_data_keys as $key ) {
393
				$value  = $this->test_data[ $key ];
394
				$legend = '';
395 View Code Duplication
				if ( isset( $this->test_legend[ $key ] ) ) {
396
					$legend = '<sup class="fright"><a href="#var-legend-' . $key . '">&dagger;' . $key . '</a></sup>';
397
				}
398
399
				$type = substr( $key, 0, 1 );
400
401
				$class = array();
402
				if ( $type !== $last_key ) {
403
					$class[]  = 'new-var-type';
404
					$last_key = $type;
405
				}
406
				if ( isset( $this->test_groups[ $test_group ]['target'] ) && $this->test_groups[ $test_group ]['target'] === $type ) {
407
					$class[] = 'target';
408
				}
409
410
411 View Code Duplication
				if ( count( $class ) > 0 ) {
412
					echo '
413
				<tr class="', implode( ' ', $class ), '">';
414
				}
415
				else {
416
					echo '
417
				<tr>';
418
				}
419
420
421
				$label = get_var( $value, '', true );
422
423
				echo '
424
					<th>', $legend, '$x = ', $label, '
425
					</th>';
426
427
				$this->print_row_cells( $value, $test_group );
428
429
				echo '
430
					<th>', $legend, '$x = ', $label, '
431
					</th>
432
				</tr>';
433
			}
434
435
			echo '
436
			</tbody>
437
			</table>';
438
439
			$this->print_error_footnotes( $test_group );
440
			$this->print_other_footnotes( $test_group );
441
442
443
			echo '
444
		</div><!-- end of div#', $test_group, ' -->';
445
		}
446
		else {
447
			trigger_error( 'Unknown test group <b>' . $test_group . '</b>', E_USER_WARNING );
448
		}
449
	}
450
451
452
	/**
453
	 * Generate the first row of the cheatsheet table.
454
	 *
455
	 * @param string $test_group The current subsection.
456
	 *
457
	 * @return string
458
	 */
459
	function create_table_header( $test_group ) {
460
461
		$this->table_notes = array(); // Make sure we start with an empty array.
462
		$group_label       = $this->get_table_header_group_label( $test_group );
463
464
		$html = '
465
				<tr>
466
					' . $group_label;
467
468
		foreach ( $this->test_groups[ $test_group ]['tests'] as $test ) {
469
			$class   = $this->get_table_header_cell_class( $test_group, $test );
470
			$tooltip = ( isset( $this->tests[ $test ]['tooltip'] ) ? ' title="' . htmlspecialchars( $this->tests[ $test ]['tooltip'], ENT_QUOTES, 'UTF-8' ) . '"' : '' );
471
472
			$html .= '
473
					<th' . $class . '>' .
474
					( ( isset( $this->tests[ $test ]['url'] ) && $this->tests[ $test ]['url'] !== '' ) ? '<a href="' . $this->tests[ $test ]['url'] . '" target="_blank"' . $tooltip . '>' : '' ) .
475
					$this->tests[ $test ]['title'] .
476
					( ( isset( $this->tests[ $test ]['url'] ) && $this->tests[ $test ]['url'] !== '' ) ? '</a>' : '' );
477
478
479
			$html .= $this->get_table_header_note_indicators( $test, $test_group );
480
			$html .= '</th>';
481
482
			unset( $class, $tooltip );
483
		}
484
485
		$html .= '
486
					' . $group_label . '
487
				</tr>';
488
489
		return $html;
490
	}
491
492
493
	/**
494
	 * Get the - potentially linked - group label (= first cell in the table header).
495
	 *
496
	 * @param string $test_group The current subsection.
497
	 *
498
	 * @return string
499
	 */
500
	function get_table_header_group_label( $test_group ) {
501
		if ( isset( $this->test_groups[ $test_group ]['book_url'] ) && $this->test_groups[ $test_group ]['book_url'] !== '' ) {
502
			$group_label = '<th class="label-col"><a href="' . $this->test_groups[ $test_group ]['book_url'] . '" target="_blank">' . $this->test_groups[ $test_group ]['title'] . '</a></th>';
503
		}
504
		else {
505
			$group_label = '<th class="label-col">' . $this->test_groups[ $test_group ]['title'] . '</th>';
506
		}
507
508
		return $group_label;
509
	}
510
511
512
	/**
513
	 * Get the notes related to the group label, if any.
514
	 *
515
	 * @param string $test
516
	 * @param string $test_group
517
	 *
518
	 * @return string
519
	 */
520
	function get_table_header_note_indicators( $test, $test_group ) {
521
		$notes = '';
522
523
		if ( isset( $this->tests[ $test ]['notes'] ) && ( is_array( $this->tests[ $test ]['notes'] ) && count( $this->tests[ $test ]['notes'] ) > 0 ) ) {
524
525
			$this->table_notes = array_merge( $this->table_notes, $this->tests[ $test ]['notes'] );
526
			$this->table_notes = array_unique( $this->table_notes );
527
528
			foreach ( $this->tests[ $test ]['notes'] as $note ) {
529
				$note_id = array_search( $note, $this->table_notes, true );
530
				if ( $note_id !== false ) {
531
					$notes .= ' <sup><a href="#' . $test_group . '-note' . ( $note_id + 1 ) . '">&Dagger;' . ( $note_id + 1 ) . '</a></sup>';
532
				}
533
			}
534
		}
535
		return $notes;
536
	}
537
538
539
	/**
540
	 * Get the CSS class string to attach to a table header cell.
541
	 *
542
	 * @param string $test_group
543
	 * @param string $test
544
	 *
545
	 * @return string
546
	 */
547
	function get_table_header_cell_class( $test_group, $test ) {
548
		$class = array();
549
550
		foreach ( $this->table_header_class_map as $group_key => $classname ) {
551
			if ( isset( $this->test_groups[ $test_group ][ $group_key ] ) && in_array( $test, $this->test_groups[ $test_group ][ $group_key ], true ) ) {
552
				$class[] = $classname;
553
			}
554
		}
555
		$class = ( ( count( $class ) > 0 ) ? ' class="' . implode( ' ', $class ) . '"' : '' );
556
557
		return $class;
558
	}
559
560
561
	/**
562
	 * Generate the html for the table top.
563
	 *
564
	 * @param string $test_group The current subsection.
565
	 */
566
	function print_tabletop( $test_group ) {
567
568
		$header = $this->create_table_header( $test_group );
569
570
		echo '
571
		<table id="', $test_group, '-table" cellpadding="0" cellspacing="0" border="0">
572
		<thead>', $header, '
573
		</thead>
574
		<tfoot>', $header, '
575
		</tfoot>
576
		<tbody>';
577
	}
578
579
580
	/**
581
	 * Generate a cheatsheet result row.
582
	 *
583
	 * @param mixed  $value      The value this row applies to.
584
	 * @param string $test_group The current subsection.
585
	 */
586
	function print_row_cells( $value, $test_group ) {
587
588
		foreach ( $this->test_groups[ $test_group ]['tests'] as $key => $test ) {
589
			$GLOBALS['has_error'] = array();
590
591
			$class = $this->get_table_row_cell_class( $test_group, $test );
592
593
			echo '
594
					<td' . $class . '>';
595
596
			$val = $this->generate_value( $value );
597
			$this->tests[ $test ]['test']( $val );
598
			$this->print_row_cell_error_refs();
599
600
			echo '					</td>';
601
602
			unset( $class, $GLOBALS['has_error'] );
603
		}
604
		unset( $test );
605
	}
606
607
608
	/**
609
	 * Get the CSS class string to attach to a table cell.
610
	 *
611
	 * @param string $test_group
612
	 * @param string $test
613
	 *
614
	 * @return string
615
	 */
616
	function get_table_row_cell_class( $test_group, $test ) {
617
		$class = array( $test );
618
		if ( in_array( $test, $this->test_groups[ $test_group ]['best'], true ) ) {
619
			$class[] = 'best';
620
		}
621 View Code Duplication
		else if ( in_array( $test, $this->test_groups[ $test_group ]['good'], true ) ) {
622
			$class[] = 'good';
623
		}
624 View Code Duplication
		if ( in_array( $test, $this->test_groups[ $test_group ]['break_at'], true ) ) {
625
			$class[] = 'end';
626
		}
627
628
		$class = ( ( count( $class ) > 0 ) ? ' class="' . implode( ' ', $class ) . '"' : '' );
629
630
		return $class;
631
	}
632
633
634
	/**
635
	 * Print the error reference numbers.
636
	 *
637
	 * Used in table cells to link to errors which will be displayed as footnotes.
638
	 */
639
	function print_row_cell_error_refs() {
640
		if ( is_array( $GLOBALS['has_error'] ) && count( $GLOBALS['has_error'] ) > 0 ) {
641
			foreach ( $GLOBALS['has_error'] as $error ) {
642 View Code Duplication
				if ( isset( $error['msg'] ) && $error['msg'] !== '' ) {
643
					echo '<br />', $error['msg'];
644
				}
645
			}
646
		}
647
	}
648
649
650
	/**
651
	 * Get the value to use for the tests.
652
	 *
653
	 * If in PHP5 and the value is an object, it will clone the object so we'll have a 'clean' object
654
	 * for each test (not a reference).
655
	 *
656
	 * @param mixed $value
657
	 *
658
	 * @return mixed
659
	 */
660
	function generate_value( $value ) {
661
		if ( method_exists( 'VartypePHP5', 'generate_value' ) ) {
662
			$value = VartypePHP5::generate_value( $value );
663
		}
664
		return $value;
665
	}
666
667
668
	/**
669
	 * Generate footnotes for any errors encountered.
670
	 *
671
	 * @param string $test_group The current subsection.
672
	 */
673
	function print_error_footnotes( $test_group ) {
674
		// Encountered errors footnote/appendix.
675
		if ( count( $GLOBALS['encountered_errors'] ) > 0 ) {
676
			echo '
677
			<ol id="', $test_group, '-errors" class="error-appendix">';
678
			foreach ( $GLOBALS['encountered_errors'] as $error ) {
679
				echo '
680
				<li>', $error, '</li>';
681
			}
682
			echo '
683
			</ol>';
684
		}
685
		unset( $GLOBALS['encountered_errors'] );
686
	}
687
688
689
	/**
690
	 * Generate footnotes for a test subsection if applicable.
691
	 *
692
	 * @param string $test_group The current subsection.
693
	 */
694
	function print_other_footnotes( $test_group ) {
695
		if ( is_array( $this->table_notes ) && count( $this->table_notes ) > 0 ) {
696
			foreach ( $this->table_notes as $key => $note ) {
697
				printf(
698
					'
699
			<div id="%1$s-note%2$s" class="note-appendix">
700
				<sup>&Dagger; %2$s</sup> %3$s
701
			</div>',
702
					$test_group,
703
					( $key + 1 ),
704
					$note
705
				);
706
			}
707
		}
708
		$this->table_notes = array(); // Reset property.
709
	}
710
}
711