1907f4b189
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q8t9GEyyLZbUQu26na1JQg
147 lines
7.5 KiB
PHP
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 . '"]'];
|
|
}
|
|
}
|