Passed
Branch master (3d135a)
by Paul
02:50
created

Settings::normalizeFieldName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 3
dl 0
loc 8
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\MetaBox\MetaBox;
7
use GeminiLabs\Pollux\Settings\RWMetaBox;
8
9
class Settings extends MetaBox
10
{
11
	/**
12
	 * @var string
13
	 */
14
	CONST ID = 'pollux_settings';
15
16
	/**
17
	 * @var string
18
	 */
19
	public $hook;
20
21
	/**
22
	 * @var string
23
	 */
24
	public $id;
25
26
	/**
27
	 * @var array
28
	 */
29
	protected static $conditions = [
30
		'hook', 'is_plugin_active', 'is_plugin_inactive',
31
	];
32
33
	/**
34
	 * {@inheritdoc}
35
	 */
36
	public function init()
37
	{
38
		// @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...
39
		// 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...
40
41
		$this->id = apply_filters( 'pollux/settings/option', static::ID );
42
43
		$this->normalize();
44
45
		add_action( 'admin_menu',                             [$this, 'addPage'] );
46
		add_action( 'pollux/settings/init',                   [$this, 'addSubmitMetaBox'] );
47
		add_action( 'current_screen',                         [$this, 'register'] );
48
		add_action( 'admin_menu',                             [$this, 'registerSetting'] );
49
		add_action( 'pollux/settings/init',                   [$this, 'reset'] );
50
		add_action( "admin_footer-toplevel_page_{$this->id}", [$this, 'renderFooterScript'] );
51
		add_filter( 'pollux/settings/instruction',            [$this, 'filterInstruction'], 10, 3 );
52
		add_filter( 'wp_redirect',                            [$this, 'filterRedirectOnSave'] );
53
	}
54
55
	/**
56
	 * @return void
57
	 * @action admin_menu
58
	 */
59
	public function addPage()
60
	{
61
		$this->hook = call_user_func_array( 'add_menu_page', apply_filters( 'pollux/settings/page', [
62
			__( 'Site Settings', 'pollux' ),
63
			__( 'Site Settings', 'pollux' ),
64
			'edit_theme_options',
65
			$this->id,
66
			[$this, 'renderPage'],
67
			'dashicons-screenoptions',
68
			1313
69
		]));
70
	}
71
72
	/**
73
	 * @return void
74
	 * @action pollux/settings/init
75
	 */
76
	public function addSubmitMetaBox()
77
	{
78
		call_user_func_array( 'add_meta_box', apply_filters( 'pollux/settings/metabox/submit', [
79
			'submitdiv',
80
			__( 'Save Settings', 'pollux' ),
81
			[ $this, 'renderSubmitMetaBox'],
82
			$this->hook,
83
			'side',
84
			'high',
85
		]));
86
	}
87
88
	/**
89
	 * @param string $instruction
90
	 * @param string $fieldId
91
	 * @param string $metaboxId
92
	 * @return string
93
	 * @filter pollux/settings/instruction
94
	 */
95
	public function filterInstruction( $instruction, $fieldId, $metaboxId )
96
	{
97
		return sprintf( "SiteMeta::get('%s', '%s');", $metaboxId, $fieldId );
98
	}
99
100
	/**
101
	 * @param string $location
102
	 * @return string
103
	 * @filter wp_redirect
104
	 */
105
	public function filterRedirectOnSave( $location )
106
	{
107
		if( strpos( $location, 'settings-updated=true' ) === false
108
			|| strpos( $location, sprintf( 'page=%s', $this->id )) === false ) {
109
			return $location;
110
		}
111
		return add_query_arg([
112
			'page' => $this->id,
113
			'settings-updated' => 'true',
114
		], admin_url( 'admin.php' ));
115
	}
116
117
	/**
118
	 * @param null|array $settings
119
	 * @return array
120
	 * @callback register_setting
121
	 */
122
	public function filterSavedSettings( $settings )
123
	{
124
		if( is_null( $settings )) {
125
			$settings = [];
126
		}
127
		return apply_filters( 'pollux/settings/save', $settings );
128
	}
129
130
	/**
131
	 * @return void
132
	 * @action current_screen
133
	 */
134
	public function register()
135
	{
136
		if( $this->app->screen()->id != $this->hook )return;
137
		foreach( parent::register() as $metabox ) {
138
			new RWMetaBox( $metabox );
139
		}
140
		add_screen_option( 'layout_columns', [
141
			'max' => 2,
142
			'default' => 2,
143
		]);
144
		do_action( 'pollux/settings/init' );
145
	}
146
147
	/**
148
	 * @return void
149
	 * @action admin_menu
150
	 */
151
	public function registerSetting()
152
	{
153
		register_setting( $this->id, $this->id, [$this, 'filterSavedSettings'] );
154
	}
155
156
	/**
157
	 * @return void
158
	 * @action admin_footer-toplevel_page_{$this->id}
159
	 */
160
	public function renderFooterScript()
161
	{
162
		$this->render( 'settings/script', [
163
			'confirm' => __( 'Are you sure want to do this?', 'pollux' ),
164
			'hook' => $this->hook,
165
			'id' => $this->id,
166
		]);
167
	}
168
169
	/**
170
	 * @return void
171
	 * @callback add_menu_page
172
	 */
173
	public function renderPage()
174
	{
175
		$this->render( 'settings/index', [
176
			'columns' => get_current_screen()->get_columns(),
177
			'id' => $this->id,
178
			'title' => __( 'Site Settings', 'pollux' ),
179
		]);
180
	}
181
182
	/**
183
	 * @return void
184
	 * @callback add_meta_box
185
	 */
186
	public function renderSubmitMetaBox()
187
	{
188
		$query = [
189
			'_wpnonce' => wp_create_nonce( $this->hook ),
190
			'action' => 'reset',
191
			'page' => $this->id,
192
		];
193
		$this->render( 'settings/submit', [
194
			'reset' => __( 'Reset Settings', 'pollux' ),
195
			'reset_url' => esc_url( add_query_arg( $query, admin_url( 'admin.php' ))),
196
			'submit' => get_submit_button( __( 'Save', 'pollux' ), 'primary', 'submit', false ),
197
		]);
198
	}
199
200
	/**
201
	 * @return void
202
	 * @action pollux/settings/init
203
	 */
204
	public function reset()
205
	{
206
		if( filter_input( INPUT_GET, 'page' ) !== $this->id
207
			|| filter_input( INPUT_GET, 'action' ) !== 'reset'
208
		)return;
209
		if( wp_verify_nonce( filter_input( INPUT_GET, '_wpnonce' ), $this->hook )) {
210
			update_option( $this->id, $this->getDefaults() );
211
			return add_settings_error( $this->id, 'reset', __( 'Settings reset to defaults.', 'pollux' ), 'updated' );
212
		}
213
		add_settings_error( $this->id, 'reset', __( 'Failed to reset settings. Please refresh the page and try again.', 'pollux' ));
214
	}
215
216
	/**
217
	 * @param string $key
218
	 * @return array
219
	 */
220
	protected function filterArrayByKey( array $array, $key )
221
	{
222
		return array_filter( $array, function( $value ) use( $key ) {
223
			return !empty( $value[$key] );
224
		});
225
	}
226
227
	/**
228
	 * @return array
229
	 */
230
	protected function getDefaults()
231
	{
232
		$metaboxes = $this->filterArrayByKey( $this->metaboxes, 'slug' );
233
234
		array_walk( $metaboxes, function( &$metabox ) {
235
			$fields = array_map( function( $field ) {
236
				$field = wp_parse_args( $field, ['std' => ''] );
237
				return [$field['slug'] => $field['std']];
238
			}, $this->filterArrayByKey( $metabox['fields'], 'slug' ));
239
			$metabox = [
240
				$metabox['slug'] => call_user_func_array( 'array_merge', $fields ),
241
			];
242
		});
243
		return call_user_func_array( 'array_merge', $metaboxes );
244
	}
245
246
	/**
247
	 * {@inheritdoc}
248
	 */
249 View Code Duplication
	protected function normalize()
250
	{
251
		foreach( $this->app->config['settings'] as $id => $metabox ) {
252
			$defaults = [
253
				'condition' => [],
254
				'fields' => [],
255
				'id' => $id,
256
				'slug' => $id,
257
			];
258
			$this->metaboxes[] = $this->setDependencies(
259
				$this->normalizeThis( $metabox, $defaults, $id )
260
			);
261
		}
262
	}
263
264
	/**
265
	 * @param string $name
266
	 * @param string $parentId
267
	 * @return string
268
	 */
269
	protected function normalizeFieldName( $name, array $data, $parentId )
270
	{
271
		if( !empty( $name )) {
272
			return $name;
273
		}
274
		$name = str_replace( sprintf( '%s-%s-', $this->id, $parentId ), '', $data['id'] );
275
		return sprintf( '%s[%s][%s]', $this->id, $parentId, $name );
276
	}
277
278
	/**
279
	 * @param string $id
280
	 * @param string $parentId
281
	 * @return string
282
	 */
283
	protected function normalizeId( $id, array $data, $parentId )
284
	{
285
		return $parentId == $id
286
			? sprintf( '%s-%s', $this->id, $id )
287
			: sprintf( '%s-%s-%s', $this->id, $parentId, $id );
288
	}
289
}
290