Files
igny8/igny8-wp-plugin/admin/class-post-meta-boxes.php
IGNY8 VPS (Salman) b2012e9563 plugin fixes
2025-12-01 07:59:19 +00:00

366 lines
13 KiB
PHP

<?php
/**
* Post Meta Boxes
*
* Handles custom meta boxes for IGNY8-created posts.
* Displays keywords, SEO fields, and sync data in WordPress post editor.
*
* @package IGNY8_Bridge
* @since 1.1.0
*/
if (!defined('ABSPATH')) {
exit;
}
class IGNY8_Post_Meta_Boxes {
/**
* Initialize meta boxes
*/
public function __construct() {
add_action('add_meta_boxes', array($this, 'add_meta_boxes'));
add_action('save_post', array($this, 'save_meta_boxes'), 10, 2);
}
/**
* Register meta boxes
*/
public function add_meta_boxes() {
// Only add meta boxes for posts that have IGNY8 content ID
$screen = get_current_screen();
if ($screen && $screen->post_type === 'post') {
// Keywords meta box
add_meta_box(
'igny8_keywords',
__('IGNY8 Keywords', 'igny8-bridge'),
array($this, 'render_keywords_meta_box'),
'post',
'side',
'high'
);
// SEO meta box
add_meta_box(
'igny8_seo',
__('IGNY8 SEO', 'igny8-bridge'),
array($this, 'render_seo_meta_box'),
'post',
'normal',
'high'
);
// Sync data meta box (read-only info)
add_meta_box(
'igny8_sync_data',
__('IGNY8 Sync Data', 'igny8-bridge'),
array($this, 'render_sync_data_meta_box'),
'post',
'side',
'default'
);
}
}
/**
* Render Keywords meta box
*/
public function render_keywords_meta_box($post) {
wp_nonce_field('igny8_keywords_nonce', 'igny8_keywords_nonce');
$primary_keyword = get_post_meta($post->ID, '_igny8_primary_keyword', true);
$secondary_keywords = get_post_meta($post->ID, '_igny8_secondary_keywords', true);
// Convert comma-separated string to array for display
$secondary_keywords_array = !empty($secondary_keywords) ? explode(',', $secondary_keywords) : array();
?>
<div class="igny8-keywords-fields">
<p>
<label for="igny8_primary_keyword"><strong><?php _e('Primary Keyword:', 'igny8-bridge'); ?></strong></label><br>
<input type="text" id="igny8_primary_keyword" name="igny8_primary_keyword"
value="<?php echo esc_attr($primary_keyword); ?>"
class="widefat"
placeholder="<?php _e('Enter primary keyword', 'igny8-bridge'); ?>">
</p>
<p>
<label for="igny8_secondary_keywords"><strong><?php _e('Secondary Keywords:', 'igny8-bridge'); ?></strong></label><br>
<textarea id="igny8_secondary_keywords" name="igny8_secondary_keywords"
rows="3" class="widefat"
placeholder="<?php _e('Enter secondary keywords, one per line', 'igny8-bridge'); ?>"><?php
echo esc_textarea(implode("\n", $secondary_keywords_array));
?></textarea>
<span class="description"><?php _e('Enter one keyword per line', 'igny8-bridge'); ?></span>
</p>
</div>
<style>
.igny8-keywords-fields input[type="text"],
.igny8-keywords-fields textarea {
margin-top: 5px;
}
.igny8-keywords-fields .description {
display: block;
margin-top: 5px;
font-style: italic;
color: #666;
}
</style>
<?php
}
/**
* Render SEO meta box
*/
public function render_seo_meta_box($post) {
wp_nonce_field('igny8_seo_nonce', 'igny8_seo_nonce');
$meta_title = get_post_meta($post->ID, '_igny8_meta_title', true);
$meta_description = get_post_meta($post->ID, '_igny8_meta_description', true);
?>
<div class="igny8-seo-fields">
<p>
<label for="igny8_meta_title"><strong><?php _e('SEO Title:', 'igny8-bridge'); ?></strong></label><br>
<input type="text" id="igny8_meta_title" name="igny8_meta_title"
value="<?php echo esc_attr($meta_title); ?>"
class="widefat"
placeholder="<?php _e('Enter SEO title', 'igny8-bridge'); ?>"
maxlength="60">
<span class="description char-count">
<?php
$title_length = mb_strlen($meta_title);
printf(__('%d characters (recommended: 50-60)', 'igny8-bridge'), $title_length);
?>
</span>
</p>
<p>
<label for="igny8_meta_description"><strong><?php _e('Meta Description:', 'igny8-bridge'); ?></strong></label><br>
<textarea id="igny8_meta_description" name="igny8_meta_description"
rows="3" class="widefat"
placeholder="<?php _e('Enter meta description', 'igny8-bridge'); ?>"
maxlength="160"><?php echo esc_textarea($meta_description); ?></textarea>
<span class="description char-count">
<?php
$desc_length = mb_strlen($meta_description);
printf(__('%d characters (recommended: 150-160)', 'igny8-bridge'), $desc_length);
?>
</span>
</p>
<p class="description">
<strong><?php _e('Note:', 'igny8-bridge'); ?></strong>
<?php _e('These SEO fields are synchronized with Yoast SEO, Rank Math, and All in One SEO plugins.', 'igny8-bridge'); ?>
</p>
</div>
<style>
.igny8-seo-fields input[type="text"],
.igny8-seo-fields textarea {
margin-top: 5px;
}
.igny8-seo-fields .description {
display: block;
margin-top: 5px;
font-style: italic;
color: #666;
}
.igny8-seo-fields .char-count {
font-size: 12px;
}
</style>
<script>
jQuery(document).ready(function($) {
// Character counter for SEO title
$('#igny8_meta_title').on('input', function() {
var length = $(this).val().length;
var color = length > 60 ? 'red' : (length < 50 ? 'orange' : 'green');
$(this).next('.char-count').text(length + ' characters (recommended: 50-60)').css('color', color);
});
// Character counter for meta description
$('#igny8_meta_description').on('input', function() {
var length = $(this).val().length;
var color = length > 160 ? 'red' : (length < 150 ? 'orange' : 'green');
$(this).next('.char-count').text(length + ' characters (recommended: 150-160)').css('color', color);
});
});
</script>
<?php
}
/**
* Render Sync Data meta box (read-only)
*/
public function render_sync_data_meta_box($post) {
$content_id = get_post_meta($post->ID, '_igny8_content_id', true);
$task_id = get_post_meta($post->ID, '_igny8_task_id', true);
$last_sync = get_post_meta($post->ID, '_igny8_last_sync', true);
$cluster_id = get_post_meta($post->ID, '_igny8_cluster_id', true);
$sector_id = get_post_meta($post->ID, '_igny8_sector_id', true);
?>
<div class="igny8-sync-data">
<?php if ($content_id): ?>
<p>
<strong><?php _e('IGNY8 Content ID:', 'igny8-bridge'); ?></strong><br>
<code><?php echo esc_html($content_id); ?></code>
</p>
<?php endif; ?>
<?php if ($task_id): ?>
<p>
<strong><?php _e('IGNY8 Task ID:', 'igny8-bridge'); ?></strong><br>
<code><?php echo esc_html($task_id); ?></code>
</p>
<?php endif; ?>
<?php if ($cluster_id): ?>
<p>
<strong><?php _e('Cluster ID:', 'igny8-bridge'); ?></strong><br>
<code><?php echo esc_html($cluster_id); ?></code>
</p>
<?php endif; ?>
<?php if ($sector_id): ?>
<p>
<strong><?php _e('Sector ID:', 'igny8-bridge'); ?></strong><br>
<code><?php echo esc_html($sector_id); ?></code>
</p>
<?php endif; ?>
<?php if ($last_sync): ?>
<p>
<strong><?php _e('Last Synced:', 'igny8-bridge'); ?></strong><br>
<?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($last_sync))); ?>
</p>
<?php endif; ?>
<?php if (!$content_id && !$task_id): ?>
<p class="description">
<?php _e('This post was not created by IGNY8.', 'igny8-bridge'); ?>
</p>
<?php endif; ?>
</div>
<style>
.igny8-sync-data p {
margin: 10px 0;
}
.igny8-sync-data code {
display: inline-block;
background: #f0f0f0;
padding: 2px 6px;
border-radius: 3px;
font-size: 12px;
}
</style>
<?php
}
/**
* Save meta boxes
*/
public function save_meta_boxes($post_id, $post) {
// Check if this is an autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// Check if this is a revision
if (wp_is_post_revision($post_id)) {
return;
}
// Check post type
if ($post->post_type !== 'post') {
return;
}
// Check user permissions
if (!current_user_can('edit_post', $post_id)) {
return;
}
// Save keywords
if (isset($_POST['igny8_keywords_nonce']) && wp_verify_nonce($_POST['igny8_keywords_nonce'], 'igny8_keywords_nonce')) {
// Save primary keyword
if (isset($_POST['igny8_primary_keyword'])) {
$primary_keyword = sanitize_text_field($_POST['igny8_primary_keyword']);
update_post_meta($post_id, '_igny8_primary_keyword', $primary_keyword);
}
// Save secondary keywords
if (isset($_POST['igny8_secondary_keywords'])) {
$secondary_keywords_raw = sanitize_textarea_field($_POST['igny8_secondary_keywords']);
// Convert newlines to commas for storage
$secondary_keywords_array = array_filter(array_map('trim', explode("\n", $secondary_keywords_raw)));
$secondary_keywords = implode(',', $secondary_keywords_array);
update_post_meta($post_id, '_igny8_secondary_keywords', $secondary_keywords);
}
}
// Save SEO fields
if (isset($_POST['igny8_seo_nonce']) && wp_verify_nonce($_POST['igny8_seo_nonce'], 'igny8_seo_nonce')) {
// Save meta title
if (isset($_POST['igny8_meta_title'])) {
$meta_title = sanitize_text_field($_POST['igny8_meta_title']);
update_post_meta($post_id, '_igny8_meta_title', $meta_title);
// Also update for SEO plugins
$this->sync_seo_title($post_id, $meta_title);
}
// Save meta description
if (isset($_POST['igny8_meta_description'])) {
$meta_description = sanitize_textarea_field($_POST['igny8_meta_description']);
update_post_meta($post_id, '_igny8_meta_description', $meta_description);
// Also update for SEO plugins
$this->sync_seo_description($post_id, $meta_description);
}
}
}
/**
* Sync SEO title to popular SEO plugins
*/
private function sync_seo_title($post_id, $title) {
if (empty($title)) {
return;
}
// Yoast SEO
update_post_meta($post_id, '_yoast_wpseo_title', $title);
// Rank Math
update_post_meta($post_id, 'rank_math_title', $title);
// All in One SEO
update_post_meta($post_id, '_aioseo_title', $title);
}
/**
* Sync SEO description to popular SEO plugins
*/
private function sync_seo_description($post_id, $description) {
if (empty($description)) {
return;
}
// Yoast SEO
update_post_meta($post_id, '_yoast_wpseo_metadesc', $description);
// Rank Math
update_post_meta($post_id, 'rank_math_description', $description);
// All in One SEO
update_post_meta($post_id, '_aioseo_description', $description);
}
}
// Initialize
new IGNY8_Post_Meta_Boxes();