wp plugin
This commit is contained in:
469
igny8-wp-plugin/admin/class-post-meta-boxes.php
Normal file
469
igny8-wp-plugin/admin/class-post-meta-boxes.php
Normal file
@@ -0,0 +1,469 @@
|
||||
<?php
|
||||
/**
|
||||
* Post Meta Boxes
|
||||
*
|
||||
* Adds meta boxes to post editor for IGNY8 features
|
||||
*
|
||||
* @package Igny8Bridge
|
||||
*/
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Igny8PostMetaBoxes Class
|
||||
*/
|
||||
class Igny8PostMetaBoxes {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('add_meta_boxes', array($this, 'add_meta_boxes'));
|
||||
add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts'));
|
||||
|
||||
// AJAX handlers
|
||||
add_action('wp_ajax_igny8_fetch_planner_brief', array($this, 'fetch_planner_brief'));
|
||||
add_action('wp_ajax_igny8_refresh_planner_task', array($this, 'refresh_planner_task'));
|
||||
add_action('wp_ajax_igny8_create_optimizer_job', array($this, 'create_optimizer_job'));
|
||||
add_action('wp_ajax_igny8_get_optimizer_status', array($this, 'get_optimizer_status'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add meta boxes to post editor
|
||||
*/
|
||||
public function add_meta_boxes() {
|
||||
$post_types = array('post', 'page', 'product');
|
||||
|
||||
foreach ($post_types as $post_type) {
|
||||
add_meta_box(
|
||||
'igny8-planner-brief',
|
||||
__('IGNY8 Planner Brief', 'igny8-bridge'),
|
||||
array($this, 'render_planner_brief_box'),
|
||||
$post_type,
|
||||
'side',
|
||||
'default'
|
||||
);
|
||||
|
||||
add_meta_box(
|
||||
'igny8-optimizer',
|
||||
__('IGNY8 Optimizer', 'igny8-bridge'),
|
||||
array($this, 'render_optimizer_box'),
|
||||
$post_type,
|
||||
'side',
|
||||
'default'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts for post editor
|
||||
*/
|
||||
public function enqueue_scripts($hook) {
|
||||
if (!in_array($hook, array('post.php', 'post-new.php'), true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_script(
|
||||
'igny8-post-editor',
|
||||
IGNY8_BRIDGE_PLUGIN_URL . 'admin/assets/js/post-editor.js',
|
||||
array('jquery'),
|
||||
IGNY8_BRIDGE_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script('igny8-post-editor', 'igny8PostEditor', array(
|
||||
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('igny8_post_editor_nonce'),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Planner Brief meta box
|
||||
*/
|
||||
public function render_planner_brief_box($post) {
|
||||
$task_id = get_post_meta($post->ID, '_igny8_task_id', true);
|
||||
$brief = get_post_meta($post->ID, '_igny8_task_brief', true);
|
||||
$brief_cached_at = get_post_meta($post->ID, '_igny8_brief_cached_at', true);
|
||||
$cluster_id = get_post_meta($post->ID, '_igny8_cluster_id', true);
|
||||
|
||||
if (!$task_id && !$cluster_id) {
|
||||
echo '<p class="description">';
|
||||
_e('This post is not linked to an IGNY8 task or cluster.', 'igny8-bridge');
|
||||
echo '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
wp_nonce_field('igny8_post_editor_nonce', 'igny8_post_editor_nonce');
|
||||
?>
|
||||
<div id="igny8-planner-brief-content">
|
||||
<?php if ($brief) : ?>
|
||||
<div class="igny8-brief-display">
|
||||
<?php if (is_array($brief)) : ?>
|
||||
<?php if (!empty($brief['title'])) : ?>
|
||||
<h4><?php echo esc_html($brief['title']); ?></h4>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($brief['content'])) : ?>
|
||||
<div class="igny8-brief-content">
|
||||
<?php echo wp_kses_post(wpautop($brief['content'])); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($brief['outline'])) : ?>
|
||||
<div class="igny8-brief-outline">
|
||||
<strong><?php _e('Outline:', 'igny8-bridge'); ?></strong>
|
||||
<?php if (is_array($brief['outline'])) : ?>
|
||||
<ul>
|
||||
<?php foreach ($brief['outline'] as $item) : ?>
|
||||
<li><?php echo esc_html($item); ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php else : ?>
|
||||
<p><?php echo esc_html($brief['outline']); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($brief['keywords'])) : ?>
|
||||
<div class="igny8-brief-keywords">
|
||||
<strong><?php _e('Keywords:', 'igny8-bridge'); ?></strong>
|
||||
<?php
|
||||
$keywords = is_array($brief['keywords']) ? $brief['keywords'] : explode(',', $brief['keywords']);
|
||||
echo '<span class="igny8-keyword-tags">';
|
||||
foreach ($keywords as $keyword) {
|
||||
echo '<span class="igny8-keyword-tag">' . esc_html(trim($keyword)) . '</span>';
|
||||
}
|
||||
echo '</span>';
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($brief['tone'])) : ?>
|
||||
<div class="igny8-brief-tone">
|
||||
<strong><?php _e('Tone:', 'igny8-bridge'); ?></strong>
|
||||
<?php echo esc_html($brief['tone']); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<p><?php echo esc_html($brief); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($brief_cached_at) : ?>
|
||||
<p class="description">
|
||||
<?php
|
||||
printf(
|
||||
__('Cached: %s', 'igny8-bridge'),
|
||||
date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($brief_cached_at))
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<p class="description">
|
||||
<?php _e('No brief cached. Click "Fetch Brief" to load from IGNY8.', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<button type="button"
|
||||
id="igny8-fetch-brief"
|
||||
class="button button-secondary"
|
||||
data-post-id="<?php echo esc_attr($post->ID); ?>"
|
||||
data-task-id="<?php echo esc_attr($task_id); ?>">
|
||||
<?php _e('Fetch Brief', 'igny8-bridge'); ?>
|
||||
</button>
|
||||
|
||||
<?php if ($task_id) : ?>
|
||||
<button type="button"
|
||||
id="igny8-refresh-task"
|
||||
class="button button-secondary"
|
||||
data-post-id="<?php echo esc_attr($post->ID); ?>"
|
||||
data-task-id="<?php echo esc_attr($task_id); ?>">
|
||||
<?php _e('Request Refresh', 'igny8-bridge'); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
|
||||
<div id="igny8-planner-brief-message" class="igny8-message" style="display: none;"></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Optimizer meta box
|
||||
*/
|
||||
public function render_optimizer_box($post) {
|
||||
$task_id = get_post_meta($post->ID, '_igny8_task_id', true);
|
||||
$optimizer_job_id = get_post_meta($post->ID, '_igny8_optimizer_job_id', true);
|
||||
$optimizer_status = get_post_meta($post->ID, '_igny8_optimizer_status', true);
|
||||
|
||||
if (!$task_id) {
|
||||
echo '<p class="description">';
|
||||
_e('This post is not linked to an IGNY8 task.', 'igny8-bridge');
|
||||
echo '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
wp_nonce_field('igny8_post_editor_nonce', 'igny8_post_editor_nonce');
|
||||
?>
|
||||
<div id="igny8-optimizer-content">
|
||||
<?php if ($optimizer_job_id) : ?>
|
||||
<div class="igny8-optimizer-status">
|
||||
<p>
|
||||
<strong><?php _e('Job ID:', 'igny8-bridge'); ?></strong>
|
||||
<?php echo esc_html($optimizer_job_id); ?>
|
||||
</p>
|
||||
|
||||
<?php if ($optimizer_status) : ?>
|
||||
<p>
|
||||
<strong><?php _e('Status:', 'igny8-bridge'); ?></strong>
|
||||
<span class="igny8-status-badge igny8-status-<?php echo esc_attr(strtolower($optimizer_status)); ?>">
|
||||
<?php echo esc_html($optimizer_status); ?>
|
||||
</span>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<p>
|
||||
<button type="button"
|
||||
id="igny8-check-optimizer-status"
|
||||
class="button button-secondary"
|
||||
data-post-id="<?php echo esc_attr($post->ID); ?>"
|
||||
data-job-id="<?php echo esc_attr($optimizer_job_id); ?>">
|
||||
<?php _e('Check Status', 'igny8-bridge'); ?>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<p class="description">
|
||||
<?php _e('No optimizer job created yet.', 'igny8-bridge'); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<button type="button"
|
||||
id="igny8-create-optimizer-job"
|
||||
class="button button-primary"
|
||||
data-post-id="<?php echo esc_attr($post->ID); ?>"
|
||||
data-task-id="<?php echo esc_attr($task_id); ?>">
|
||||
<?php _e('Request Optimization', 'igny8-bridge'); ?>
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<div id="igny8-optimizer-message" class="igny8-message" style="display: none;"></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch Planner brief (AJAX handler)
|
||||
*/
|
||||
public static function fetch_planner_brief() {
|
||||
check_ajax_referer('igny8_post_editor_nonce', 'nonce');
|
||||
|
||||
if (!current_user_can('edit_posts')) {
|
||||
wp_send_json_error(array('message' => 'Unauthorized'));
|
||||
}
|
||||
|
||||
if (!igny8_is_connection_enabled()) {
|
||||
wp_send_json_error(array('message' => 'Connection is disabled. Enable sync operations first.'));
|
||||
}
|
||||
|
||||
$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
|
||||
$task_id = isset($_POST['task_id']) ? intval($_POST['task_id']) : 0;
|
||||
|
||||
if (!$post_id || !$task_id) {
|
||||
wp_send_json_error(array('message' => 'Invalid post ID or task ID'));
|
||||
}
|
||||
|
||||
$api = new Igny8API();
|
||||
|
||||
if (!$api->is_authenticated()) {
|
||||
wp_send_json_error(array('message' => 'Not authenticated'));
|
||||
}
|
||||
|
||||
// Try to fetch from Planner first
|
||||
$response = $api->get("/planner/tasks/{$task_id}/brief/");
|
||||
|
||||
if (!$response['success']) {
|
||||
// Fallback to Writer brief
|
||||
$response = $api->get("/writer/tasks/{$task_id}/brief/");
|
||||
}
|
||||
|
||||
if ($response['success'] && !empty($response['data'])) {
|
||||
update_post_meta($post_id, '_igny8_task_brief', $response['data']);
|
||||
update_post_meta($post_id, '_igny8_brief_cached_at', current_time('mysql'));
|
||||
|
||||
wp_send_json_success(array(
|
||||
'message' => 'Brief fetched successfully',
|
||||
'brief' => $response['data']
|
||||
));
|
||||
} else {
|
||||
wp_send_json_error(array(
|
||||
'message' => 'Failed to fetch brief: ' . ($response['error'] ?? 'Unknown error')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh Planner task (AJAX handler)
|
||||
*/
|
||||
public static function refresh_planner_task() {
|
||||
check_ajax_referer('igny8_post_editor_nonce', 'nonce');
|
||||
|
||||
if (!current_user_can('edit_posts')) {
|
||||
wp_send_json_error(array('message' => 'Unauthorized'));
|
||||
}
|
||||
|
||||
if (!igny8_is_connection_enabled()) {
|
||||
wp_send_json_error(array('message' => 'Connection is disabled. Enable sync operations first.'));
|
||||
}
|
||||
|
||||
$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
|
||||
$task_id = isset($_POST['task_id']) ? intval($_POST['task_id']) : 0;
|
||||
|
||||
if (!$post_id || !$task_id) {
|
||||
wp_send_json_error(array('message' => 'Invalid post ID or task ID'));
|
||||
}
|
||||
|
||||
$api = new Igny8API();
|
||||
|
||||
if (!$api->is_authenticated()) {
|
||||
wp_send_json_error(array('message' => 'Not authenticated'));
|
||||
}
|
||||
|
||||
$response = $api->post("/planner/tasks/{$task_id}/refresh/", array(
|
||||
'wordpress_post_id' => $post_id,
|
||||
'reason' => 'reoptimize',
|
||||
'notes' => 'Requested refresh from WordPress editor'
|
||||
));
|
||||
|
||||
if ($response['success']) {
|
||||
wp_send_json_success(array(
|
||||
'message' => 'Refresh requested successfully',
|
||||
'data' => $response['data']
|
||||
));
|
||||
} else {
|
||||
wp_send_json_error(array(
|
||||
'message' => 'Failed to request refresh: ' . ($response['error'] ?? 'Unknown error')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Optimizer job (AJAX handler)
|
||||
*/
|
||||
public static function create_optimizer_job() {
|
||||
check_ajax_referer('igny8_post_editor_nonce', 'nonce');
|
||||
|
||||
if (!current_user_can('edit_posts')) {
|
||||
wp_send_json_error(array('message' => 'Unauthorized'));
|
||||
}
|
||||
|
||||
if (!igny8_is_connection_enabled()) {
|
||||
wp_send_json_error(array('message' => 'Connection is disabled. Enable sync operations first.'));
|
||||
}
|
||||
|
||||
$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
|
||||
$task_id = isset($_POST['task_id']) ? intval($_POST['task_id']) : 0;
|
||||
$job_type = isset($_POST['job_type']) ? sanitize_text_field($_POST['job_type']) : 'audit';
|
||||
$priority = isset($_POST['priority']) ? sanitize_text_field($_POST['priority']) : 'normal';
|
||||
|
||||
if (!$post_id || !$task_id) {
|
||||
wp_send_json_error(array('message' => 'Invalid post ID or task ID'));
|
||||
}
|
||||
|
||||
$api = new Igny8API();
|
||||
|
||||
if (!$api->is_authenticated()) {
|
||||
wp_send_json_error(array('message' => 'Not authenticated'));
|
||||
}
|
||||
|
||||
$response = $api->post("/optimizer/jobs/", array(
|
||||
'post_id' => $post_id,
|
||||
'task_id' => $task_id,
|
||||
'job_type' => $job_type,
|
||||
'priority' => $priority
|
||||
));
|
||||
|
||||
if ($response['success'] && !empty($response['data'])) {
|
||||
$job_id = $response['data']['id'] ?? $response['data']['job_id'] ?? null;
|
||||
|
||||
if ($job_id) {
|
||||
update_post_meta($post_id, '_igny8_optimizer_job_id', $job_id);
|
||||
update_post_meta($post_id, '_igny8_optimizer_status', $response['data']['status'] ?? 'pending');
|
||||
update_post_meta($post_id, '_igny8_optimizer_job_created_at', current_time('mysql'));
|
||||
}
|
||||
|
||||
wp_send_json_success(array(
|
||||
'message' => 'Optimizer job created successfully',
|
||||
'job_id' => $job_id,
|
||||
'data' => $response['data']
|
||||
));
|
||||
} else {
|
||||
wp_send_json_error(array(
|
||||
'message' => 'Failed to create optimizer job: ' . ($response['error'] ?? 'Unknown error')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Optimizer job status (AJAX handler)
|
||||
*/
|
||||
public static function get_optimizer_status() {
|
||||
check_ajax_referer('igny8_post_editor_nonce', 'nonce');
|
||||
|
||||
if (!current_user_can('edit_posts')) {
|
||||
wp_send_json_error(array('message' => 'Unauthorized'));
|
||||
}
|
||||
|
||||
if (!igny8_is_connection_enabled()) {
|
||||
wp_send_json_error(array('message' => 'Connection is disabled. Enable sync operations first.'));
|
||||
}
|
||||
|
||||
$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
|
||||
$job_id = isset($_POST['job_id']) ? intval($_POST['job_id']) : 0;
|
||||
|
||||
if (!$post_id || !$job_id) {
|
||||
wp_send_json_error(array('message' => 'Invalid post ID or job ID'));
|
||||
}
|
||||
|
||||
$api = new Igny8API();
|
||||
|
||||
if (!$api->is_authenticated()) {
|
||||
wp_send_json_error(array('message' => 'Not authenticated'));
|
||||
}
|
||||
|
||||
$response = $api->get("/optimizer/jobs/{$job_id}/");
|
||||
|
||||
if ($response['success'] && !empty($response['data'])) {
|
||||
$status = $response['data']['status'] ?? 'unknown';
|
||||
update_post_meta($post_id, '_igny8_optimizer_status', $status);
|
||||
|
||||
if (!empty($response['data']['score_changes'])) {
|
||||
update_post_meta($post_id, '_igny8_optimizer_score_changes', $response['data']['score_changes']);
|
||||
}
|
||||
|
||||
if (!empty($response['data']['recommendations'])) {
|
||||
update_post_meta($post_id, '_igny8_optimizer_recommendations', $response['data']['recommendations']);
|
||||
}
|
||||
|
||||
wp_send_json_success(array(
|
||||
'message' => 'Status retrieved successfully',
|
||||
'status' => $status,
|
||||
'data' => $response['data']
|
||||
));
|
||||
} else {
|
||||
wp_send_json_error(array(
|
||||
'message' => 'Failed to get status: ' . ($response['error'] ?? 'Unknown error')
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize
|
||||
new Igny8PostMetaBoxes();
|
||||
|
||||
Reference in New Issue
Block a user