v1.0.0
This commit is contained in:
parent
ac2c7a8014
commit
f7702f2872
25 changed files with 6453 additions and 0 deletions
219
includes/class-robotstxt-og-meta-box.php
Normal file
219
includes/class-robotstxt-og-meta-box.php
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
<?php
|
||||
/**
|
||||
* Meta Box Class
|
||||
*
|
||||
* Provides per-post Open Graph and social media customization fields
|
||||
* in the WordPress post editor.
|
||||
*
|
||||
* @package ROBOTSTXT_OG
|
||||
* @since 1.2.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Robotstxt_OG_Meta_Box
|
||||
*
|
||||
* Registers and handles the Open Graph meta box in the post editor,
|
||||
* and registers the underlying post meta for REST API access.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
class Robotstxt_OG_Meta_Box {
|
||||
|
||||
/**
|
||||
* Initialize hooks.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init(): void {
|
||||
// Register post meta for REST API access (block editor).
|
||||
add_action( 'init', array( $this, 'register_post_meta' ) );
|
||||
|
||||
// Meta box UI is admin-only.
|
||||
if ( is_admin() ) {
|
||||
add_action( 'add_meta_boxes', array( $this, 'register_meta_box' ) );
|
||||
add_action( 'save_post', array( $this, 'save_meta_box' ), 10, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register custom post meta for all public post types.
|
||||
*
|
||||
* Exposes _og_title and _og_description via the REST API so the
|
||||
* block editor can read and write them via useEntityProp.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_post_meta(): void {
|
||||
$post_types = get_post_types( array( 'public' => true ), 'names' );
|
||||
|
||||
foreach ( $post_types as $post_type ) {
|
||||
register_post_meta(
|
||||
$post_type,
|
||||
'_og_title',
|
||||
array(
|
||||
'type' => 'string',
|
||||
'single' => true,
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
'auth_callback' => static function () {
|
||||
return current_user_can( 'edit_posts' );
|
||||
},
|
||||
'show_in_rest' => true,
|
||||
)
|
||||
);
|
||||
|
||||
register_post_meta(
|
||||
$post_type,
|
||||
'_og_description',
|
||||
array(
|
||||
'type' => 'string',
|
||||
'single' => true,
|
||||
'sanitize_callback' => 'sanitize_textarea_field',
|
||||
'auth_callback' => static function () {
|
||||
return current_user_can( 'edit_posts' );
|
||||
},
|
||||
'show_in_rest' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the meta box for all public post types.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_meta_box(): void {
|
||||
$post_types = get_post_types( array( 'public' => true ), 'names' );
|
||||
|
||||
foreach ( $post_types as $post_type ) {
|
||||
add_meta_box(
|
||||
'robotstxt-og-meta-box',
|
||||
__( 'Open Graph / Social Media', 'robotstxt-og' ),
|
||||
array( $this, 'render_meta_box' ),
|
||||
$post_type,
|
||||
'normal',
|
||||
'default'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the meta box HTML.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @param WP_Post $post The current post object.
|
||||
* @return void
|
||||
*/
|
||||
public function render_meta_box( WP_Post $post ): void {
|
||||
wp_nonce_field( 'robotstxt_og_meta_box', 'robotstxt_og_meta_box_nonce' );
|
||||
|
||||
$og_title = (string) get_post_meta( $post->ID, '_og_title', true );
|
||||
$og_description = (string) get_post_meta( $post->ID, '_og_description', true );
|
||||
|
||||
?>
|
||||
<table class="form-table" role="presentation">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="robotstxt_og_title">
|
||||
<?php esc_html_e( 'Custom Title', 'robotstxt-og' ); ?>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
id="robotstxt_og_title"
|
||||
name="robotstxt_og_title"
|
||||
value="<?php echo esc_attr( $og_title ); ?>"
|
||||
class="large-text"
|
||||
/>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Overrides the default og:title for this post. Leave blank to use the post title automatically.', 'robotstxt-og' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="robotstxt_og_description">
|
||||
<?php esc_html_e( 'Custom Description', 'robotstxt-og' ); ?>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<textarea
|
||||
id="robotstxt_og_description"
|
||||
name="robotstxt_og_description"
|
||||
class="large-text"
|
||||
rows="3"
|
||||
><?php echo esc_textarea( $og_description ); ?></textarea>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Overrides the default og:description for this post. Leave blank to use the excerpt automatically.', 'robotstxt-og' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box values on post save.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @param int $post_id The post ID.
|
||||
* @param WP_Post $post The post object.
|
||||
* @return void
|
||||
*/
|
||||
public function save_meta_box( int $post_id, WP_Post $post ): void {
|
||||
// Skip autosaves and revisions.
|
||||
if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify nonce.
|
||||
$nonce_raw = filter_input( INPUT_POST, 'robotstxt_og_meta_box_nonce', FILTER_SANITIZE_SPECIAL_CHARS );
|
||||
$nonce = $nonce_raw ? sanitize_text_field( wp_unslash( $nonce_raw ) ) : '';
|
||||
|
||||
if ( ! wp_verify_nonce( $nonce, 'robotstxt_og_meta_box' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check permissions.
|
||||
$post_type_obj = get_post_type_object( $post->post_type );
|
||||
|
||||
if ( ! $post_type_obj || ! current_user_can( $post_type_obj->cap->edit_post, $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save og:title.
|
||||
$og_title_raw = filter_input( INPUT_POST, 'robotstxt_og_title', FILTER_SANITIZE_SPECIAL_CHARS );
|
||||
$og_title = $og_title_raw ? sanitize_text_field( wp_unslash( $og_title_raw ) ) : '';
|
||||
|
||||
if ( empty( $og_title ) ) {
|
||||
delete_post_meta( $post_id, '_og_title' );
|
||||
} else {
|
||||
update_post_meta( $post_id, '_og_title', $og_title );
|
||||
}
|
||||
|
||||
// Save og:description.
|
||||
$og_desc_raw = filter_input( INPUT_POST, 'robotstxt_og_description', FILTER_UNSAFE_RAW );
|
||||
$og_desc = $og_desc_raw ? sanitize_textarea_field( wp_unslash( $og_desc_raw ) ) : '';
|
||||
|
||||
if ( empty( $og_desc ) ) {
|
||||
delete_post_meta( $post_id, '_og_description' );
|
||||
} else {
|
||||
update_post_meta( $post_id, '_og_description', $og_desc );
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue