<?php
/*
Plugin Name: PlainPath Design Architect Pro
Description: Complete AI-Optimized Azure Design Tool with Dynamic Repeaters & Schema.
Version: 2.0
Author: Kushal Ahuja
*/
// 1. ADMIN ASSETS & MEDIA LIBRARY
add_action('admin_enqueue_scripts', function($hook) {
if ('post.php' != $hook && 'post-new.php' != $hook) return;
wp_enqueue_media();
});
// 2. SEO & AI SCHEMA INJECTION (AEO/GEO Optimization)
add_action('wp_head', function() {
if (!is_single()) return;
$id = get_the_ID();
$title = get_post_meta($id, 'pp_seo_title', true) ?: get_the_title();
$desc = get_post_meta($id, 'pp_seo_desc', true);
$keys = get_post_meta($id, 'pp_seo_keys', true);
if ($desc) {
echo '<meta name="description" content="' . esc_attr($desc) . '">' . "\n";
echo '<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "' . esc_attr($title) . '",
"description": "' . esc_attr($desc) . '",
"keywords": "' . esc_attr($keys) . '",
"author": { "@type": "Person", "name": "Kushal Ahuja" }
}
</script>' . "\n";
}
});
// 3. META BOX UI
add_action('add_meta_boxes', function() {
add_meta_box('pp_v2_box', 'PlainPath Design Architect v2.0', 'pp_render_v2_box', 'post', 'normal', 'high');
});
function pp_render_v2_box($post) {
wp_nonce_field('pp_v2_nonce', 'pp_v2_nonce_field');
// Retrieve Data
$seo_title = get_post_meta($post->ID, 'pp_seo_title', true);
$seo_desc = get_post_meta($post->ID, 'pp_seo_desc', true);
$seo_keys = get_post_meta($post->ID, 'pp_seo_keys', true);
$problem = get_post_meta($post->ID, 'pp_problem', true);
$comps = get_post_meta($post->ID, 'pp_components', true) ?: [];
$diags = get_post_meta($post->ID, 'pp_diagrams', true) ?: [];
$facts = get_post_meta($post->ID, 'pp_facts', true) ?: [];
$deep = get_post_meta($post->ID, 'pp_deep_dive', true);
?>
<style>
.pp-v2-section { border: 1px solid #ddd; padding: 15px; margin-bottom: 20px; background: #fff; border-left: 4px solid #000; }
.pp-row { display: flex; gap: 10px; margin-bottom: 10px; align-items: center; }
label { font-weight: bold; display: block; margin-bottom: 5px; }
</style>
<div id="pp-v2-container">
<!-- SEO FIELDS -->
<div class="pp-v2-section" style="background: #f0f8ff; border-left-color: #0073aa;">
<label>AI & SEO Optimization</label>
<input type="text" name="pp_seo_title" value="<?php echo esc_attr($seo_title); ?>" placeholder="AI Optimized Title" style="width:100%; margin-bottom:5px;">
<textarea name="pp_seo_desc" placeholder="Meta Description (AI Signal)" style="width:100%; height:50px;"><?php echo esc_textarea($seo_desc); ?></textarea>
<input type="text" name="pp_seo_keys" value="<?php echo esc_attr($seo_keys); ?>" placeholder="Keywords (comma separated)" style="width:100%;">
</div>
<!-- PART 1 -->
<div class="pp-v2-section">
<label>Part 1: Problem Statement (NotebookLM)</label>
<textarea name="pp_problem" id="pp_problem" style="width:100%; height:80px;"><?php echo esc_textarea($problem); ?></textarea>
</div>
<!-- PART 2 -->
<div class="pp-v2-section">
<label>Part 2: Components & Videos</label>
<div id="comp-wrap">
<?php foreach($comps as $c): ?>
<div class="pp-row"><input type="text" name="c_name[]" class="c-name" value="<?php echo esc_attr($c['name']); ?>" placeholder="Service" style="width:40%;"><input type="text" name="c_vid[]" class="c-vid" value="<?php echo esc_attr($c['vid']); ?>" placeholder="YouTube ID" style="width:50%;"><button type="button" class="remove-pp">X</button></div>
<?php endforeach; ?>
</div>
<button type="button" class="add-pp button" data-type="comp">Add Component</button>
</div>
<!-- PART 3 -->
<div class="pp-v2-section">
<label>Part 3: Architecture Diagrams (HLD/LLD)</label>
<div id="diag-wrap">
<?php foreach($diags as $d): ?>
<div class="pp-row"><select name="d_type[]" class="d-type" style="width:20%;"><option value="HLD" <?php selected($d['type'], 'HLD'); ?>>HLD</option><option value="LLD" <?php selected($d['type'], 'LLD'); ?>>LLD</option></select><input type="text" name="d_url[]" class="d-url" value="<?php echo esc_attr($d['url']); ?>" style="width:50%;"><button type="button" class="pp-upload button">Upload</button><button type="button" class="remove-pp">X</button></div>
<?php endforeach; ?>
</div>
<button type="button" class="add-pp button" data-type="diag">Add Diagram Block</button>
</div>
<!-- PART 4 -->
<div class="pp-v2-section">
<label>Part 4: Detailed Implementation (Excel Table)</label>
<div id="fact-wrap">
<?php foreach($facts as $f): ?>
<div class="pp-row"><input type="text" name="f_key[]" class="f-key" value="<?php echo esc_attr($f['key']); ?>" style="width:45%;" placeholder="Param"><input type="text" name="f_val[]" class="f-val" value="<?php echo esc_attr($f['val']); ?>" style="width:45%;" placeholder="Value"><button type="button" class="remove-pp">X</button></div>
<?php endforeach; ?>
</div>
<button type="button" class="add-pp button" data-type="fact">Add Extra Row</button>
<textarea name="pp_deep_dive" id="pp_deep_dive" style="width:100%; margin-top:10px; height:80px;"><?php echo esc_textarea($deep); ?></textarea>
</div>
<!-- GENERATE HTML (ACTUAL FIX) -->
<div class="pp-v2-section" style="background:#fff7e6;">
<button type="button" id="pp-gen-btn" class="button button-primary">Generate Final HTML</button>
<textarea id="pp-preview" readonly style="width:100%; height:150px; margin-top:10px; display:none;"></textarea>
</div>
</div>
<script>
jQuery(document).ready(function($){
$('.add-pp').on('click', function(){
var type = $(this).data('type');
if(type==='comp') $('#comp-wrap').append('<div class="pp-row"><input type="text" name="c_name[]" class="c-name" style="width:40%;"><input type="text" name="c_vid[]" class="c-vid" style="width:50%;"><button type="button" class="remove-pp">X</button></div>');
if(type==='diag') $('#diag-wrap').append('<div class="pp-row"><select name="d_type[]" class="d-type" style="width:20%;"><option value="HLD">HLD</option><option value="LLD">LLD</option></select><input type="text" name="d_url[]" class="d-url" style="width:50%;"><button type="button" class="pp-upload button">Upload</button><button type="button" class="remove-pp">X</button></div>');
if(type==='fact') $('#fact-wrap').append('<div class="pp-row"><input type="text" name="f_key[]" class="f-key" style="width:45%;"><input type="text" name="f_val[]" class="f-val" style="width:45%;"><button type="button" class="remove-pp">X</button></div>');
});
$(document).on('click', '.pp-upload', function(e){
e.preventDefault(); var btn = $(this);
wp.media({ title: 'Select Image', multiple: false }).on('select', function() {
btn.prev('.d-url').val(this.get('selection').first().toJSON().url);
}).open();
});
$(document).on('click', '.remove-pp', function(){ $(this).parent().remove(); });
$('#pp-gen-btn').on('click', function(){
var h = "<div class='plainpath-architect'>\n<h2>Part 1</h2><p>"+$('#pp_problem').val()+"</p>\n";
h += "<h2>Part 4 Narrative</h2><p>"+$('#pp_deep_dive').val()+"</p>\n</div>";
$('#pp-preview').show().val(h);
});
});
</script>
<?php
}
// 4. SAVE LOGIC (PREVENTS DISAPPEARING CONTENT)
add_action('save_post', function($post_id) {
if (!isset($_POST['pp_v2_nonce_field']) || !wp_verify_nonce($_POST['pp_v2_nonce_field'], 'pp_v2_nonce')) return;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
update_post_meta($post_id, 'pp_seo_title', $_POST['pp_seo_title']);
update_post_meta($post_id, 'pp_seo_desc', $_POST['pp_seo_desc']);
update_post_meta($post_id, 'pp_seo_keys', $_POST['pp_seo_keys']);
update_post_meta($post_id, 'pp_problem', $_POST['pp_problem']);
update_post_meta($post_id, 'pp_deep_dive', $_POST['pp_deep_dive']);
$comps = []; if(isset($_POST['c_name'])) foreach($_POST['c_name'] as $i => $n) if(!empty($n)) $comps[] = ['name' => $n, 'vid' => $_POST['c_vid'][$i]];
update_post_meta($post_id, 'pp_components', $comps);
$diags = []; if(isset($_POST['d_url'])) foreach($_POST['d_url'] as $i => $u) if(!empty($u)) $diags[] = ['url' => $u, 'type' => $_POST['d_type'][$i]];
update_post_meta($post_id, 'pp_diagrams', $diags);
$facts = []; if(isset($_POST['f_key'])) foreach($_POST['f_key'] as $i => $k) if(!empty($k)) $facts[] = ['key' => $k, 'val' => $_POST['f_val'][$i]];
update_post_meta($post_id, 'pp_facts', $facts);
});
// 5. FRONT-END RENDERING (FIXED)
add_filter('the_content', function($content) {
if (!is_single()) return $content;
$id = get_the_ID();
$problem = get_post_meta($id, 'pp_problem', true);
if (empty($problem)) return $content;
$comps = get_post_meta($id, 'pp_components', true) ?: [];
$diags = get_post_meta($id, 'pp_diagrams', true) ?: [];
$facts = get_post_meta($id, 'pp_facts', true) ?: [];
$deep = get_post_meta($id, 'pp_deep_dive', true);
$html = "<div class='pp-design-wrapper' style='border-top:3px solid #000; margin-top:30px;'>";
$html .= "<h2>Part 1: The Problem</h2><p>".nl2br(esc_html($problem))."</p>";
$html .= "<h2>Part 2: Components</h2><table style='width:100%; border-collapse:collapse;'>";
foreach($comps as $c) $html .= "<tr><td style='border:1px solid #ccc; padding:10px;'>".esc_html($c['name'])."</td><td style='border:1px solid #ccc; background:#000; color:#fff; text-align:center;'>Video ID: ".esc_html($c['vid'])."</td></tr>";
$html .= "</table>";
$html .= "<h2>Part 3: Architecture</h2>";
foreach($diags as $d) $html .= "<div style='border:1px solid #ddd; padding:10px; margin-bottom:15px;'><strong>".esc_html($d['type'])."</strong><img src='".esc_url($d['url'])."' style='width:100%;'></div>";
$html .= "<h2>Part 4: Detailed Implementation</h2><table style='width:100%; border-collapse:collapse; margin-bottom:15px;'>";
foreach($facts as $f) $html .= "<tr><td style='border:1px solid #eee; padding:10px;'><strong>".esc_html($f['key'])."</strong></td><td style='border:1px solid #eee; padding:10px;'>".esc_html($f['val'])."</td></tr>";
$html .= "</table><div style='padding:15px; border-left:3px solid #000; background:#f9f9f9;'>".nl2br(esc_html($deep))."</div></div>";
return $content . $html;
});
Test 3
by
Tags:
Leave a Reply