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', [ |
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
|
|
|
if( is_null( $settings )) { |
104
|
|
|
$settings = []; |
105
|
|
|
} |
106
|
|
|
return $this->filter( 'save', array_merge( $this->getSettings(), $settings )); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* @param string $key |
111
|
|
|
* @param mixed $fallback |
112
|
|
|
* @param string $group |
113
|
|
|
* @return string|array |
114
|
|
|
*/ |
115
|
|
|
public function getMetaValue( $key, $fallback = '', $group = '' ) |
116
|
|
|
{ |
117
|
|
|
return SiteMeta::get( $group, $key, $fallback ); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* @return void |
122
|
|
|
* @action current_screen |
123
|
|
|
*/ |
124
|
|
|
public function register() |
125
|
|
|
{ |
126
|
|
|
if(( new Helper )->getCurrentScreen()->id != $this->hook )return; |
127
|
|
|
if( $this->app->gatekeeper->hasDependency( self::DEPENDENCY )) { |
128
|
|
|
foreach( parent::register() as $metabox ) { |
129
|
|
|
new RWMetaBox( $metabox, static::ID, $this ); |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
add_screen_option( 'layout_columns', [ |
133
|
|
|
'max' => 2, |
134
|
|
|
'default' => 2, |
135
|
|
|
]); |
136
|
|
|
$this->action( 'init' ); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* @return void |
141
|
|
|
* @action admin_menu |
142
|
|
|
*/ |
143
|
|
|
public function registerPage() |
144
|
|
|
{ |
145
|
|
|
$this->hook = call_user_func_array( 'add_menu_page', $this->filter( 'page', [ |
146
|
|
|
__( 'Site Settings', 'pollux' ), |
147
|
|
|
__( 'Site Settings', 'pollux' ), |
148
|
|
|
static::CAPABILITY, |
149
|
|
|
static::id(), |
150
|
|
|
[$this, 'renderPage'], |
151
|
|
|
'dashicons-screenoptions', |
152
|
|
|
1313 |
153
|
|
|
])); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* @return void |
158
|
|
|
* @action admin_menu |
159
|
|
|
*/ |
160
|
|
|
public function registerSetting() |
161
|
|
|
{ |
162
|
|
|
register_setting( static::id(), static::id(), [$this, 'filterSavedSettings'] ); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* @return void |
167
|
|
|
* @action admin_print_footer_scripts |
168
|
|
|
*/ |
169
|
|
|
public function renderFooterScript() |
170
|
|
|
{ |
171
|
|
|
if(( new Helper )->getCurrentScreen()->id != $this->hook )return; |
172
|
|
|
$this->app->render( 'settings/script', [ |
173
|
|
|
'confirm' => __( 'Are you sure want to do this?', 'pollux' ), |
174
|
|
|
'hook' => $this->hook, |
175
|
|
|
'id' => static::id(), |
176
|
|
|
]); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @return void |
181
|
|
|
* @callback add_menu_page |
182
|
|
|
*/ |
183
|
|
|
public function renderPage() |
184
|
|
|
{ |
185
|
|
|
$this->app->render( 'settings/index', [ |
186
|
|
|
'columns' => get_current_screen()->get_columns(), |
187
|
|
|
'heading' => __( 'Site Settings', 'pollux' ), |
188
|
|
|
'id' => static::id(), |
189
|
|
|
]); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* @return void |
194
|
|
|
* @callback add_meta_box |
195
|
|
|
*/ |
196
|
|
|
public function renderSubmitMetaBox() |
197
|
|
|
{ |
198
|
|
|
global $pagenow; |
199
|
|
|
$query = [ |
200
|
|
|
'_wpnonce' => wp_create_nonce( $this->hook ), |
201
|
|
|
'action' => 'reset', |
202
|
|
|
'page' => static::id(), |
203
|
|
|
]; |
204
|
|
|
$this->app->render( 'settings/submit', [ |
205
|
|
|
'reset' => __( 'Reset all', 'pollux' ), |
206
|
|
|
'reset_url' => esc_url( add_query_arg( $query, admin_url( $pagenow ))), |
207
|
|
|
'submit' => get_submit_button( __( 'Save', 'pollux' ), 'primary', 'submit', false ), |
208
|
|
|
]); |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* @return void |
213
|
|
|
* @action pollux/{static::ID}/init |
214
|
|
|
*/ |
215
|
|
View Code Duplication |
public function resetPage() |
|
|
|
|
216
|
|
|
{ |
217
|
|
|
if( filter_input( INPUT_GET, 'page' ) !== static::id() |
218
|
|
|
|| filter_input( INPUT_GET, 'action' ) !== 'reset' |
219
|
|
|
)return; |
220
|
|
|
if( wp_verify_nonce( filter_input( INPUT_GET, '_wpnonce' ), $this->hook )) { |
221
|
|
|
update_option( static::id(), $this->getDefaults() ); |
222
|
|
|
add_settings_error( static::id(), 'reset', __( 'Reset successful.', 'pollux' ), 'updated' ); |
223
|
|
|
} |
224
|
|
|
else { |
225
|
|
|
add_settings_error( static::id(), 'failed', __( 'Failed to reset. Please try again.', 'pollux' )); |
226
|
|
|
} |
227
|
|
|
set_transient( 'settings_errors', get_settings_errors(), 30 ); |
228
|
|
|
wp_safe_redirect( add_query_arg( 'settings-updated', 'true', wp_get_referer() )); |
229
|
|
|
exit; |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
/** |
233
|
|
|
* @param string $key |
234
|
|
|
* @return array |
235
|
|
|
*/ |
236
|
|
|
protected function filterArrayByKey( array $array, $key ) |
237
|
|
|
{ |
238
|
|
|
return array_filter( $array, function( $value ) use( $key ) { |
239
|
|
|
return !empty( $value[$key] ); |
240
|
|
|
}); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* @return array |
245
|
|
|
*/ |
246
|
|
|
protected function getDefaults() |
247
|
|
|
{ |
248
|
|
|
$metaboxes = $this->filterArrayByKey( $this->metaboxes, 'slug' ); |
249
|
|
|
|
250
|
|
|
array_walk( $metaboxes, function( &$metabox ) { |
251
|
|
|
$fields = array_map( function( $field ) { |
252
|
|
|
$field = wp_parse_args( $field, ['std' => ''] ); |
253
|
|
|
return [$field['slug'] => $field['std']]; |
254
|
|
|
}, $this->filterArrayByKey( $metabox['fields'], 'slug' )); |
255
|
|
|
$metabox = [ |
256
|
|
|
$metabox['slug'] => call_user_func_array( 'array_merge', $fields ), |
257
|
|
|
]; |
258
|
|
|
}); |
259
|
|
|
return call_user_func_array( 'array_merge', $metaboxes ); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
protected function getSettings() |
263
|
|
|
{ |
264
|
|
|
return (array) SiteMeta::all(); |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
/** |
268
|
|
|
* @param string $name |
269
|
|
|
* @param string $parentId |
270
|
|
|
* @return string |
271
|
|
|
*/ |
272
|
|
|
protected function normalizeFieldName( $name, array $data, $parentId ) |
273
|
|
|
{ |
274
|
|
|
return sprintf( '%s[%s][%s]', static::id(), $parentId, $data['slug'] ); |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* @param string $id |
279
|
|
|
* @param string $parentId |
280
|
|
|
* @return string |
281
|
|
|
*/ |
282
|
|
|
protected function normalizeId( $id, array $data, $parentId ) |
283
|
|
|
{ |
284
|
|
|
return $parentId == $id |
285
|
|
|
? sprintf( '%s-%s', static::id(), $id ) |
286
|
|
|
: sprintf( '%s-%s-%s', static::id(), $parentId, $id ); |
287
|
|
|
} |
288
|
|
|
} |
289
|
|
|
|
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.