Passed
Push — master ( 51995c...0bccda )
by Paul
06:07 queued 02:50
created

Settings::normalizeId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 3
dl 0
loc 6
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
		// if( empty( $this->app->config->{static::ID} ))return;
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
45
		// if( is_bool( $this->app->config->{static::ID} )) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% 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
		// 	$this->app->config->{static::ID} = [];
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% 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...
47
		// }
48
49
		// @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...
50
		// 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...
51
52
		$this->normalize( $this->app->config->{static::ID} );
53
54
		add_action( 'pollux/'.static::ID.'/init',                [$this, 'addSubmitMetaBox'] );
55
		add_action( 'current_screen',                            [$this, 'register'] );
56
		add_action( 'admin_menu',                                [$this, 'registerPage'] );
57
		add_action( 'admin_menu',                                [$this, 'registerSetting'] );
58
		add_action( 'pollux/'.static::ID.'/init',                [$this, 'resetPage'] );
59
		add_action( 'admin_print_footer_scripts',                [$this, 'renderFooterScript'] );
60
		add_filter( 'pollux/'.static::ID.'/instruction',         [$this, 'filterInstruction'], 10, 3 );
61
		add_filter( 'pollux/'.static::ID.'/before/instructions', [$this, 'filterBeforeInstructions'] );
62
	}
63
64
	/**
65
	 * @return void
66
	 * @action pollux/{static::ID}/init
67
	 */
68
	public function addSubmitMetaBox()
69
	{
70
		call_user_func_array( 'add_meta_box', $this->filter( 'metabox/submit', [
71
			'submitdiv',
72
			__( 'Save Settings', 'pollux' ),
73
			[$this, 'renderSubmitMetaBox'],
74
			$this->hook,
75
			'side',
76
			'high',
77
		]));
78
	}
79
80
	/**
81
	 * @return string
82
	 * @filter pollux/{static::ID}/before/instructions
83
	 */
84
	public function filterBeforeInstructions()
85
	{
86
		return '<pre class="my-sites nav-tab-active misc-pub-section">SiteMeta::all();</pre>';
87
	}
88
89
	/**
90
	 * @param string $instruction
91
	 * @return string
92
	 * @action pollux/{static::ID}/instruction
93
	 */
94
	public function filterInstruction( $instruction, array $field, array $metabox )
95
	{
96
		return sprintf( "SiteMeta::%s('%s');", $metabox['slug'], $field['slug'] );
97
	}
98
99
	/**
100
	 * @param null|array $settings
101
	 * @return array
102
	 * @callback register_setting
103
	 */
104
	public function filterSavedSettings( $settings )
105
	{
106
		if( is_null( $settings )) {
107
			$settings = [];
108
		}
109
		return $this->filter( 'save', array_merge( $this->getSettings(), $settings ));
110
	}
111
112
	/**
113
	 * @param string $key
114
	 * @param mixed $fallback
115
	 * @param string $group
116
	 * @return string|array
117
	 */
118
	public function getMetaValue( $key, $fallback = '', $group = '' )
119
	{
120
		return SiteMeta::get( $group, $key, $fallback );
121
	}
122
123
	/**
124
	 * @return void
125
	 * @action current_screen
126
	 */
127
	public function register()
128
	{
129
		if(( new Helper )->getCurrentScreen()->id != $this->hook )return;
130
		foreach( parent::register() as $metabox ) {
131
			new RWMetaBox( $metabox, static::ID, $this );
132
		}
133
		add_screen_option( 'layout_columns', [
134
			'max' => 2,
135
			'default' => 2,
136
		]);
137
		$this->action( 'init' );
138
	}
139
140
	/**
141
	 * @return void
142
	 * @action admin_menu
143
	 */
144
	public function registerPage()
145
	{
146
		$this->hook = call_user_func_array( 'add_menu_page', $this->filter( 'page', [
147
			__( 'Site Settings', 'pollux' ),
148
			__( 'Site Settings', 'pollux' ),
149
			'edit_theme_options',
150
			static::id(),
151
			[$this, 'renderPage'],
152
			'dashicons-screenoptions',
153
			1313
154
		]));
155
	}
156
157
	/**
158
	 * @return void
159
	 * @action admin_menu
160
	 */
161
	public function registerSetting()
