Passed
Push — master ( 336c10...5d2e19 )
by Paul
02:17
created

Settings::filterInstruction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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