Skip to content

Commit 10e3dc2

Browse files
committed
Add Hook_Registry
1 parent d50c41c commit 10e3dc2

31 files changed

Lines changed: 8190 additions & 0 deletions

includes/admin/class-settings.php

Lines changed: 1125 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
<?php
2+
/**
3+
* Class to display and save a Metabox.
4+
*
5+
* @package WebberZone\Starter_Plugin
6+
*/
7+
8+
namespace WebberZone\Starter_Plugin\Admin\Settings;
9+
10+
use WebberZone\Starter_Plugin\Util\Hook_Registry;
11+
12+
// If this file is called directly, abort.
13+
if ( ! defined( 'WPINC' ) ) {
14+
die;
15+
}
16+
17+
/**
18+
* Metabox API class.
19+
*/
20+
#[\AllowDynamicProperties]
21+
class Metabox_API {
22+
23+
24+
/**
25+
* Current version number
26+
*
27+
* @var string
28+
*/
29+
const VERSION = '2.3.0';
30+
31+
/**
32+
* Settings Key.
33+
*
34+
* @var string Settings Key.
35+
*/
36+
public $settings_key;
37+
38+
/**
39+
* Prefix which is used for creating the unique filters and actions.
40+
*
41+
* @var string Prefix.
42+
*/
43+
public $prefix;
44+
45+
/**
46+
* Name of the Post type.
47+
*
48+
* @var string Post type.
49+
*/
50+
protected $post_type;
51+
52+
/**
53+
* Title of the Metabox.
54+
*
55+
* @var string Post type.
56+
*/
57+
protected $title;
58+
59+
/**
60+
* Translation strings.
61+
*
62+
* @var array Translation strings.
63+
*/
64+
public $translation_strings;
65+
66+
/**
67+
* Array containing the settings' fields.
68+
*
69+
* @var array Settings fields array.
70+
*/
71+
protected $registered_settings = array();
72+
73+
/**
74+
* Main constructor class.
75+
*
76+
* @param array|string $args {
77+
* Array or string of arguments. Default is blank array.
78+
*
79+
* @type string $settings_key Settings key - is used to prepare the form fields. It is not the meta key.
80+
* @type string $prefix Used to create the meta keys. The meta key format is _{$prefix}_{$setting_id}.
81+
* @type string|array|\WP_Screen $post_type The post type(s) on which to show the box.
82+
* @type array $registered_settings Settings fields array.
83+
* @type array $translation_strings Translation strings.
84+
* }
85+
*/
86+
public function __construct( $args ) {
87+
$defaults = array(
88+
'settings_key' => '',
89+
'prefix' => '',
90+
'post_type' => '',
91+
'title' => '',
92+
'registered_settings' => array(),
93+
'translation_strings' => array(),
94+
);
95+
96+
$args = wp_parse_args( $args, $defaults );
97+
98+
foreach ( $args as $name => $value ) {
99+
$this->$name = $value;
100+
}
101+
102+
Hook_Registry::add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
103+
Hook_Registry::add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
104+
Hook_Registry::add_action( "save_post_{$this->post_type}", array( $this, 'save' ) );
105+
}
106+
107+
/**
108+
* Function to add the metabox.
109+
*/
110+
public function add_meta_boxes() {
111+
add_meta_box(
112+
$this->prefix . '_metabox_id',
113+
$this->title,
114+
array( $this, 'html' ),
115+
$this->post_type,
116+
'advanced',
117+
'high'
118+
);
119+
}
120+
121+
/**
122+
* Enqueue scripts and styles.
123+
*
124+
* @param string $hook The current admin page.
125+
*/
126+
public function admin_enqueue_scripts( $hook ) {
127+
if ( in_array( $hook, array( 'post.php', 'post-new.php' ), true ) || get_current_screen()->post_type === $this->post_type ) {
128+
self::enqueue_scripts_styles();
129+
}
130+
}
131+
132+
/**
133+
* Enqueues all scripts, styles, settings, and templates necessary to use the Settings API.
134+
*/
135+
public static function enqueue_scripts_styles() {
136+
137+
$minimize = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
138+
139+
wp_enqueue_style( 'wp-color-picker' );
140+
141+
wp_enqueue_media();
142+
wp_enqueue_script( 'wp-color-picker' );
143+
wp_enqueue_script( 'jquery' );
144+
wp_enqueue_script( 'jquery-ui-autocomplete' );
145+
wp_enqueue_script( 'jquery-ui-tabs' );
146+
147+
wp_enqueue_code_editor(
148+
array(
149+
'type' => 'text/html',
150+
'codemirror' => array(
151+
'indentUnit' => 2,
152+
'tabSize' => 2,
153+
),
154+
)
155+
);
156+
157+
// Enqueue WZ Admin JS.
158+
wp_enqueue_script( 'wz-admin-js' );
159+
wp_enqueue_script( 'wz-codemirror-js' );
160+
wp_enqueue_script( 'wz-taxonomy-suggest-js' );
161+
wp_enqueue_script( 'wz-media-selector-js' );
162+
}
163+
164+
/**
165+
* Function to save the metabox.
166+
*
167+
* @param int|string $post_id Post ID.
168+
*/
169+
public function save( $post_id ) {
170+
171+
$post_meta = array();
172+
173+
// Bail if we're doing an auto save.
174+
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
175+
return;
176+
}
177+
178+
// If our nonce isn't there, or we can't verify it, bail.
179+
if ( ! isset( $_POST[ $this->prefix . '_meta_box_nonce' ] ) || ! wp_verify_nonce( sanitize_key( $_POST[ $this->prefix . '_meta_box_nonce' ] ), $this->prefix . '_meta_box' ) ) {
180+
return;
181+
}
182+
183+
// If our current user can't edit this post, bail.
184+
if ( ! current_user_can( 'edit_post', $post_id ) ) {
185+
return;
186+
}
187+
188+
if ( empty( $_POST[ $this->settings_key ] ) ) {
189+
return;
190+
}
191+
192+
$settings_sanitize = new Settings_Sanitize(
193+
array(
194+
'settings_key' => $this->settings_key,
195+
'prefix' => $this->prefix,
196+
)
197+
);
198+
199+
$posted = $_POST[ $this->settings_key ]; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.ValidatedSanitizedInput.MissingUnslash
200+
201+
foreach ( $this->registered_settings as $setting ) {
202+
$id = $setting['id'];
203+
$type = $setting['type'] ?? 'text';
204+
205+
/**
206+
* Skip settings that are not really settings.
207+
*
208+
* @param array $non_setting_types Array of types which are not settings.
209+
*/
210+
$non_setting_types = apply_filters( $this->prefix . '_metabox_non_setting_types', array( 'header', 'descriptive_text' ) );
211+
212+
if ( in_array( $type, $non_setting_types, true ) ) {
213+
continue;
214+
}
215+
216+
if ( isset( $posted[ $id ] ) ) {
217+
$value = $posted[ $id ];
218+
$sanitize_callback = is_callable( array( $settings_sanitize, "sanitize_{$type}_field" ) ) ? array( $settings_sanitize, "sanitize_{$type}_field" ) : array( $settings_sanitize, 'sanitize_missing' );
219+
$post_meta[ $id ] = call_user_func( $sanitize_callback, $value );
220+
}
221+
}
222+
223+
// Run the array through a generic function that allows access to all of the settings.
224+
$post_meta = call_user_func( array( $this, 'sanitize_post_meta' ), $post_meta );
225+
226+
/**
227+
* Filter the post meta array which contains post-specific settings.
228+
*
229+
* @param array $post_meta Array of metabox settings.
230+
* @param int $post_id Post ID
231+
*/
232+
$post_meta = apply_filters( "{$this->prefix}_meta_key", $post_meta, $post_id );
233+
234+
// Now loop through the settings array and either save or delete the meta key.
235+
foreach ( $this->registered_settings as $setting ) {
236+
if ( empty( $post_meta[ $setting['id'] ] ) ) {
237+
delete_post_meta( $post_id, "_{$this->prefix}_{$setting['id']}" );
238+
}
239+
}
240+
241+
foreach ( $post_meta as $setting => $value ) {
242+
if ( empty( $post_meta[ $setting ] ) ) {
243+
delete_post_meta( $post_id, "_{$this->prefix}_$setting" );
244+
} else {
245+
update_post_meta( $post_id, "_{$this->prefix}_$setting", $value );
246+
}
247+
}
248+
}
249+
250+
/**
251+
* Function to display the metabox.
252+
*
253+
* @param \WP_Post $post Post object.
254+
*/
255+
public function html( $post ) {
256+
// Add an nonce field so we can check for it later.
257+
wp_nonce_field( $this->prefix . '_meta_box', $this->prefix . '_meta_box_nonce' );
258+
259+
$settings_form = new Settings_Form(
260+
array(
261+
'settings_key' => $this->settings_key,
262+
'prefix' => $this->prefix,
263+
'translation_strings' => $this->translation_strings,
264+
)
265+
);
266+
267+
echo '<table class="form-table">';
268+
foreach ( $this->registered_settings as $setting ) {
269+
270+
$args = wp_parse_args(
271+
$setting,
272+
array(
273+
'id' => null,
274+
'name' => '',
275+
'desc' => '',
276+
'type' => null,
277+
'default' => '',
278+
'options' => '',
279+
'max' => null,
280+
'min' => null,
281+
'step' => null,
282+
'size' => null,
283+
'field_class' => '',
284+
'field_attributes' => '',
285+
'placeholder' => '',
286+
)
287+
);
288+
289+
$id = $args['id'];
290+
$value = get_post_meta( $post->ID, "_{$this->prefix}_{$id}", true );
291+
$args['value'] = ! empty( $value ) ? $value : ( $args['default'] ?? '' );
292+
$type = $args['type'] ?? 'text';
293+
$callback = method_exists( $settings_form, "callback_{$type}" ) ? array( $settings_form, "callback_{$type}" ) : array( $settings_form, 'callback_missing' );
294+
295+
echo '<tr>';
296+
echo '<th scope="row">' . $args['name'] . '</th>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
297+
echo '<td>';
298+
call_user_func( $callback, $args );
299+
echo '</td>';
300+
echo '</tr>';
301+
}
302+
echo '</table>';
303+
304+
/**
305+
* Action triggered when displaying the meta box.
306+
*
307+
* @param object $post Post object.
308+
*/
309+
do_action( $this->prefix . '_meta_box', $post );
310+
}
311+
312+
/**
313+
* Sanitize Post Meta array.
314+
*
315+
* @param array $settings Post meta settings array.
316+
* @return array Sanitized value.
317+
*/
318+
public function sanitize_post_meta( $settings ) {
319+
320+
// This array holds a list of keys that will be passed through our category/tags loop to determine the ids.
321+
$keys = array(
322+
'include_on_category' => array(
323+
'tax' => 'category',
324+
'ids_field' => 'include_on_category_ids',
325+
),
326+
'include_on_post_tag' => array(
327+
'tax' => 'post_tag',
328+
'ids_field' => 'include_on_post_tag_ids',
329+
),
330+
);
331+
332+
foreach ( $keys as $key => $fields ) {
333+
if ( isset( $settings[ $key ] ) ) {
334+
$ids = array();
335+
$names = array();
336+
337+
$taxes = array_unique( str_getcsv( $settings[ $key ], ',', '"', '' ) );
338+
339+
foreach ( $taxes as $tax ) {
340+
$tax_name = get_term_by( 'name', $tax, $fields['tax'] );
341+
342+
if ( isset( $tax_name->term_taxonomy_id ) ) {
343+
$ids[] = $tax_name->term_taxonomy_id;
344+
$names[] = $tax_name->name;
345+
}
346+
}
347+
$settings[ $fields['ids_field'] ] = join( ',', $ids );
348+
$settings[ $key ] = Settings_Sanitize::str_putcsv( $names );
349+
} else {
350+
$settings[ $fields['ids_field'] ] = '';
351+
}
352+
}
353+
354+
return $settings;
355+
}
356+
}

0 commit comments

Comments
 (0)