Completed
Push — master ( 02e362...3c05a4 )
by Fulvio
04:00
created

SettingsPage::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
/**
3
 * WP PHP Console
4
 *
5
 * This source file is subject to the GNU General Public License v3.0
6
 * that is bundled with this package in the file license.txt.
7
 * It is also available through the world-wide-web at this URL:
8
 * http://www.gnu.org/licenses/gpl-3.0.html
9
 *
10
 * @author    Fulvio Notarstefano <[email protected]>
11
 * @copyright Copyright (c) 2014-2019 Fulvio Notarstefano
12
 * @license   http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
13
 */
14
15
namespace WP_PHP_Console\Admin;
16
17
use WP_PHP_Console\Plugin;
18
use WP_PHP_Console\Settings;
19
20
defined( 'ABSPATH' ) or exit;
21
22
/**
23
 * WP PHP Console settings page.
24
 *
25
 * @since 1.6.0
26
 */
27
class SettingsPage {
28
29
30
	/** @var string the plugin's settings page slug */
31
	private $page_id;
32
33
	/** @var string the plugin's settings option key name */
34
	private $option_key;
35
36
	/** @var array settings options */
37
	private $options;
38
39
40
	/**
41
	 * Registers settings and admin menu.
42
	 *
43
	 * @since 1.6.0
44
	 */
45
	public function __construct() {
46
47
		$this->page_id    = str_replace( '-', '_', Plugin::ID );
48
		$this->option_key = Settings::get_settings_key();
49
		$this->options    = Settings::get_settings();
50
51
		add_action( 'admin_menu', function() { $this->register_settings_page(); } );
52
		add_action( 'admin_init', function() { $this->register_settings(); } );
53
	}
54
55
56
	/**
57
	 * Adds a plugin Settings menu.
58
	 *
59
	 * @since 1.6.0
60
	 */
61
	private function register_settings_page() {
62
63
		add_options_page(
64
			Plugin::NAME,
65
			Plugin::NAME,
66
			'manage_options',
67
			$this->page_id,
68
			[ $this, 'output_settings_page' ]
69
		);
70
	}
71
72
73
	/**
74
	 * Registers the plugin settings.
75
	 *
76
	 * @since 1.6.0
77
	 */
78
	private function register_settings() {
79
80
		register_setting(
81
			$this->option_key,
82
			$this->option_key,
83
			[ $this, 'sanitize_field' ]
84
		);
85
86
		add_settings_section(
87
			$this->option_key,
88
			__( 'Settings', 'wp-php-console' ),
89
			[ $this, 'output_settings_instructions' ],
90
			$this->page_id
91
		);
92
93
		$settings_fields = [
94
			'password' => [
95
				'label' => esc_html__( 'Password', 'wp-php-console' ),
96
				'args'  => [
97
					'id'       => 'password',
98
					'type'     => 'password',
99
					'required' => true,
100
				]
101
			],
102
			'ssl' => [
103
				'label' => esc_html__( 'Allow only on SSL', 'wp-php-console' ),
104
				'args'  => [
105
					'id'   => 'ssl',
106
					'type' => 'checkbox',
107
				]
108
			],
109
			'ip' => [
110
				'label' => esc_html__( 'Allowed IP Masks', 'wp-php-console' ),
111
				'args'  => [
112
					'id'   => 'ip',
113
					'type' => 'text',
114
				]
115
			],
116
			'register' => [
117
				'label' => esc_html__( 'Register PC Class', 'wp-php-console' ),
118
				'args'  => [
119
					'id'   => 'register',
120
					'type' => 'checkbox',
121
				]
122
			],
123
			'stack' => [
124
				'label' => esc_html__( 'Show Call Stack', 'wp-php-console' ),
125
				'args'  => [
126
					'id'   => 'stack',
127
					'type' => 'checkbox',
128
				]
129
			],
130
			'short' => [
131
				'label' => esc_html__( 'Short Path Names', 'wp-php-console' ),
132
				'args'  => [
133
					'id'   => 'short',
134
					'type' => 'checkbox',
135
				]
136
			],
137
		];
138
139
		foreach ( $settings_fields as $key => $field ) {
140
			add_settings_field(
141
				$this->page_id . '['. $key . ']',
142
				$field['label'],
143
				[ $this, 'output_input_field' ],
144
				$this->page_id,
145
				$this->option_key,
146
				$field['args']
147
			);
148
		}
149
	}
150
151
152
	/**
153
	 * Outputs settings page additional info.
154
	 *
155
	 * Prints more details on the plugin settings page.
156
	 *
157
	 * @internal callback method
158
	 *
159
	 * @since 1.6.0
160
	 */
161
	public function output_settings_instructions() {
162
163
		?>
164
		<p><?php printf(
165
				/* translators: Placeholder: %s refers to the PHP Console library, pointing to its GitHub repository */
166
				_x( 'This plugin allows you to use %s within your WordPress installation for testing, debugging and development purposes.', 'PHP Console, the PHP Library', 'wp-php-console' ),
167
				'<a href="' . esc_url( Plugin::get_php_console_project_page_url() ) . '" target="_blank">PHP Console</a>'
168
			);
169
		?></p>
170
		<h4><?php esc_html_e( 'Usage instructions:', 'wp-php-console' ); ?></h4>
171
		<ol>
172
			<?php
173
174
			$instructions = [
175
				sprintf(
176
					/* translators: Placeholder: %s represents the Google Chrome PHP Console extension download link */
177
					_x( 'Make sure you have downloaded and installed %s.', 'PHP Console, the Chrome Extension', 'wp-php-console' ),
178
					'<a target="_blank" href="' . esc_url( Plugin::get_php_console_chrome_extension_url() ) .'">PHP Console extension for Google Chrome</a>'
179
				),
180
				esc_html__( 'Set a password for the eval terminal in the options below and hit "Save Changes".', 'wp-php-console' ),
181
				esc_html__( 'Reload any page of your installation and click on the key icon in your Chrome browser address bar, enter your password and access the terminal.', 'wp-php-console' ),
182
				esc_html__( 'From the eval terminal you can execute any PHP or WordPress specific function, including functions from your plugins and active theme.', 'wp-php-console' ),
183
				sprintf(
184
					/* translators: Placeholders: %1$s - PHP code snippet example, %2$s - Chrome javascript console shortcut */
185
					__( 'In your PHP code, you can call PHP Console debug statements like %1$s to display PHP variables in the browser\'s JavaScript-console (e.g. %2$s) and optionally filter selected tags through the browser\'s Remote PHP Eval Terminal screen\'s "Ignore Debug options".', 'wp-php-console' ),
186
					'<code>debug(&#36;var, &#36;tag)</code>',
187
					'<code>CTRL+SHIFT+J</code>'
188
				),
189
			];
190
191
			foreach ( $instructions as $list_item ) :
192
				?><li><?php echo $list_item; ?></li><?php
193
			endforeach;
194
195
			?>
196
		</ol>
197
		<hr>
198
		<?php
199
	}
200
201
202
	/**
203
	 * Gets the field ID.
204
	 *
205
	 * @since 1.6.0
206
	 *
207
	 * @param array $field field arguments
208
	 * @return string
209
	 */
210
	private function get_field_id( array $field ) {
211
212
		return $this->page_id . '-' . $field['id'];
213
	}
214
215
216
	/**
217
	 * Gets the field name.
218
	 *
219
	 * @since 1.6.0
220
	 *
221
	 * @param array $field field arguments
222
	 * @return string
223
	 */
224
	private function get_field_name( array $field ) {
225
226
		return str_replace( '-', '_', $this->page_id . '[' . $field['id'] . ']' );
227
	}
228
229
230
	/**
231
	 * Gets the field current value.
232
	 *
233
	 * @since 1.6.0
234
	 *
235
	 * @param array $field field arguments
236
	 * @return int|string|bool
237
	 */
238
	private function get_field_value( array $field ) {
239
240
		return $this->options[ $field['id'] ];
241
	}
242
243
244
	/**
245
	 * Outputs an input field.
246
	 *
247
	 * @internal callback method
248
	 *
249
	 * @since 1.6.0
250
	 *
251
	 * @param array $args
252
	 */
253
	public function output_input_field( array $args = [] ) {
254
255
		if ( empty( $args ) ) {
256
			return;
257
		}
258
259
		switch ( $args['type'] ) {
260
			case 'password' :
261
			case 'text' :
262
				$this->output_input_text_field( $args );
263
				break;
264
			case 'checkbox' :
265
				$this->output_checkbox_field( $args );
266
			break;
267
		}
268
	}
269
270
271
	/**
272
	 * Outputs a text input field.
273
	 *
274
	 * @since 1.6.0
275
	 *
276
	 * @param array $args
277
	 */
278
	private function output_input_text_field( $args = [] ) {
279
280
		?>
281
		<label>
282
			<input
283
				type="<?php echo isset( $args['type'] ) ? esc_attr( $args['type'] ) : 'text'; ?>"
284
				id="<?php echo esc_attr( $this->get_field_id( $args ) ); ?>"
285
				name="<?php echo esc_attr( $this->get_field_name( $args ) ); ?>"
286
				value="<?php echo esc_attr( $this->get_field_value( $args ) ); ?>"
287
			>
288
			<?php if ( ! empty( $args['required'] ) ) : ?>
289
				<span style="color:red;" title="<?php esc_attr_e( 'Required', 'wp-php-console' ); ?>">*</span>
290
			<?php endif; ?>
291
		</label>
292
		<?php
293
294
		switch ( $args['id'] ) :
295
296
			case 'ip' :
297
				$this->output_ip_field_instructions();
298
				break;
299
300
			case 'password' :
301
				$this->output_password_field_instructions();
302
				break;
303
304
		endswitch;
305
	}
306
307
308
	/**
309
	 * Outputs the "Password" field instructions.
310
	 *
311
	 * @since 1.6.0
312
	 */
313
	private function output_password_field_instructions() {
314
315
		?>
316
		<p class="description"><?php esc_html_e( 'The password for the eval terminal. If empty, the connector will not work.', 'wp-php-console' ); ?></p>
317
		<?php
318
	}
319
320
321
	/**
322
	 * Outputs the "IP range" field instructions.
323
	 *
324
	 * @since 1.6.0
325
	 */
326
	private function output_ip_field_instructions() {
327
328
		?>
329
		<p class="description"><?php esc_html_e( 'You may specify any of the following, to give access to specific IPs to the eval terminal:', 'wp-php-console' ); ?></p>
330
		<ol>
331
			<li><span class="description"><?php printf(
332
						/* translators: Placeholders: %1$s - a single IP address, %2$s link to Varying Vagrant Vagrants project repository */
333
						__( 'An IP address (for example %1$s, %2$s default IP address).', 'wp-php-console' ),
334
						'<code>192.168.50.4</code>',
335
						'<a href="https://github.com/Varying-Vagrant-Vagrants/VVV">Varying Vagrant Vagrants</a>'
336
					); ?></span></li>
337
			<li><span class="description"><?php printf(
338
						/* translators: Placeholders: %1$s a range of IP addresses, %2$s - comma separated IP addresses */
339
						__( 'A range of addresses (%1$s) or multiple addresses, comma separated (%2$s).', 'wp-php-console' ),
340
						'<code>192.168.*.*</code>',
341
						'<code>192.168.10.25,192.168.10.28</code>'
342
					); ?></span></li>
343
		</ol>
344
		<?php
345
	}
346
347
348
	/**
349
	 * Outputs a checkbox input field.
350
	 *
351
	 * @since 1.6.0
352
	 *
353
	 * @param array $args
354
	 */
355
	public function output_checkbox_field( array $args = [] ) {
356
357
		$field_id = esc_attr( $this->get_field_id( $args ) );
358
359
		?>
360
		<label>
361
			<input
362
				type="checkbox"
363
				id="<?php echo $field_id; ?>"
364
				name="<?php echo esc_attr( $this->get_field_name( $args ) ); ?>"
365
				value="1"
366
				<?php checked( (bool) $this->get_field_value( $args ) ); ?>
367
			><?php esc_html_e( 'Yes', 'wp-php-console' ); ?>
368
		</label>
369
		<?php
370
371
		switch ( $args['id'] ) :
372
373
			case 'register' :
374
				$this->output_register_pc_class_field_instructions();
375
				break;
376
377
			case 'short' :
378
				$this->output_show_short_paths_field_instructions();
379
				break;
380
381
			case 'ssl' :
382
				$this->output_ssl_field_instructions();
383
				break;
384
385
			case 'stack' :
386
				$this->output_show_call_stack_field_instructions();
387
				break;
388
389
		endswitch;
390
	}
391
392
393
	/**
394
	 * Outputs the "SSL option" field instructions.
395
	 *
396
	 * @since 1.6.0
397
	 */
398
	private function output_ssl_field_instructions() {
399
400
		?>
401
		<p class="description"><?php esc_html_e( 'Enable this option if you want the eval terminal to work only on a SSL connection.', 'wp-php-console' ); ?></p>
402
		<?php
403
	}
404
405
406
	/**
407
	 * Outputs the "Register PC class" field instructions.
408
	 *
409
	 * @since 1.6.0
410
	 */
411 View Code Duplication
	private function output_register_pc_class_field_instructions() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
412
413
		?>
414
		<p class="description"><?php
415
			esc_html_e( 'Enable to register PC class in the global namespace.', 'wp-php-console' );
416
			echo '<br>';
417
			printf(
418
				/* translators: Placeholders: %1$s, %2$s and %3$s are PHP code snippets examples */
419
				__( 'Allows to write %1$s or %2$s instructions in PHP to inspect %3$s in the JavaScript console.', 'wp-php-console' ),
420
				'<code>PC::debug(&#36;var, &#36;tag)</code>',
421
				'<code>PC::magic_tag(&#36;var)</code>',
422
				'<code>&#36;var</code>'
423
			); ?></p>
424
		<?php
425
	}
