Created
January 31, 2025 16:59
-
-
Save jonshipman/21960ef56853a3b9f54c119de4e20509 to your computer and use it in GitHub Desktop.
Custom Post Type Metabox Class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Custom Post Type Meta Box. | |
* | |
* @package Heartland | |
*/ | |
/** | |
* Meta box class. | |
*/ | |
class Heartland_Core_Meta_Box { | |
/** | |
* Meta box data. | |
* | |
* @var array | |
*/ | |
protected $meta_box; | |
/** | |
* Create meta box based on given data. | |
* | |
* @param array $meta_box Meta box data. | |
*/ | |
public function __construct( $meta_box ) { | |
$this->meta_box = $meta_box; | |
add_action( 'admin_menu', array( $this, 'add' ) ); | |
add_action( 'save_post', array( $this, 'save' ) ); | |
add_action( 'admin_menu', array( $this, 'metahide' ) ); | |
} | |
/** | |
* Hides the custom meta box from locations. | |
*/ | |
public function metahide() { | |
if ( empty( $this->meta_box['posts'] ) ) { | |
return; | |
} | |
remove_meta_box( 'postcustom', $this->meta_box['posts'], 'normal' ); | |
} | |
/** | |
* Add meta box for multiple post types. | |
*/ | |
public function add() { | |
if ( empty( $this->meta_box['posts'] ) ) { | |
return; | |
} | |
foreach ( $this->meta_box['posts'] as $page ) { | |
add_meta_box( $this->meta_box['id'], $this->meta_box['title'], array( $this, 'show' ), $page, $this->meta_box['context'], $this->meta_box['priority'] ); | |
} | |
} | |
/** | |
* Callback function to show fields in meta box. | |
*/ | |
public function show() { | |
global $post; | |
/** | |
* Use nonce for verification. | |
*/ | |
echo '<input type="hidden" name="heartland_core_prefix_meta_box_nonce" value="' . esc_attr( wp_create_nonce( basename( __FILE__ ) ) ), '" />'; | |
echo '<table class="form-table">'; | |
foreach ( $this->meta_box['fields'] as $field ) { | |
/** | |
* Get current post meta data. | |
*/ | |
$meta = get_post_meta( $post->ID, $field['id'], true ); | |
$field_name = 'heartland_core_' . $field['id']; | |
?> | |
<tr> | |
<th style="width:20%"> | |
<label for="<?php echo esc_attr( $field_name ); ?>"><?php echo esc_html( $field['name'] ); ?></label> | |
</th> | |
<td> | |
<?php | |
switch ( $field['type'] ) { | |
case 'thumbnail': | |
$default_url = \Elementor\Utils::get_placeholder_image_src(); | |
$featured_img_url = $default_url; | |
if ( $meta ) { | |
$featured_img_url = wp_get_attachment_url( $meta, 'medium' ); | |
} | |
?> | |
<div class="editor-post-featured-image__preview" style="display: inline-block; max-width: 160px;"> | |
<img data-default-url="<?php echo esc_url( $default_url ); ?>" id="<?php echo esc_attr( $field_name ); ?>_image" src="<?php echo esc_url( $featured_img_url ); ?>" class="editor-post-featured-image__preview-image" /> | |
</div> | |
<input type="hidden" name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>" value="<?php echo esc_attr( $meta ); ?>" /> | |
<button type="button" id="<?php echo esc_attr( $field_name ); ?>_select" class="button heartland-core-upload-button"><?php esc_html_e( 'Select Image', 'heartland' ); ?></button> | |
<button type="button" id="<?php echo esc_attr( $field_name ); ?>_remove" class="button heartland-core-remove-button"><?php esc_html_e( 'Remove Image', 'heartland' ); ?></button> | |
<br> | |
<script> | |
document.getElementById('<?php echo esc_attr( $field_name ); ?>_select').addEventListener('click', function() { | |
var custom_uploader = wp.media({ | |
title: 'Select Image', | |
button: { | |
text: 'Use this image', | |
}, | |
multiple: false, | |
}).on('select', function() { | |
var attachment = custom_uploader.state().get('selection').first().toJSON(); | |
document.getElementById('<?php echo esc_attr( $field_name ); ?>').value = attachment.id; | |
document.getElementById('<?php echo esc_attr( $field_name ); ?>_image').src = attachment.url; | |
}).open(); | |
}); | |
document.getElementById('<?php echo esc_attr( $field_name ); ?>_remove').addEventListener('click', function() { | |
document.getElementById('<?php echo esc_attr( $field_name ); ?>').value = ''; | |
const image = document.getElementById('<?php echo esc_attr( $field_name ); ?>_image'); | |
image.src = image.getAttribute('data-default-url'); | |
}); | |
</script> | |
<?php | |
echo esc_html( $field['desc'] ); | |
break; | |
case 'text': | |
?> | |
<input type="text" name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>" value="<?php echo esc_attr( $meta ? $meta : $field['std'] ); ?>" size="30" style="width:97%" /> | |
<br> | |
<?php | |
echo esc_html( $field['desc'] ); | |
break; | |
case 'textarea': | |
?> | |
<textarea name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>" cols="60" rows="4" style="width:97%"><?php echo esc_html( $meta ? $meta : $field['std'] ); ?></textarea> | |
<br> | |
<?php | |
echo esc_html( $field['desc'] ); | |
break; | |
case 'select': | |
?> | |
<select name="<?php echo esc_attr( $field_name ); ?>" id="<?php echo esc_attr( $field_name ); ?>"> | |
<?php | |
foreach ( $field['options'] as $option ) { | |
?> | |
<option value="<?php echo esc_attr( $option['value'] ); ?>"<?php selected( $meta, $option['value'] ); ?>><?php echo esc_html( $option['name'] ); ?></option> | |
<?php | |
} | |
?> | |
</select> | |
<br> | |
<?php | |
echo esc_html( $field['desc'] ); | |
break; | |
case 'radio': | |
foreach ( $field['options'] as $option ) { | |
?> | |
<input type="radio" name="<?php echo esc_attr( $field_name ); ?>" value="<?php echo esc_attr( $option['value'] ); ?>"<?php checked( $meta, $option['value'] ); ?> /> | |
<?php | |
echo esc_html( $option['name'] ); | |
} | |
echo '<br>' . esc_html( $field['desc'] ); | |
break; | |
case 'checkbox': | |
foreach ( $field['options'] as $option ) { | |
?> | |
<input type="checkbox" name="<?php echo esc_attr( $field_name ); ?>" value="<?php echo esc_attr( $option['value'] ); ?>"<?php checked( $meta, $option['value'] ); ?> /> | |
<?php | |
echo esc_html( $option['name'] ); | |
} | |
echo '<br>' . esc_html( $field['desc'] ); | |
break; | |
} | |
echo '<td></tr>'; | |
} | |
echo '</table>'; | |
} | |
/** | |
* Save data from meta box | |
* | |
* @param int $post_id Post ID. | |
*/ | |
public function save( $post_id ) { | |
/** | |
* Verify nonce. | |
*/ | |
$nonce_safe = isset( $_POST['heartland_core_prefix_meta_box_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['heartland_core_prefix_meta_box_nonce'] ) ) : false; | |
if ( ! isset( $_POST['heartland_core_prefix_meta_box_nonce'] ) || ! wp_verify_nonce( $nonce_safe, basename( __FILE__ ) ) ) { | |
return $post_id; | |
} | |
/** | |
* Check autosave. | |
*/ | |
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { | |
return $post_id; | |
} | |
/** | |
* Check permissions. | |
*/ | |
if ( ! empty( $_POST['post_type'] ) && 'page' === $_POST['post_type'] ) { | |
if ( ! current_user_can( 'edit_page', $post_id ) ) { | |
return $post_id; | |
} | |
} elseif ( ! current_user_can( 'edit_post', $post_id ) ) { | |
return $post_id; | |
} | |
foreach ( $this->meta_box['fields'] as $field ) { | |
$old = get_post_meta( $post_id, $field['id'], true ); | |
$field_name = 'heartland_core_' . $field['id']; | |
$new = empty( $_POST[ $field_name ] ) ? '' : sanitize_text_field( wp_unslash( $_POST[ $field_name ] ) ); | |
if ( $new && $new !== $old ) { | |
update_post_meta( $post_id, $field['id'], $new ); | |
} elseif ( '' === $new && $old ) { | |
delete_post_meta( $post_id, $field['id'], $old ); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment