Settings   A
last analyzed

Complexity

Total Complexity 30

Size/Duplication

Total Lines 277
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 14
Bugs 3 Features 0
Metric Value
eloc 97
c 14
b 3
f 0
dl 0
loc 277
ccs 0
cts 113
cp 0
rs 10
wmc 30

20 Methods

Rating   Name   Duplication   Size   Complexity  
A renderFooterScript() 0 7 2
A id() 0 3 1
A registerSetting() 0 3 1
A normalizeId() 0 5 2
A renderPage() 0 6 1
A renderSubmitMetaBox() 0 12 1
A resetPage() 0 15 4
A filterArrayByKey() 0 4 1
A filterInstruction() 0 3 1
A getDefaults() 0 14 1
A canProceed() 0 4 2
A getSettings() 0 3 1
A register() 0 13 4
A getMetaValue() 0 3 1
A filterBeforeInstructions() 0 3 1
A registerPage() 0 10 1
A normalizeFieldName() 0 3 1
A filterSavedSettings() 0 6 1
A addSubmitMetaBox() 0 9 1
A init() 0 14 2
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
	const ID = 'settings';
14
15
	const CAPABILITY = 'edit_theme_options';
16
	const DEPENDENCY = 'meta-box/meta-box.php';
17
18
	const CONDITIONS = [
19
		'class_exists', 'defined', 'function_exists', 'hook', 'is_plugin_active',
20
		'is_plugin_inactive',
21
	];
22
23
	/**
24
	 * @var string
25
	 */
26
	public $hook;
27
28
	/**
29
	 * @return string
30
	 */
31
	public static function id()
32
	{
33
		return apply_filters( sprintf( 'pollux/%s/id', static::ID ), Application::prefix() . static::ID );
34
	}
35
36
	/**
37
	 * {@inheritdoc}
38
	 */
39
	public function init()
40
	{
41
		if( !$this->canProceed() )return;
42
43
		$this->normalize( $this->app->config->{static::ID} );
44
45
		add_action( 'pollux/'.static::ID.'/init',                [$this, 'addSubmitMetaBox'] );
46
		add_action( 'current_screen',                            [$this, 'register'] );
47
		add_action( 'admin_menu',                                [$this, 'registerPage'] );
48
		add_action( 'admin_menu',                                [$this, 'registerSetting'] );
49
		add_action( 'pollux/'.static::ID.'/init',                [$this, 'resetPage'] );
50
		add_action( 'admin_print_footer_scripts',                [$this, 'renderFooterScript'] );
51
		add_filter( 'pollux/'.static::ID.'/instruction',         [$this, 'filterInstruction'], 10, 3 );
52
		add_filter( 'pollux/'.static::ID.'/before/instructions', [$this, 'filterBeforeInstructions'] );
53
	}
54
55
	public function canProceed()
56
	{
57
		return $this->app->gatekeeper->hasDependency( static::DEPENDENCY )
58
			&& !empty( $this->app->config->{static::ID} );
59
	}
60
61
	/**
62
	 * @return void
63
	 * @action pollux/{static::ID}/init
64
	 */
65
	public function addSubmitMetaBox()
66
	{
67
		call_user_func_array( 'add_meta_box', $this->filter( 'metabox/submit', [
0 ignored issues
show
Bug introduced by
It seems like $this->filter('metabox/s...>hook, 'side', 'high')) can also be of type string; however, parameter $param_arr of call_user_func_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

67
		call_user_func_array( 'add_meta_box', /** @scrutinizer ignore-type */ $this->filter( 'metabox/submit', [
Loading history...
68
			'submitdiv',
69
			__( 'Save Settings', 'pollux' ),
70
			[$this, 'renderSubmitMetaBox'],
71
			$this->hook,
72
			'side',
73
			'high',
74
		]));
75
	}
76
77
	/**
78
	 * @return string
79
	 * @filter pollux/{static::ID}/before/instructions
80
	 */
81
	public function filterBeforeInstructions()
82
	{
83
		return '<pre class="my-sites nav-tab-active misc-pub-section">SiteMeta::all();</pre>';
84
	}
85
86
	/**
87
	 * @param string $instruction
88
	 * @return string
89
	 * @action pollux/{static::ID}/instruction
90
	 */
91
	public function filterInstruction( $instruction, array $field, array $metabox )
92
	{
93
		return sprintf( "SiteMeta::%s('%s');", $metabox['slug'], $field['slug'] );
94
	}
95
96
	/**
97
	 * @param null|array $settings
98
	 * @return array
99
	 * @callback register_setting
100
	 */
101
	public function filterSavedSettings( $settings )
102
	{
103
		$settings = Helper::toArray( $settings );
104
		return $this->filter( 'save', array_merge(
105
			array_intersect_key( $this->getSettings(), $settings ),
106
			$settings
107
		));
108
	}
109
110
	/**
111
	 * @param string $key
112
	 * @param mixed $fallback
113
	 * @param string $group
114
	 * @return string|array
115
	 */
116
	public function getMetaValue( $key, $fallback = '', $group = '' )
117
	{
118
		return SiteMeta::get( $group, $key, $fallback );
119
	}
120
121
	/**
122
	 * @return void
123
	 * @action current_screen
124
	 */
125
	public function register()
126
	{
127
		if( Helper::getCurrentScreen()->id != $this->hook )return;
128
		if( $this->app->gatekeeper->hasDependency( self::DEPENDENCY )) {
129
			foreach( parent::register() as $metabox ) {
130
				new RWMetaBox( $metabox, static::ID, $this );
131
			}
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', [
0 ignored issues
show
Bug introduced by
It seems like $this->filter('page', ar...-screenoptions', 1313)) can also be of type string; however, parameter $param_arr of call_user_func_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

146
		$this->hook = call_user_func_array( 'add_menu_page', /** @scrutinizer ignore-type */ $this->filter( 'page', [
Loading history...
147
			__( 'Site Settings', 'pollux' ),
148
			__( 'Site Settings', 'pollux' ),
149
			static::CAPABILITY,
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( 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(),
0 ignored issues
show
Bug introduced by
Are you sure the usage of get_current_screen() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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
	public function resetPage()
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();
0 ignored issues
show
Bug introduced by
The method all() does not exist on GeminiLabs\Pollux\Facades\SiteMeta. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

265
		return (array) SiteMeta::/** @scrutinizer ignore-call */ all();
Loading history...
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