* @author Maximum Software Inc * @license GPL-3.0-only * @link https://agenistrator.com/ * * SPDX-FileCopyrightText: 2025-2026 Alex Ruban * SPDX-FileCopyrightText: 2025-2026 Maximum Software Inc * SPDX-License-Identifier: GPL-3.0-only */ namespace Agenistrator; // Direct access prevention if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Render_Shortcode_Tool class. */ class Render_Shortcode_Tool extends Tool { /** * Get the tool ID. * * @return string The tool ID. * @since 1.0.0 */ public function get_id() { return 'render_shortcode'; } /** * Get the tool name. * * @return string The tool name. * @since 1.0.0 */ public function get_name() { return __( 'Render Shortcode', 'agenistrator' ); } /** * Get the description of the tool. * * @return string The description of the tool. * @since 1.0.0 */ public function get_description() { return 'Executes a WordPress shortcode and returns the rendered HTML output. Useful for previewing shortcode output.'; } /** * Get the parameters for this tool. * * @return array Parameters schema in JSON Schema format. * @since 1.0.0 */ public function get_parameters() { return array( 'type' => 'object', 'properties' => array( 'shortcode' => array( 'type' => 'string', 'description' => 'The full shortcode string to render, including brackets (e.g., "[gallery ids=1,2,3]" or "[contact-form id=1]"). Use `get_shortcode_details` tool first to view the shortcode source code and discover accepted parameters.', ), ), 'required' => array( 'shortcode' ), ); } /** * Check if the current user has permission to execute this tool. * * @return bool Whether the user has permission. * @since 1.0.0 */ public function current_user_can_execute() { return current_user_can( 'manage_options' ); } /** * Check if this tool is read-only. * * @return bool True - this tool only renders output, no persistent changes. * @since 1.0.0 */ public function is_read_only() { return true; } /** * Execute the tool with the given arguments. * * @param array $args The arguments for the tool. * @return array The result of executing the tool. * @since 1.0.0 */ protected function execute( $args ) { $shortcode = $args['shortcode']; // Extract the shortcode tag for validation $tag = $this->extract_shortcode_tag( $shortcode ); if ( ! $tag ) { return $this->error_response( 'Invalid shortcode format. Shortcode must be wrapped in brackets (e.g., "[gallery]").' ); } // Check if the shortcode exists if ( ! shortcode_exists( $tag ) ) { return $this->error_response( String_Utils::replace_tags( 'Shortcode [{tag}] is not registered.', array( 'tag' => $tag ) ) ); } // Render the shortcode $output = do_shortcode( $shortcode ); // Check if output is the same as input (shortcode wasn't processed) if ( $shortcode === $output ) { return $this->error_response( String_Utils::replace_tags( 'Shortcode [{tag}] did not produce any output.', array( 'tag' => $tag ) ) ); } $output_length = strlen( $output ); return $this->success_response( 'Shortcode rendered successfully', array( 'tag' => $tag, 'input' => $shortcode, 'output' => $output, 'output_length' => $output_length, ) ); } /** * Extract the shortcode tag from a shortcode string. * * @param string $shortcode The full shortcode string. * @return string|null The shortcode tag, or null if invalid. */ private function extract_shortcode_tag( $shortcode ) { // Match shortcode pattern: [tag ...] or [tag] if ( preg_match( '/^\[([a-zA-Z0-9_-]+)/', $shortcode, $matches ) ) { return $matches[1]; } return null; } }