PluginProbe
WebberZone Top 10 — Popular Posts / 4.3.2
WebberZone Top 10 — Popular Posts v4.3.2
4.5.1 4.5.0 4.4.3 4.4.2 4.4.1 4.4.0 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.4.1 1.5 1.5.1 1.5.2 1.5.3 1.6 1.6.1 All 117 releases
top-10 / includes / admin / settings / class-metabox-api.php

class-metabox-api.php in WebberZone Top 10 — Popular Posts 4.3.2, at includes/admin/settings/class-metabox-api.php

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