426
427
428
	/**
429
	 * Outputs the "Show Call Stack" field instructions.
430
	 *
431
	 * @since 1.6.0
432
	 */
433
	private function output_show_call_stack_field_instructions() {
434
435
		?>
436
		<p class="description"><?php esc_html_e( 'Enable to see the full call stack when PHP Console writes to the browser JavaScript console.', 'wp-php-console' ); ?></p>
437
		<?php
438
	}
439
440
441
	/**
442
	 * Outputs the "Show Short Paths" field field instructions.
443
	 *
444
	 * @since 1.6.0
445
	 */
446 View Code Duplication
	private function output_show_short_paths_field_instructions() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
447
448
		?>
449
		<p class="description"><?php
450
			esc_html_e( 'Enable to shorten the length of PHP Console error sources and traces paths in browser JavaScript console for better readability.', 'wp-php-console' );
451
			echo '<br>';
452
			printf(
453
				/* translators: Placeholders: %1$s - long server path, %2$s - shortened server path */
454
				__( 'Paths like %1$s will be displayed as %2$s', 'wp-php-console' ),
455
				'<code>/server/path/to/document/root/WP/wp-admin/admin.php:31</code>',
456
				'<code>/WP/wp-admin/admin.php:31</code>'
457
			); ?></p>
