Passed
Push — develop ( 5e8f92...83d763 )
by Paul
03:00
created

Settings::addPage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 12
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\Pollux\Settings;
4
5
use GeminiLabs\Pollux\Application;
6
use GeminiLabs\Pollux\Facades\SiteMeta;
7
use GeminiLabs\Pollux\Helper;
8
use GeminiLabs\Pollux\MetaBox\MetaBox;
9
use GeminiLabs\Pollux\Settings\RWMetaBox;
10
11
class Settings extends MetaBox
12
{
13
	/**
14
	 * @var string
15
	 */
16
	const ID = 'settings';
17
18
	/**
19
	 * @var array
20
	 */
21
	public static $conditions = [
22
		'class_exists', 'defined', 'function_exists', 'hook', 'is_plugin_active',
23
		'is_plugin_inactive',
24
	];
25
26
	/**
27
	 * @var string
28
	 */
29
	public $hook;
30
31
	/**
32
	 * @return string
33
	 */
34
	public static function id()
35
	{
36
		return apply_filters( sprintf( 'pollux/%s/id', static::ID ), Application::prefix() . static::ID );
37
	}
38
39
	/**
40
	 * {@inheritdoc}
41
	 */
42
	public function init()
43
	{
44
		// @todo: run GateKeeper to check dependencies and capability (make sure it it run on the correct hook!)
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
45
		// if( !is_plugin_active( 'meta-box/meta-box.php' ))return;
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
46
47
		$this->normalize( $this->app->config[ static::ID ]);
48
49
		add_action( 'admin_menu',                        [$this, 'addPage'] );
50
		add_action( 'pollux/'.static::ID.'/init',        [$this, 'addSubmitMetaBox'] );
51
		add_action( 'current_screen',                    [$this, 'register'] );
52
		add_action( 'admin_menu',                        [$this, 'registerSetting'] );
53
		add_action( 'pollux/'.static::ID.'/init',        [$this, 'reset'] );
54
		add_action( 'admin_print_footer_scripts',        [$this, 'renderFooterScript'] );
55
		add_filter( 'pollux/'.static::ID.'/instruction', [$this, 'filterInstruction'], 10, 3 );
56
		add_filter( 'wp_redirect',                       [$this, 'filterRedirectOnSave'] );
57
	}
58
59
	/**
60
	 * @return void
61
	 */
62
	public function action()
63
	{
64
		$args = func_get_args();
65
		$hook = sprintf( 'pollux/%s/%s', static::ID, array_shift( $args ));
66
		return do_action_ref_array( $hook, array_filter( $args ));
67
	}
68
69
	/**
70
	 * @return void
71
	 * @action admin_menu
72
	 */
73 View Code Duplication
	public function addPage()
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...
74
	{
75
		$this->hook = call_user_func_array( 'add_menu_page', $this->filter( 'page', [
76
			__( 'Site Settings', 'pollux' ),
77
			__( 'Site Settings', 'pollux' ),
78
			'edit_theme_options',
79
			static::id(),
80
			[$this, 'renderPage'],
81
			'dashicons-screenoptions',
82
			1313
83
		]));
84
	}
85
86
	/**
87
	 * @return void
88
	 * @action pollux/{static::ID}/init
89
	 */
90
	public function addSubmitMetaBox()
91
	{
92
		call_user_func_array( 'add_meta_box', $this->filter( 'metabox/submit', [
93
			'submitdiv',
94
			__( 'Save Settings', 'pollux' ),
95
			[$this, 'renderSubmitMetaBox'],
96
			$this->hook,
97
			'side',
98
			'high',
99
		]));
100
	}
101
102
	/**
103
	 * @return mixed
104
	 */
105
	public function filter()
106
	{
107
		$args = func_get_args();
108
		$hook = sprintf( 'pollux/%s/%s', static::ID, array_shift( $args ));
109
		return apply_filters_ref_array( $hook, array_filter( $args ));
110
	}
111
112
	/**
113
	 * @param string $instruction
114
	 * @param string $fieldId
115
	 * @param string $metaboxId
116
	 * @return string
117
	 * @action pollux/{static::ID}/instruction
118
	 */
119
	public function filterInstruction( $instruction, $fieldId, $metaboxId )
120
	{
121
		return sprintf( "SiteMeta::get('%s', '%s');", $metaboxId, $fieldId );
122
	}
123
124
	/**
125
	 * @param string $location
126
	 * @return string
127
	 * @filter wp_redirect
128
	 */
129
	public function filterRedirectOnSave( $location )
130
	{
131
		if( strpos( $location, 'settings-updated=true' ) === false
132
			|| strpos( $location, sprintf( 'page=%s', static::id() )) === false ) {
133
			return $location;
134
		}
135
		return add_query_arg([
136
			'page' => static::id(),
137
			'settings-updated' => 'true',
138
		], admin_url( 'admin.php' ));
139
	}
140
141
	/**
142
	 * @param null|array $settings
143
	 * @return array
144
	 * @callback register_setting
145
	 */
146
	public function filterSavedSettings( $settings )
147
	{
148
		if( is_null( $settings )) {
149
			$settings = [];
150
		}
151
		$this->action( 'saved' );
152
		return $this->filter( 'save', $settings );
153
	}
154
155
	/**
156
	 * @return void
157
	 * @action current_screen
158
	 */
159
	public function register()
160
	{
161
		if(( new Helper )->getCurrentScreen()->id != $this->hook )return;
162
		foreach( parent::register() as $metabox ) {
163
			new RWMetaBox( $metabox );
164
		}
165
		add_screen_option( 'layout_columns', [
166
			'max' => 2,
167
			'default' => 2,
168
		]);
169
		$this->action( 'init' );
170
	}
171
172
	/**
173
	 * @return void
174
	 * @action admin_menu
175
	 */
176
	public function registerSetting()
177
	{
178
		register_setting( static::id(), static::id(), [$this, 'filterSavedSettings'] );
179
	}
180
181
	/**
182
	 * @return void
183
	 * @action admin_print_footer_scripts
184
	 */
185
	public function renderFooterScript()
186
	{
187
		if(( new Helper )->getCurrentScreen()->id != $this->hook )return;
188
		$this->render( 'settings/script', [
189
			'confirm' => __( 'Are you sure want to do this?', 'pollux' ),
190
			'hook' => $this->hook,
191
			'id' => static::id(),
192
		]);
193
	}
194
195
	/**
196
	 * @return void
197
	 * @callback add_menu_page
198
	 */
199
	public function renderPage()
200
	{
201
		$this->render( 'settings/index', [
202
			'columns' => get_current_screen()->get_columns(),
203
			'heading' => __( 'Site Settings', 'pollux' ),
204
			'id' => static::id(),
205
		]);
206
	}
207
208
	/**
209
	 * @return void
210
	 * @callback add_meta_box
211
	 */
212
	public function renderSubmitMetaBox()
213
	{
214
		$query = [
215
			'_wpnonce' => wp_create_nonce( $this->hook ),
216
			'action' => 'reset',
217
			'page' => static::id(),
218
		];
219
		$this->render( 'settings/submit', [
220
			'reset' => __( 'Reset', 'pollux' ),
221
			'reset_url' => esc_url( add_query_arg( $query, admin_url( 'admin.php' ))),
222
			'submit' => get_submit_button( __( 'Save', 'pollux' ), 'primary', 'submit', false ),
223
		]);
224
	}
225
226
	/**
227
	 * @return void
228
	 * @action pollux/{static::ID}/init
229
	 */
230
	public function reset()
231
	{
232
		if( filter_input( INPUT_GET, 'page' ) !== static::id()
233
			|| filter_input( INPUT_GET, 'action' ) !== 'reset'
234
		)return;
235
		if( wp_verify_nonce( filter_input( INPUT_GET, '_wpnonce' ), $this->hook )) {
236
			update_option( static::id(), $this->getDefaults() );
237
			return add_settings_error( static::id(), 'reset', __( 'All values have been reset to defaults.', 'pollux' ), 'updated' );
238
		}
239
		add_settings_error( static::id(), 'reset', __( 'Failed to reset values. Please refresh the page and try again.', 'pollux' ));
240
	}
241
242
	/**
243
	 * @param string $key
244
	 * @return array
245
	 */
246
	protected function filterArrayByKey( array $array, $key )
247
	{
248
		return array_filter( $array, function( $value ) use( $key ) {
249
			return !empty( $value[$key] );
250
		});
251
	}
252
253
	/**
254
	 * @return array
255
	 */
256
	protected function getDefaults()
257
	{
258
		$metaboxes = $this->filterArrayByKey( $this->metaboxes, 'slug' );
259
260
		array_walk( $metaboxes, function( &$metabox ) {
261
			$fields = array_map( function( $field ) {
262
				$field = wp_parse_args( $field, ['std' => ''] );
263
				return [$field['slug'] => $field['std']];
264
			}, $this->filterArrayByKey( $metabox['fields'], 'slug' ));
265
			$metabox = [
266
				$metabox['slug'] => call_user_func_array( 'array_merge', $fields ),
267
			];
268
		});
269
		return call_user_func_array( 'array_merge', $metaboxes );
270
	}
271
272
	/**
273
	 * @return string|array
274
	 */
275
	protected function getValue( $key, $group )
276
	{
277
		return SiteMeta::get( $group, $key, false );
278
	}
279
280
	/**
281
	 * @param string $name
282
	 * @param string $parentId
283
	 * @return string
284
	 */
285
	protected function normalizeFieldName( $name, array $data, $parentId )
286
	{
287
		if( !empty( $name )) {
288
			return $name;
289
		}
290
		$name = str_replace( sprintf( '%s-%s-', static::id(), $parentId ), '', $data['id'] );
291
		return sprintf( '%s[%s][%s]', static::id(), $parentId, $name );
292
	}
293
294
	/**
295
	 * @param string $id
296
	 * @param string $parentId
297
	 * @return string
298
	 */
299
	protected function normalizeId( $id, array $data, $parentId )
300
	{
301
		return $parentId == $id
302
			? sprintf( '%s-%s', static::id(), $id )
303
			: sprintf( '%s-%s-%s', static::id(), $parentId, $id );
304
	}
305
}
306