162
	{
163
		register_setting( static::id(), static::id(), [$this, 'filterSavedSettings'] );
164
	}
165
166
	/**
167
	 * @return void
168
	 * @action admin_print_footer_scripts
169
	 */
170
	public function renderFooterScript()
171
	{
172
		if(( new Helper )->getCurrentScreen()->id != $this->hook )return;
173
		$this->app->render( 'settings/script', [
174
			'confirm' => __( 'Are you sure want to do this?', 'pollux' ),
175
			'hook' => $this->hook,
176
			'id' => static::id(),
177
		]);
178
	}
179
180
	/**
181
	 * @return void
182
	 * @callback add_menu_page
183
	 */
184
	public function renderPage()
185
	{
186
		$this->app->render( 'settings/index', [
187
			'columns' => get_current_screen()->get_columns(),
188
			'heading' => __( 'Site Settings', 'pollux' ),
189
			'id' => static::id(),
190
		]);
191
	}
192
193
	/**
194
	 * @return void
195
	 * @callback add_meta_box
196
	 */
197
	public function renderSubmitMetaBox()
198
	{
199
		global $pagenow;
200
		$query = [
201
			'_wpnonce' => wp_create_nonce( $this->hook ),
202
			'action' => 'reset',
203
			'page' => static::id(),
204
		];
205
		$this->app->render( 'settings/submit', [
206
			'reset' => __( 'Reset all', 'pollux' ),
207
			'reset_url' => esc_url( add_query_arg( $query, admin_url( $pagenow ))),
208
			'submit' => get_submit_button( __( 'Save', 'pollux' ), 'primary', 'submit', false ),
209
		]);
210
	}
211
212
	/**
213
	 * @return void
214
	 * @action pollux/{static::ID}/init
215
	 */
216 View Code Duplication
	public function resetPage()
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...
217
	{
218
		if( filter_input( INPUT_GET, 'page' ) !== static::id()
219
			|| filter_input( INPUT_GET, 'action' ) !== 'reset'
220
		)return;
221
		if( wp_verify_nonce( filter_input( INPUT_GET, '_wpnonce' ), $this->hook )) {
222
			update_option( static::id(), $this->getDefaults() );
223
			add_settings_error( static::id(), 'reset', __( 'Reset successful.', 'pollux' ), 'updated' );
224
		}
225
		else {
226
			add_settings_error( static::id(), 'failed', __( 'Failed to reset. Please try again.', 'pollux' ));
227
		}
228
		set_transient( 'settings_errors', get_settings_errors(), 30 );
229
		wp_safe_redirect( add_query_arg( 'settings-updated', 'true',  wp_get_referer() ));
230
		exit;
231
	}
232
233
	/**
234
	 * @param string $key
235
	 * @return array
236
	 */
237
	protected function filterArrayByKey( array $array, $key )
238
	{
239
		return array_filter( $array, function( $value ) use( $key ) {
240
			return !empty( $value[$key] );
241
		});
242
	}
243
244
	/**
245
	 * @return array
246
	 */
247
	protected function getDefaults()
248
	{
249
		$metaboxes = $this->filterArrayByKey( $this->metaboxes, 'slug' );
250
251
		array_walk( $metaboxes, function( &$metabox ) {
252
			$fields = array_map( function( $field ) {
253
				$field = wp_parse_args( $field, ['std' => ''] );
254
				return [$field['slug'] => $field['std']];
255
			}, $this->filterArrayByKey( $metabox['fields'], 'slug' ));
256
			$metabox = [
257
				$metabox['slug'] => call_user_func_array( 'array_merge', $fields ),
258
			];
259
		});
260
		return call_user_func_array( 'array_merge', $metaboxes );
261
	}
262
263
	protected function getSettings()
264
	{
265
		return (array) SiteMeta::all();
266
	}
267
268
	/**
269
	 * @param string $name
270
	 * @param string $parentId
271
	 * @return string
272
	 */
273
	protected function normalizeFieldName( $name, array $data, $parentId )
274
	{
275
		return sprintf( '%s[%s][%s]', static::id(), $parentId, $data['slug'] );
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', static::id(), $id )
287
			: sprintf( '%s-%s-%s', static::id(), $parentId, $id );
288
	}
289
}
290