* @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; } /** * Tool_Manager class. */ class Tool_Manager extends Manager { /** * Registered tools * @var array */ private $tools = array(); /** * Mapping of tool IDs to tool classes * @var array */ private $tool_mapping = array( // Core tools 'list_all_tools' => 'List_All_Tools_Tool', 'import_tools' => 'Import_Tools_Tool', 'unimport_tools' => 'Unimport_Tools_Tool', 'terminate' => 'Terminate_Tool', 'continue' => 'Continue_Tool', // Content tools 'search_content' => 'Search_Content_Tool', 'create_post' => 'Create_Post_Tool', 'create_page' => 'Create_Page_Tool', 'update_page' => 'Update_Page_Tool', 'delete_page' => 'Delete_Page_Tool', 'update_post' => 'Update_Post_Tool', 'delete_post' => 'Delete_Post_Tool', 'get_post_details' => 'Get_Post_Details_Tool', 'get_page_details' => 'Get_Page_Details_Tool', 'list_posts' => 'List_Posts_Tool', 'list_pages' => 'List_Pages_Tool', // Post Meta tools 'list_post_meta' => 'List_Post_Meta_Tool', 'get_post_meta' => 'Get_Post_Meta_Tool', 'create_post_meta' => 'Create_Post_Meta_Tool', 'update_post_meta' => 'Update_Post_Meta_Tool', 'delete_post_meta' => 'Delete_Post_Meta_Tool', // Comment tools 'list_comments' => 'List_Comments_Tool', 'get_comment_details' => 'Get_Comment_Details_Tool', 'create_comment' => 'Create_Comment_Tool', 'update_comment' => 'Update_Comment_Tool', 'delete_comment' => 'Delete_Comment_Tool', // Category tools 'list_categories' => 'List_Categories_Tool', 'get_category_details' => 'Get_Category_Details_Tool', 'create_category' => 'Create_Category_Tool', 'update_category' => 'Update_Category_Tool', 'delete_category' => 'Delete_Category_Tool', // Tag tools 'list_tags' => 'List_Tags_Tool', 'get_tag_details' => 'Get_Tag_Details_Tool', 'create_tag' => 'Create_Tag_Tool', 'update_tag' => 'Update_Tag_Tool', 'delete_tag' => 'Delete_Tag_Tool', // Media tools 'list_media' => 'List_Media_Tool', 'get_media_details' => 'Get_Media_Details_Tool', 'create_media' => 'Create_Media_Tool', 'update_media' => 'Update_Media_Tool', 'delete_media' => 'Delete_Media_Tool', // User tools 'list_users' => 'List_Users_Tool', 'get_user_details' => 'Get_User_Details_Tool', 'get_current_user' => 'Get_Current_User_Tool', 'create_user' => 'Create_User_Tool', 'update_user' => 'Update_User_Tool', 'delete_user' => 'Delete_User_Tool', 'send_password_reset' => 'Send_Password_Reset_Tool', // Plugin tools 'list_installed_plugins' => 'List_Installed_Plugins_Tool', 'list_active_plugins' => 'List_Active_Plugins_Tool', 'get_plugin_details' => 'Get_Plugin_Details_Tool', 'search_plugins' => 'Search_Plugins_Tool', 'install_plugin' => 'Install_Plugin_Tool', 'uninstall_plugin' => 'Uninstall_Plugin_Tool', 'update_plugins' => 'Update_Plugins_Tool', 'activate_plugin' => 'Activate_Plugin_Tool', 'deactivate_plugin' => 'Deactivate_Plugin_Tool', // Plugin file tools 'list_plugin_files' => 'List_Plugin_Files_Tool', 'read_plugin_file' => 'Read_Plugin_File_Tool', // Theme tools 'list_installed_themes' => 'List_Installed_Themes_Tool', 'get_active_theme' => 'Get_Active_Theme_Tool', 'get_theme_details' => 'Get_Theme_Details_Tool', 'search_themes' => 'Search_Themes_Tool', 'install_theme' => 'Install_Theme_Tool', 'uninstall_theme' => 'Uninstall_Theme_Tool', 'update_themes' => 'Update_Themes_Tool', 'activate_theme' => 'Activate_Theme_Tool', // Theme file tools 'list_theme_files' => 'List_Theme_Files_Tool', 'read_theme_file' => 'Read_Theme_File_Tool', // Debug log tools 'get_debug_log_info' => 'Get_Debug_Log_Info_Tool', 'read_debug_log_file' => 'Read_Debug_Log_File_Tool', // Options tools 'list_options' => 'List_Options_Tool', 'get_option_value' => 'Get_Option_Value_Tool', 'update_option' => 'Update_Option_Tool', 'delete_option' => 'Delete_Option_Tool', // Site tools 'get_site_info' => 'Get_Site_Info_Tool', 'get_site_health' => 'Get_Site_Health_Tool', 'list_available_updates' => 'List_Available_Updates_Tool', 'update_core' => 'Update_Core_Tool', // Web tools 'send_email' => 'Send_Email_Tool', 'fetch_url' => 'Fetch_Url_Tool', 'download_file' => 'Download_File_Tool', // Config tools 'configure_llm_provider' => 'Configure_LLM_Provider_Tool', 'get_chat_model' => 'Get_Chat_Model_Tool', 'get_embeddings_model' => 'Get_Embeddings_Model_Tool', 'list_chat_models' => 'List_Chat_Models_Tool', 'list_embeddings_models' => 'List_Embeddings_Models_Tool', 'change_chat_model' => 'Change_Chat_Model_Tool', 'change_embeddings_model' => 'Change_Embeddings_Model_Tool', 'sync_embeddings' => 'Sync_Embeddings_Tool', 'change_chat_position' => 'Change_Chat_Position_Tool', // Role and capability tools 'list_roles' => 'List_Roles_Tool', 'get_role_details' => 'Get_Role_Details_Tool', 'list_capabilities' => 'List_Capabilities_Tool', 'check_user_capability' => 'Check_User_Capability_Tool', 'add_role' => 'Add_Role_Tool', 'remove_role' => 'Remove_Role_Tool', 'clone_role' => 'Clone_Role_Tool', 'add_capability_to_role' => 'Add_Capability_To_Role_Tool', 'remove_capability_from_role' => 'Remove_Capability_From_Role_Tool', 'grant_user_capability' => 'Grant_User_Capability_Tool', 'revoke_user_capability' => 'Revoke_User_Capability_Tool', // System tools 'calculate_php' => 'Calculate_PHP_Tool', 'read_file' => 'Read_File_Tool', 'write_file' => 'Write_File_Tool', 'list_files' => 'List_Files_Tool', 'delete_file' => 'Delete_File_Tool', // Menu tools 'list_menus' => 'List_Menus_Tool', 'create_menu' => 'Create_Menu_Tool', 'delete_menu' => 'Delete_Menu_Tool', 'get_menu_details' => 'Get_Menu_Details_Tool', 'add_menu_item' => 'Add_Menu_Item_Tool', 'update_menu_item' => 'Update_Menu_Item_Tool', 'delete_menu_item' => 'Delete_Menu_Item_Tool', 'list_menu_locations' => 'List_Menu_Locations_Tool', 'assign_menu_to_location' => 'Assign_Menu_To_Location_Tool', 'unassign_menu_from_location' => 'Unassign_Menu_From_Location_Tool', // Cron tools 'list_cron_events' => 'WP_Cron_Event_List_Tool', 'get_cron_event_details' => 'WP_Cron_Event_Details_Tool', 'list_cron_schedules' => 'WP_Cron_Schedule_List_Tool', 'schedule_cron_event' => 'WP_Cron_Event_Schedule_Tool', 'unschedule_cron_event' => 'WP_Cron_Event_Unschedule_Tool', 'run_cron' => 'WP_Cron_Run_Tool', 'cron_event_exists' => 'WP_Cron_Event_Exists_Tool', // Action Scheduler tools 'list_scheduled_actions' => 'Action_Scheduler_List_Tool', 'get_scheduled_action_details' => 'Action_Scheduler_Details_Tool', 'schedule_action' => 'Action_Scheduler_Schedule_Tool', 'cancel_scheduled_action' => 'Action_Scheduler_Cancel_Tool', 'run_scheduled_action' => 'Action_Scheduler_Run_Tool', 'search_scheduled_actions' => 'Action_Scheduler_Search_Tool', // Shortcode tools 'list_shortcodes' => 'List_Shortcodes_Tool', 'get_shortcode_details' => 'Get_Shortcode_Details_Tool', 'render_shortcode' => 'Render_Shortcode_Tool', // Post type tools 'list_post_types' => 'List_Post_Types_Tool', 'get_post_type_details' => 'Get_Post_Type_Details_Tool', // Custom post type tools 'list_custom_posts' => 'List_Custom_Posts_Tool', 'get_custom_post' => 'Get_Custom_Post_Tool', 'create_custom_post' => 'Create_Custom_Post_Tool', 'update_custom_post' => 'Update_Custom_Post_Tool', 'delete_custom_post' => 'Delete_Custom_Post_Tool', // Taxonomy tools 'list_taxonomies' => 'List_Taxonomies_Tool', 'get_taxonomy_details' => 'Get_Taxonomy_Details_Tool', 'list_terms' => 'List_Terms_Tool', 'get_term_details' => 'Get_Term_Details_Tool', 'create_term' => 'Create_Term_Tool', 'update_term' => 'Update_Term_Tool', 'delete_term' => 'Delete_Term_Tool', 'term_exists' => 'Term_Exists_Tool', ); /** * Cached always-imported tools * @var array|null */ private $always_imported_tools_cache = null; /** * Constructor - initializes the manager * @since 1.0.0 */ protected function __construct() { // Register built-in tools $this->register_built_in_tools(); // Call parent constructor with option suffix parent::__construct( 'tool_settings' ); } /** * Get default configuration * * Returns tool settings with default values based on each tool's * default enabled status. * * @return array Default configuration * @since 1.0.0 */ protected function get_default_config() { // Initialize with empty tools configuration $tools_config = array(); // Get default enabled status from each tool instance foreach ( $this->tools as $tool_id => $tool ) { $tools_config[ $tool_id ] = array( 'enabled' => $tool->get_default_enabled_status(), ); } // Return configuration with tools array return array( 'tools' => $tools_config, ); } /** * Register built-in tools provided by the plugin */ private function register_built_in_tools() { // Register each tool if its class exists foreach ( $this->tool_mapping as $class_name ) { $full_class_name = '\\Agenistrator\\' . $class_name; if ( class_exists( $full_class_name ) ) { $tool = new $full_class_name(); $this->register_tool( $tool ); } } } /** * Register a tool * * @param Tool $tool The tool to register * @return bool True if registration succeeded, false otherwise * @since 1.0.0 */ public function register_tool( $tool ) { if ( ! ( $tool instanceof Tool ) ) { return false; } $id = $tool->get_id(); if ( empty( $id ) ) { return false; } $this->always_imported_tools_cache = null; $this->tools[ $id ] = $tool; return true; } /** * Unregister a tool * * @param string $name The name of the tool to unregister * @return bool True if unregistration succeeded, false otherwise * @since 1.0.0 */ public function unregister_tool( $name ) { if ( isset( $this->tools[ $name ] ) ) { $this->always_imported_tools_cache = null; unset( $this->tools[ $name ] ); return true; } return false; } /** * Get all registered tools * * @param bool $only_enabled Whether to return only enabled tools * @return array Array of registered tools * @since 1.0.0 */ public function get_tools( $only_enabled = false ) { if ( ! $only_enabled ) { return $this->tools; } $enabled_tools = array(); foreach ( $this->tools as $name => $tool ) { if ( $this->is_tool_enabled( $name ) ) { $enabled_tools[ $name ] = $tool; } } return $enabled_tools; } /** * Get a specific tool by name * * @param string $name The name of the tool to get * @return Tool|null The tool, or null if not found * @since 1.0.0 */ public function get_tool( $name ) { return $this->tools[ $name ] ?? null; } /** * Get tools that are always imported (core tools) * * @return array Array of tools that are always imported * @since 1.0.0 */ public function get_always_imported_tools() { if ( null !== $this->always_imported_tools_cache ) { return $this->always_imported_tools_cache; } $result = array(); foreach ( $this->tools as $id => $tool ) { if ( $tool->is_always_imported() ) { $result[ $id ] = $tool; } } $this->always_imported_tools_cache = $result; return $result; } /** * Get tool settings * * @return array The tool settings * @since 1.0.0 */ public function get_tool_settings() { // Ensure all registered tools have settings foreach ( $this->tools as $tool_id => $tool ) { if ( ! $this->get_config( array( 'tools', $tool_id ) ) ) { $this->set_config_and_save( array( 'tools', $tool_id ), array( 'enabled' => $tool->get_default_enabled_status(), ) ); } } return $this->get_config( array( 'tools' ), array() ); } /** * Check if a tool is enabled * * Always-enabled tools return true regardless of settings. * * @param string $tool_id The ID of the tool to check * @return bool True if the tool is enabled, false otherwise * @since 1.0.0 */ public function is_tool_enabled( $tool_id ) { $tool = $this->get_tool( $tool_id ); if ( ! $tool ) { return false; } // Always-enabled tools cannot be disabled if ( $tool->is_always_enabled() ) { return true; } $enabled = $this->get_config( array( 'tools', $tool_id, 'enabled' ) ); if ( null !== $enabled ) { return $enabled; } return $tool->get_default_enabled_status(); } /** * Set a tool's enabled status * * Cannot disable always-enabled tools. * * @param string $tool_id The ID of the tool to update * @param bool $enabled True to enable, false to disable * @return bool True if the update succeeded, false otherwise * @throws \Exception If trying to disable an always-enabled tool * @since 1.0.0 */ public function set_tool_enabled( $tool_id, $enabled ) { $tool = $this->get_tool( $tool_id ); if ( ! $tool ) { // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception messages are not HTML output throw new \Exception( __( 'Tool not found.', 'agenistrator' ) ); } // Prevent disabling always-enabled tools if ( $tool->is_always_enabled() && ! $enabled ) { // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception messages are not HTML output throw new \Exception( __( 'This tool cannot be disabled.', 'agenistrator' ) ); } // Update enabled status and save return $this->set_config_and_save( array( 'tools', $tool_id, 'enabled' ), $enabled ); } }