458
		<?php
459
	}
460
461
462
	/**
463
	 * Sanitizes user input in the settings page.
464
	 *
465
	 * @internal callback method
466
	 *
467
	 * @since 1.6.0
468
	 *
469
	 * @param array $option user input
470
	 * @return array sanitized input
471
	 */
472
	public function sanitize_field( $option ) {
473
474
		$input = wp_parse_args( $option, [
475
			'ip'       => '',
476
			'password' => '',
477
			'register' => false,
478
			'short'    => false,
479
			'ssl'      => false,
480
			'stack'    => false,
481
		] );
482
483
		$sanitized_input = [
484
			'ip'       => sanitize_text_field( $input['ip'] ),
485
			'password' => sanitize_text_field( $input['password'] ),
486
			'register' => ! empty( $input['register'] ),
487
			'short'    => ! empty( $input['short'] ),
488
			'ssl'      => ! empty( $input['ssl'] ),
489
			'stack'    => ! empty( $input['stack'] ),
490
		];
491
492
		return $sanitized_input;
493
	}
494
495
496
	/**
497
	 * Outputs the settings page.
498
	 *
499
	 * @internal callback method
500
	 *
501
	 * @since 1.6.0
502
	 */
503
	public function output_settings_page() {
504
505
		?>
506
		<div class="wrap">
507
			<h2><?php echo Plugin::NAME; ?></h2>
508
			<hr />
509
			<form method="post" action="options.php">
510
				<?php
511
512
				settings_fields( $this->option_key );
513
514
				do_settings_sections( $this->page_id );
515
516
				submit_button();
517
518
				?>
519
			</form>
520
		</div>
521
		<?php
522
	}
523
524
525
}
526