Files
igny8/igny8-wp-integration-plugin/data/semantic-mapping.php
2025-11-21 19:18:24 +05:00

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
)
);
}