Files
advanced-mcp-plugin/includes/Extensions/Batch13.php
T

147 lines
7.5 KiB
PHP

<?php
/**
* Batch 13 — Woodmart functionality (Pro-equivalent, net-new).
*
* Builds on b12's option helpers with the theme's real build surface:
* its Elementor widgets, the Header/Footer/Layout builder (woodmart_layout CPT),
* and reusable HTML Blocks (cms_block CPT). Guarded — inert unless the active
* theme is Woodmart. GPL-2.0-or-later. See NOTICE.md.
*/
namespace AskTamMCP\Extensions;
defined('ABSPATH') || exit;
class Batch13 {
public static function register($registry): void {
if (!self::isWoodmart()) return;
$def = function (string $name, string $desc, array $props, array $required, string $scope, string $method) {
$schema = ['type' => 'object', 'properties' => $props];
if ($required) $schema['required'] = $required;
return ['name' => $name, 'description' => $desc, 'scope' => $scope,
'handler' => 'AskTamMCP\\Extensions\\Batch13::' . $method, 'inputSchema' => $schema];
};
$registry->register($def('woodmart_list_widgets', 'List Woodmart Elementor widgets (wd_* and Woodmart WP widgets) with name and title. group = wd | wp | all (default all).',
['group' => ['type' => 'string', 'enum' => ['wd', 'wp', 'all']]], [], 'read', 'listWidgets'));
$registry->register($def('woodmart_list_layouts', 'List Woodmart Layout Builder entries (woodmart_layout CPT: headers, footers, page/shop layouts). Returns id, title, status, and the meta keys present on each.',
['status' => ['type' => 'string'], 'per_page' => ['type' => 'integer', 'default' => 50]], [], 'read', 'listLayouts'));
$registry->register($def('woodmart_list_html_blocks', 'List Woodmart HTML Blocks (cms_block CPT), each with its id, title, status, and ready-to-use shortcode.',
['status' => ['type' => 'string'], 'per_page' => ['type' => 'integer', 'default' => 50]], [], 'read', 'listBlocks'));
$registry->register($def('woodmart_get_block', 'Get one Woodmart HTML Block or Layout by id: title, status, whether it is Elementor-built, a content/length summary, and its shortcode.',
['id' => ['type' => 'integer']], ['id'], 'read', 'getBlock'));
$registry->register($def('woodmart_create_html_block', 'Create a Woodmart HTML Block (cms_block). Returns the new id and its [woodmart_html_block] shortcode. content is classic HTML/shortcode markup; status defaults to publish.',
['title' => ['type' => 'string'], 'content' => ['type' => 'string'], 'status' => ['type' => 'string', 'enum' => ['publish', 'draft']]], ['title'], 'write', 'createBlock'));
}
private static function isWoodmart(): bool {
if (function_exists('woodmart_get_opt')) return true;
$t = wp_get_theme();
$cands = [$t->get('TextDomain'), $t->get_template(), strtolower((string) $t->get('Name'))];
return in_array('woodmart', array_map('strtolower', array_filter($cands)), true);
}
public static function listWidgets(array $args): array {
$group = isset($args['group']) ? (string) $args['group'] : 'all';
if (!class_exists('\Elementor\Plugin')) {
throw new \RuntimeException('Elementor is not active; Woodmart Elementor widgets are unavailable.');
}
$types = \Elementor\Plugin::instance()->widgets_manager->get_widget_types();
$out = [];
foreach ($types as $name => $w) {
$isWd = strpos($name, 'wd_') === 0 || strpos($name, 'woodmart') !== false;
$isWpWd = strpos($name, 'wp-widget-woodmart') === 0;
if (!$isWd && !$isWpWd) continue;
$kind = $isWpWd ? 'wp' : 'wd';
if ($group !== 'all' && $group !== $kind) continue;
$title = '';
if (is_object($w) && method_exists($w, 'get_title')) { try { $title = (string) $w->get_title(); } catch (\Throwable $e) {} }
$out[] = ['name' => $name, 'title' => $title, 'kind' => $kind];
}
usort($out, fn($a, $b) => strcmp($a['name'], $b['name']));
return ['count' => count($out), 'widgets' => $out];
}
private static function queryCpt(string $cpt, array $args): array {
$q = get_posts([
'post_type' => $cpt,
'post_status' => isset($args['status']) ? (string) $args['status'] : ['publish', 'draft', 'pending', 'private'],
'numberposts' => (int) ($args['per_page'] ?? 50),
'orderby' => 'date',
'order' => 'DESC',
]);
return is_array($q) ? $q : [];
}
public static function listLayouts(array $args): array {
if (!post_type_exists('woodmart_layout')) {
return ['supported' => false, 'note' => 'woodmart_layout CPT not registered on this site.', 'count' => 0, 'layouts' => []];
}
$posts = self::queryCpt('woodmart_layout', $args);
$out = [];
foreach ($posts as $p) {
$meta = get_post_meta($p->ID);
$keys = array_values(array_filter(array_keys($meta), fn($k) => $k !== '' && strpos($k, '_edit') !== 0));
$out[] = ['id' => $p->ID, 'title' => $p->post_title, 'status' => $p->post_status, 'meta_keys' => $keys];
}
return ['supported' => true, 'count' => count($out), 'layouts' => $out];
}
public static function listBlocks(array $args): array {
if (!post_type_exists('cms_block')) {
return ['supported' => false, 'note' => 'cms_block CPT not registered on this site.', 'count' => 0, 'blocks' => []];
}
$posts = self::queryCpt('cms_block', $args);
$out = [];
foreach ($posts as $p) {
$out[] = [
'id' => $p->ID, 'title' => $p->post_title, 'status' => $p->post_status,
'shortcode' => '[woodmart_html_block id="' . $p->ID . '"]',
];
}
return ['supported' => true, 'count' => count($out), 'blocks' => $out];
}
public static function getBlock(array $args): array {
$id = (int) ($args['id'] ?? 0);
$p = get_post($id);
if (!$p) throw new \RuntimeException('Post not found: ' . $id);
$isElementor = get_post_meta($id, '_elementor_edit_mode', true) === 'builder';
$content = (string) $p->post_content;
$shortcode = $p->post_type === 'cms_block' ? '[woodmart_html_block id="' . $id . '"]' : null;
return [
'id' => $id,
'post_type' => $p->post_type,
'title' => $p->post_title,
'status' => $p->post_status,
'elementor_built' => $isElementor,
'content_length' => strlen($content),
'content_preview' => mb_substr(wp_strip_all_tags($content), 0, 300),
'shortcode' => $shortcode,
];
}
public static function createBlock(array $args): array {
if (!post_type_exists('cms_block')) {
throw new \RuntimeException('cms_block CPT not registered; Woodmart HTML Blocks unavailable on this site.');
}
$title = trim((string) ($args['title'] ?? ''));
if ($title === '') throw new \RuntimeException('title required.');
$status = ($args['status'] ?? 'publish') === 'draft' ? 'draft' : 'publish';
$id = wp_insert_post([
'post_type' => 'cms_block',
'post_title' => $title,
'post_content' => (string) ($args['content'] ?? ''),
'post_status' => $status,
], true);
if (is_wp_error($id)) throw new \RuntimeException('Create failed: ' . $id->get_error_message());
return ['id' => $id, 'title' => $title, 'status' => $status, 'shortcode' => '[woodmart_html_block id="' . $id . '"]'];
}
}