226 lines
7.2 KiB
PHP
226 lines
7.2 KiB
PHP
<?php
|
|
/**
|
|
* Semantic Strategy Mapping
|
|
*
|
|
* Maps WordPress site data to IGNY8 semantic structure
|
|
* Follows WORDPRESS-PLUGIN-INTEGRATION.md guidelines
|
|
*
|
|
* @package Igny8Bridge
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Map WordPress site data to IGNY8 semantic strategy
|
|
* This creates sectors, clusters, and keywords based on site structure
|
|
*
|
|
* @param int $site_id IGNY8 site ID
|
|
* @param array $site_data Site data from igny8_collect_site_data()
|
|
* @return array Response from IGNY8 API
|
|
*/
|
|
function igny8_map_site_to_semantic_strategy($site_id, $site_data) {
|
|
// Skip if connection is disabled
|
|
if (!igny8_is_connection_enabled()) {
|
|
return array('success' => false, 'error' => 'Connection disabled');
|
|
}
|
|
|
|
$api = new Igny8API();
|
|
|
|
if (!$api->is_authenticated()) {
|
|
return array('success' => false, 'error' => 'Not authenticated');
|
|
}
|
|
|
|
// Extract semantic structure from site data
|
|
$semantic_map = array(
|
|
'sectors' => array(),
|
|
'clusters' => array(),
|
|
'keywords' => array()
|
|
);
|
|
|
|
// Map taxonomies to sectors
|
|
foreach ($site_data['taxonomies'] as $tax_name => $tax_data) {
|
|
if ($tax_data['taxonomy']['hierarchical']) {
|
|
// Hierarchical taxonomies (categories) become sectors
|
|
$sector = array(
|
|
'name' => $tax_data['taxonomy']['label'],
|
|
'slug' => $tax_data['taxonomy']['name'],
|
|
'description' => $tax_data['taxonomy']['description'],
|
|
'source' => 'wordpress_taxonomy',
|
|
'source_id' => $tax_name
|
|
);
|
|
|
|
// Map terms to clusters
|
|
$clusters = array();
|
|
foreach ($tax_data['terms'] as $term) {
|
|
$clusters[] = array(
|
|
'name' => $term['name'],
|
|
'slug' => $term['slug'],
|
|
'description' => $term['description'],
|
|
'source' => 'wordpress_term',
|
|
'source_id' => $term['id']
|
|
);
|
|
|
|
// Extract keywords from posts in this term
|
|
$keywords = igny8_extract_keywords_from_term_posts($term['id'], $tax_name);
|
|
$semantic_map['keywords'] = array_merge($semantic_map['keywords'], $keywords);
|
|
}
|
|
|
|
$sector['clusters'] = $clusters;
|
|
$semantic_map['sectors'][] = $sector;
|
|
}
|
|
}
|
|
|
|
// Map WooCommerce product categories to sectors
|
|
if (!empty($site_data['product_categories'])) {
|
|
$product_sector = array(
|
|
'name' => 'Products',
|
|
'slug' => 'products',
|
|
'description' => 'WooCommerce product categories',
|
|
'source' => 'woocommerce',
|
|
'clusters' => array()
|
|
);
|
|
|
|
foreach ($site_data['product_categories'] as $category) {
|
|
$product_sector['clusters'][] = array(
|
|
'name' => $category['name'],
|
|
'slug' => $category['slug'],
|
|
'description' => $category['description'],
|
|
'source' => 'woocommerce_category',
|
|
'source_id' => $category['id']
|
|
);
|
|
}
|
|
|
|
$semantic_map['sectors'][] = $product_sector;
|
|
}
|
|
|
|
// Send semantic map to IGNY8
|
|
$response = $api->post("/planner/sites/{$site_id}/semantic-map/", array(
|
|
'semantic_map' => $semantic_map,
|
|
'site_data' => $site_data
|
|
));
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Extract keywords from posts associated with a taxonomy term
|
|
*
|
|
* @param int $term_id Term ID
|
|
* @param string $taxonomy Taxonomy name
|
|
* @return array Formatted keywords array
|
|
*/
|
|
function igny8_extract_keywords_from_term_posts($term_id, $taxonomy) {
|
|
$args = array(
|
|
'post_type' => 'any',
|
|
'posts_per_page' => -1,
|
|
'tax_query' => array(
|
|
array(
|
|
'taxonomy' => $taxonomy,
|
|
'field' => 'term_id',
|
|
'terms' => $term_id
|
|
)
|
|
)
|
|
);
|
|
|
|
$query = new WP_Query($args);
|
|
$keywords = array();
|
|
|
|
if ($query->have_posts()) {
|
|
while ($query->have_posts()) {
|
|
$query->the_post();
|
|
|
|
// Extract keywords from post title and content
|
|
$title_words = str_word_count(get_the_title(), 1);
|
|
$content_words = str_word_count(strip_tags(get_the_content()), 1);
|
|
|
|
// Combine and get unique keywords
|
|
$all_words = array_merge($title_words, $content_words);
|
|
$unique_words = array_unique(array_map('strtolower', $all_words));
|
|
|
|
// Filter out common words (stop words)
|
|
$stop_words = array('the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by');
|
|
$keywords = array_merge($keywords, array_diff($unique_words, $stop_words));
|
|
}
|
|
wp_reset_postdata();
|
|
}
|
|
|
|
// Format keywords
|
|
$formatted_keywords = array();
|
|
foreach (array_unique($keywords) as $keyword) {
|
|
if (strlen($keyword) > 3) { // Only keywords longer than 3 characters
|
|
$formatted_keywords[] = array(
|
|
'keyword' => $keyword,
|
|
'source' => 'wordpress_post',
|
|
'source_term_id' => $term_id
|
|
);
|
|
}
|
|
}
|
|
|
|
return $formatted_keywords;
|
|
}
|
|
|
|
/**
|
|
* Complete workflow: Fetch site data → Map to semantic strategy → Restructure content
|
|
*
|
|
* @param int $site_id IGNY8 site ID
|
|
* @return array|false Analysis result or false on failure
|
|
*/
|
|
function igny8_analyze_and_restructure_site($site_id) {
|
|
$api = new Igny8API();
|
|
|
|
if (!$api->is_authenticated()) {
|
|
return false;
|
|
}
|
|
|
|
// Step 1: Collect all site data
|
|
$site_data = igny8_collect_site_data();
|
|
|
|
// Step 2: Send to IGNY8 for analysis
|
|
$analysis_response = $api->post("/system/sites/{$site_id}/analyze/", array(
|
|
'site_data' => $site_data,
|
|
'analysis_type' => 'full_site_restructure'
|
|
));
|
|
|
|
if (!$analysis_response['success']) {
|
|
return false;
|
|
}
|
|
|
|
$analysis_id = $analysis_response['data']['analysis_id'] ?? null;
|
|
|
|
// Step 3: Map to semantic strategy
|
|
$mapping_response = igny8_map_site_to_semantic_strategy($site_id, $site_data);
|
|
|
|
if (!$mapping_response['success']) {
|
|
return false;
|
|
}
|
|
|
|
// Step 4: Get restructuring recommendations
|
|
$recommendations_response = $api->get("/system/sites/{$site_id}/recommendations/");
|
|
|
|
if (!$recommendations_response['success']) {
|
|
return false;
|
|
}
|
|
|
|
// Get keywords count from mapping response
|
|
$keywords_count = 0;
|
|
if (isset($mapping_response['data']['keywords'])) {
|
|
$keywords_count = count($mapping_response['data']['keywords']);
|
|
}
|
|
|
|
return array(
|
|
'analysis_id' => $analysis_id,
|
|
'semantic_map' => $mapping_response['data'] ?? null,
|
|
'recommendations' => $recommendations_response['data'] ?? null,
|
|
'site_data_summary' => array(
|
|
'total_posts' => count($site_data['posts']),
|
|
'total_taxonomies' => count($site_data['taxonomies']),
|
|
'total_products' => count($site_data['products'] ?? array()),
|
|
'total_keywords' => $keywords_count
|
|
)
|
|
);
|
|
}
|
|
|