feat(batch18): Elementor power — kits, library/theme-builder, conditions, dynamic tags, Pro form submissions

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8t9GEyyLZbUQu26na1JQg
This commit is contained in:
2026-10-16 02:11:50 +00:00
parent 9e223005f5
commit 827ab31e78
+119
View File
@@ -0,0 +1,119 @@
<?php
/**
* Batch 18 — Elementor power (Pro-aware, net-new).
*
* Beyond the core Elementor tools: kits, the full template library grouped by
* type (theme-builder headers/footers/singles/archives, popups, saved
* templates), per-template display conditions, dynamic tags, and Elementor Pro
* form submissions. Guarded by ELEMENTOR_VERSION; Pro-only pieces degrade
* gracefully. GPL-2.0-or-later. See NOTICE.md.
*/
namespace AskTamMCP\Extensions;
defined('ABSPATH') || exit;
class Batch18 {
public static function register($registry): void {
if (!defined('ELEMENTOR_VERSION')) 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\\Batch18::' . $method, 'inputSchema' => $schema];
};
$registry->register($def('elementor_list_kits', 'List Elementor kits (global style sets) and which one is active.',
[], [], 'read', 'listKits'));
$registry->register($def('elementor_list_library', 'List Elementor library templates grouped by type (page, section, container, header, footer, single, archive, popup, loop-item, etc.). Covers theme-builder + popups + saved templates.',
['type' => ['type' => 'string'], 'per_page' => ['type' => 'integer', 'default' => 200]], [], 'read', 'listLibrary'));
$registry->register($def('elementor_get_conditions', 'Get the display conditions of an Elementor theme-builder / popup template by id (Elementor Pro).',
['template_id' => ['type' => 'integer']], ['template_id'], 'read', 'getConditions'));
$registry->register($def('elementor_get_dynamic_tags', 'List registered Elementor dynamic tags grouped by group (most are Elementor Pro).',
[], [], 'read', 'getDynamicTags'));
$registry->register($def('elementor_get_form_submissions', 'List Elementor Pro Forms submissions (newest first): id, form name, page, created date. Requires Elementor Pro Forms submissions storage.',
['limit' => ['type' => 'integer', 'default' => 50], 'form_name' => ['type' => 'string']], [], 'read', 'formSubmissions'));
}
public static function listKits(array $args): array {
$active = (int) get_option('elementor_active_kit');
$kits = get_posts(['post_type' => 'elementor_library', 'post_status' => 'publish', 'numberposts' => 50,
'meta_key' => '_elementor_template_type', 'meta_value' => 'kit', 'fields' => 'ids']);
$out = [];
foreach ((array) $kits as $id) $out[] = ['id' => (int) $id, 'title' => get_the_title($id), 'active' => ((int) $id === $active)];
if (!$out && $active) $out[] = ['id' => $active, 'title' => get_the_title($active), 'active' => true];
return ['active_kit' => $active, 'count' => count($out), 'kits' => $out];
}
public static function listLibrary(array $args): array {
$posts = get_posts(['post_type' => 'elementor_library', 'post_status' => ['publish', 'draft'],
'numberposts' => (int) ($args['per_page'] ?? 200), 'fields' => 'ids']);
$groups = [];
$filter = isset($args['type']) ? (string) $args['type'] : '';
foreach ((array) $posts as $id) {
$type = get_post_meta($id, '_elementor_template_type', true) ?: 'unknown';
if ($type === 'kit') continue;
if ($filter !== '' && $type !== $filter) continue;
$groups[$type][] = ['id' => (int) $id, 'title' => get_the_title($id), 'status' => get_post_status($id)];
}
$counts = array_map('count', $groups);
return ['types' => array_keys($groups), 'counts' => $counts, 'templates' => $groups];
}
public static function getConditions(array $args): array {
$id = (int) ($args['template_id'] ?? 0);
if (!get_post($id)) throw new \RuntimeException('Template not found: ' . $id);
$cond = get_post_meta($id, '_elementor_conditions', true);
$type = get_post_meta($id, '_elementor_template_type', true);
return [
'template_id' => $id,
'template_type' => $type ?: null,
'conditions' => is_array($cond) ? $cond : [],
'has_conditions' => !empty($cond),
'note' => (!empty($cond) || defined('ELEMENTOR_PRO_VERSION')) ? null : 'Display conditions are an Elementor Pro feature.',
];
}
public static function getDynamicTags(array $args): array {
if (!class_exists('\Elementor\Plugin')) throw new \RuntimeException('Elementor not available.');
$mgr = \Elementor\Plugin::instance()->dynamic_tags;
if (!$mgr) return ['supported' => false, 'note' => 'Dynamic tags unavailable.', 'tags' => []];
$out = [];
try {
$cfg = method_exists($mgr, 'get_tags_config') ? $mgr->get_tags_config() : [];
foreach ((array) $cfg as $name => $data) {
$out[] = ['name' => $name, 'title' => $data['title'] ?? '', 'group' => is_array($data['group'] ?? null) ? implode(',', $data['group']) : ($data['group'] ?? '')];
}
} catch (\Throwable $e) {
return ['supported' => false, 'note' => 'Could not read dynamic tags: ' . $e->getMessage(), 'tags' => []];
}
usort($out, fn($a, $b) => strcmp($a['name'], $b['name']));
return ['supported' => true, 'count' => count($out), 'pro' => defined('ELEMENTOR_PRO_VERSION'), 'tags' => $out];
}
public static function formSubmissions(array $args): array {
global $wpdb;
$t = $wpdb->prefix . 'e_submissions';
if (!$wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $t))) {
return ['supported' => false, 'note' => 'Elementor Pro Forms submissions table not found (needs Pro with DB storage enabled).', 'submissions' => []];
}
$limit = max(1, (int) ($args['limit'] ?? 50));
$where = '';
if (!empty($args['form_name'])) {
$where = $wpdb->prepare('WHERE form_name = %s', (string) $args['form_name']);
}
$rows = $wpdb->get_results("SELECT id, form_name, post_id, created_at, status FROM {$t} {$where} ORDER BY id DESC LIMIT {$limit}", ARRAY_A);
$out = [];
foreach ((array) $rows as $r) {
$out[] = ['id' => (int) $r['id'], 'form_name' => $r['form_name'], 'post_id' => (int) $r['post_id'],
'page' => get_the_title((int) $r['post_id']), 'created_at' => $r['created_at'], 'status' => $r['status']];
}
return ['supported' => true, 'count' => count($out), 'submissions' => $out];
}
}