diff --git a/includes/blocks/class-convertkit-block.php b/includes/blocks/class-convertkit-block.php index 1426f5e42..c308a1bd0 100644 --- a/includes/blocks/class-convertkit-block.php +++ b/includes/blocks/class-convertkit-block.php @@ -68,10 +68,10 @@ public function register_abilities( $abilities ) { return array_merge( $abilities, array( - new ConvertKit_MCP_Ability_Block_List( $this ), - new ConvertKit_MCP_Ability_Block_Insert( $this ), - new ConvertKit_MCP_Ability_Block_Update( $this ), - new ConvertKit_MCP_Ability_Block_Delete( $this ), + new ConvertKit_MCP_Ability_Content_List( $this ), + new ConvertKit_MCP_Ability_Content_Insert( $this ), + new ConvertKit_MCP_Ability_Content_Update( $this ), + new ConvertKit_MCP_Ability_Content_Delete( $this ), ) ); diff --git a/includes/blocks/helpers/class-convertkit-content-post-helper.php b/includes/blocks/helpers/class-convertkit-content-post-helper.php new file mode 100644 index 000000000..cc3b867ac --- /dev/null +++ b/includes/blocks/helpers/class-convertkit-content-post-helper.php @@ -0,0 +1,279 @@ +post_content ) ? 'block' : 'shortcode'; + + } + + /** + * Returns the human-readable name of the page builder used to build the + * given Post, or false if no supported page builder is detected. + * + * @since 3.4.0 + * + * @param int $post_id Post ID. + * @return string|false + */ + private static function detect_page_builder( $post_id ) { + + // Elementor stores its content in the _elementor_data post meta key, + // and flags edited posts via _elementor_edit_mode. + if ( 'builder' === get_post_meta( $post_id, '_elementor_edit_mode', true ) ) { + return 'Elementor'; + } + + /** + * Filters the detected page builder for a Post. + * + * Return a non-empty string (the page builder's name) to mark the Post + * as built with an unsupported page builder, causing the Content MCP + * abilities to return an error rather than writing to post_content. + * + * @since 3.4.0 + * + * @param string|false $page_builder Detected page builder name, or false. + * @param int $post_id Post ID. + */ + return apply_filters( 'convertkit_content_post_helper_detect_page_builder', false, $post_id ); + + } + + /** + * Returns a WP_Error for an unrecognised content mechanism. Acts as a + * defensive fallback; detect_mechanism() should only ever return a known + * mechanism or a WP_Error. + * + * @since 3.4.0 + * + * @param string $mechanism The unrecognised mechanism. + * @return WP_Error + */ + private static function unsupported_mechanism_error( $mechanism ) { + + return new WP_Error( + 'convertkit_content_post_helper_unsupported_mechanism', + sprintf( + /* translators: %s: mechanism identifier */ + __( 'Unsupported content mechanism: %s.', 'convertkit' ), + $mechanism + ) + ); + + } + +} diff --git a/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-delete.php b/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-delete.php similarity index 70% rename from includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-delete.php rename to includes/mcp/abilities/content/class-convertkit-mcp-ability-content-delete.php index 67531683b..fc21b383a 100644 --- a/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-delete.php +++ b/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-delete.php @@ -1,22 +1,22 @@ -delete` (e.g. `kit/form-delete`). + * Registered by an element opting in via the `convertkit_abilities` filter and + * produces an ability named `kit/-delete` (e.g. `kit/form-delete`). * * @package ConvertKit * @author ConvertKit */ -class ConvertKit_MCP_Ability_Block_Delete extends ConvertKit_MCP_Ability_Block { +class ConvertKit_MCP_Ability_Content_Delete extends ConvertKit_MCP_Ability_Content { /** * Sets whether the ability is destructive. @@ -51,7 +51,7 @@ public function get_label() { return sprintf( /* translators: %s: block title */ - __( 'Delete an existing %s block from a post', 'convertkit' ), + __( 'Delete an existing %s element from a post', 'convertkit' ), $this->block->get_title() ); @@ -68,7 +68,7 @@ public function get_description() { return sprintf( /* translators: 1: block full name e.g. convertkit/form, 2: block title */ - __( 'Removes a single occurrence of the %1$s (%2$s) block from the given post.', 'convertkit' ), + __( 'Removes a single occurrence of the %1$s (%2$s) element from the given post.', 'convertkit' ), 'convertkit/' . $this->block->get_name(), $this->block->get_title() ); @@ -91,12 +91,12 @@ public function get_input_schema() { 'post_id' => array( 'type' => 'integer', 'minimum' => 1, - 'description' => __( 'ID of the post containing the block.', 'convertkit' ), + 'description' => __( 'ID of the post containing the element.', 'convertkit' ), ), 'occurrence_index' => array( 'type' => 'integer', 'minimum' => 0, - 'description' => __( 'The zero-based occurrence index of the block to delete.', 'convertkit' ), + 'description' => __( 'The zero-based occurrence index of the element to delete.', 'convertkit' ), ), ), ); @@ -127,8 +127,8 @@ public function execute_callback( $input ) { // Get occurrence index. $occurrence_index = isset( $input['occurrence_index'] ) ? (int) $input['occurrence_index'] : 0; - // Delete block from post. - return ConvertKit_Block_Post_Helper::delete( $post_id, 'convertkit/' . $this->block->get_name(), $occurrence_index ); + // Delete the element from the post. + return ConvertKit_Content_Post_Helper::delete( $post_id, $this->block->get_name(), $occurrence_index ); } diff --git a/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-insert.php b/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-insert.php similarity index 67% rename from includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-insert.php rename to includes/mcp/abilities/content/class-convertkit-mcp-ability-content-insert.php index c76b30edd..5c14151f7 100644 --- a/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-insert.php +++ b/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-insert.php @@ -1,22 +1,22 @@ -insert` (e.g. `kit/form-insert`). + * Registered by an element opting in via the `convertkit_abilities` filter and + * produces an ability named `kit/-insert` (e.g. `kit/form-insert`). * * @package ConvertKit * @author ConvertKit */ -class ConvertKit_MCP_Ability_Block_Insert extends ConvertKit_MCP_Ability_Block { +class ConvertKit_MCP_Ability_Content_Insert extends ConvertKit_MCP_Ability_Content { /** * Returns the verb this ability represents. @@ -42,7 +42,7 @@ public function get_label() { return sprintf( /* translators: %s: block title */ - __( 'Insert a %s block into a post', 'convertkit' ), + __( 'Insert a %s element into a post', 'convertkit' ), $this->block->get_title() ); @@ -59,7 +59,7 @@ public function get_description() { return sprintf( /* translators: 1: block full name e.g. convertkit/form, 2: block title */ - __( 'Inserts a new %1$s (%2$s) block into the given post\'s content. The block can be appended (default), prepended, or positioned relative to an existing block using a zero-based index.', 'convertkit' ), + __( 'Inserts a new %1$s (%2$s) element into the given post\'s content. The element can be appended (default), prepended, or positioned relative to an existing element using a zero-based index.', 'convertkit' ), 'convertkit/' . $this->block->get_name(), $this->block->get_title() ); @@ -82,22 +82,22 @@ public function get_input_schema() { 'post_id' => array( 'type' => 'integer', 'minimum' => 1, - 'description' => __( 'Page / Post / Custom Post Type ID to insert the block into.', 'convertkit' ), + 'description' => __( 'Page / Post / Custom Post Type ID to insert the element into.', 'convertkit' ), ), 'position' => array( 'type' => 'string', 'enum' => array( 'append', 'prepend', 'index' ), 'default' => 'append', - 'description' => __( 'Where to insert the new block. "index" requires the "index" property.', 'convertkit' ), + 'description' => __( 'Where to insert the new element. "index" requires the "index" property.', 'convertkit' ), ), 'index' => array( 'type' => 'integer', 'minimum' => 0, - 'description' => __( 'When position is "index", the zero-based top-level block index at which to insert the new block.', 'convertkit' ), + 'description' => __( 'When position is "index", the zero-based top-level element index at which to insert the new element.', 'convertkit' ), ), 'attrs' => array( 'type' => 'object', - 'description' => __( 'Block attributes.', 'convertkit' ), + 'description' => __( 'Element attributes.', 'convertkit' ), 'properties' => $this->get_input_schema_properties(), ), ), @@ -131,8 +131,8 @@ public function execute_callback( $input ) { $position = isset( $input['position'] ) ? (string) $input['position'] : 'append'; $index = isset( $input['index'] ) ? (int) $input['index'] : 0; - // Insert block into post. - return ConvertKit_Block_Post_Helper::insert( $post_id, 'convertkit/' . $this->block->get_name(), $attrs, $position, $index ); + // Insert the element into the post. + return ConvertKit_Content_Post_Helper::insert( $post_id, $this->block->get_name(), $attrs, $position, $index ); } diff --git a/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-list.php b/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-list.php similarity index 74% rename from includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-list.php rename to includes/mcp/abilities/content/class-convertkit-mcp-ability-content-list.php index 2d23b5ac8..d68e6d784 100644 --- a/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-list.php +++ b/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-list.php @@ -1,22 +1,22 @@ -list` (e.g. `kit/form-list`). + * Registered by an element opting in via the `convertkit_abilities` filter and + * produces an ability named `kit/-list` (e.g. `kit/form-list`). * * @package ConvertKit * @author ConvertKit */ -class ConvertKit_MCP_Ability_Block_List extends ConvertKit_MCP_Ability_Block { +class ConvertKit_MCP_Ability_Content_List extends ConvertKit_MCP_Ability_Content { /** * Sets whether the ability is readonly. @@ -60,7 +60,7 @@ public function get_label() { return sprintf( /* translators: %s: block title */ - __( 'List %s blocks in a post', 'convertkit' ), + __( 'List %s elements in a post', 'convertkit' ), $this->block->get_title() ); @@ -77,7 +77,7 @@ public function get_description() { return sprintf( /* translators: 1: block full name e.g. convertkit/form, 2: block title */ - __( 'Lists every occurrence of the %1$s (%2$s) block in the given post, including each occurrence\'s zero-based index and current attribute values.', 'convertkit' ), + __( 'Lists every occurrence of the %1$s (%2$s) element in the given post, including each occurrence\'s zero-based index and current attribute values.', 'convertkit' ), 'convertkit/' . $this->block->get_name(), $this->block->get_title() ); @@ -136,11 +136,11 @@ public function get_output_schema() { 'index' => array( 'type' => 'integer', 'minimum' => 0, - 'description' => __( 'Zero-based occurrence index among this block\'s appearances in the post.', 'convertkit' ), + 'description' => __( 'Zero-based occurrence index among this element\'s appearances in the post.', 'convertkit' ), ), 'attrs' => array( 'type' => 'object', - 'description' => __( 'Block attributes for this occurrence.', 'convertkit' ), + 'description' => __( 'Element attributes for this occurrence.', 'convertkit' ), ), ), ), @@ -171,12 +171,17 @@ public function execute_callback( $input ) { ); } - // Find blocks in post. - $occurrences = ConvertKit_Block_Post_Helper::find( $post_id, 'convertkit/' . $this->block->get_name() ); + // Find element occurrences in post. + $occurrences = ConvertKit_Content_Post_Helper::find( $post_id, $this->block->get_name() ); if ( is_wp_error( $occurrences ) ) { return $occurrences; } + // Normalise a "no occurrences" result (false) to an empty array. + if ( false === $occurrences ) { + $occurrences = array(); + } + // Return result. return array( 'post_id' => $post_id, diff --git a/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-update.php b/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-update.php similarity index 67% rename from includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-update.php rename to includes/mcp/abilities/content/class-convertkit-mcp-ability-content-update.php index 5f6cc3fc0..d7c73ca47 100644 --- a/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-update.php +++ b/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-update.php @@ -1,25 +1,22 @@ -update` (e.g. `kit/form-update`). - * - * By default the provided attributes are merged into the existing attributes. - * Set `replace_all` to true to replace all attributes with the supplied set. + * Registered by an element opting in via the `convertkit_abilities` filter and + * produces an ability named `kit/-update` (e.g. `kit/form-update`). * * @package ConvertKit * @author ConvertKit */ -class ConvertKit_MCP_Ability_Block_Update extends ConvertKit_MCP_Ability_Block { +class ConvertKit_MCP_Ability_Content_Update extends ConvertKit_MCP_Ability_Content { /** * Sets whether the ability is idempotent. @@ -54,7 +51,7 @@ public function get_label() { return sprintf( /* translators: %s: block title */ - __( 'Update an existing %s block in a post', 'convertkit' ), + __( 'Update an existing %s element in a post', 'convertkit' ), $this->block->get_title() ); @@ -71,7 +68,7 @@ public function get_description() { return sprintf( /* translators: 1: block full name e.g. convertkit/form, 2: block title */ - __( 'Updates the attributes of a single occurrence of the %1$s (%2$s) block in the given post. By default the provided attributes are merged into the existing attributes; set replace_all to true to replace them entirely.', 'convertkit' ), + __( 'Updates the attributes of a single occurrence of the %1$s (%2$s) element in the given post. By default the provided attributes are merged into the existing attributes.', 'convertkit' ), 'convertkit/' . $this->block->get_name(), $this->block->get_title() ); @@ -94,16 +91,16 @@ public function get_input_schema() { 'post_id' => array( 'type' => 'integer', 'minimum' => 1, - 'description' => __( 'Page / Post / Custom Post Type ID containing the existing block.', 'convertkit' ), + 'description' => __( 'Page / Post / Custom Post Type ID containing the existing element.', 'convertkit' ), ), 'occurrence_index' => array( 'type' => 'integer', 'minimum' => 0, - 'description' => __( 'The zero-based occurrence index of the block to update.', 'convertkit' ), + 'description' => __( 'The zero-based occurrence index of the element to update.', 'convertkit' ), ), 'attrs' => array( 'type' => 'object', - 'description' => __( 'Block attributes to update. Any attributes not provided will be left unchanged.', 'convertkit' ), + 'description' => __( 'Element attributes to update. Any attributes not provided will be left unchanged.', 'convertkit' ), 'properties' => $this->get_input_schema_properties(), ), ), @@ -132,12 +129,12 @@ public function execute_callback( $input ) { ); } - // Get attributes, position and index. + // Get attributes and occurrence index. $attrs = isset( $input['attrs'] ) && is_array( $input['attrs'] ) ? $input['attrs'] : array(); $occurrence_index = isset( $input['occurrence_index'] ) ? (int) $input['occurrence_index'] : 0; - // Update block into post. - return ConvertKit_Block_Post_Helper::update( $post_id, 'convertkit/' . $this->block->get_name(), $occurrence_index, $attrs ); + // Update the element in the post. + return ConvertKit_Content_Post_Helper::update( $post_id, $this->block->get_name(), $occurrence_index, $attrs ); } diff --git a/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block.php b/includes/mcp/abilities/content/class-convertkit-mcp-ability-content.php similarity index 87% rename from includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block.php rename to includes/mcp/abilities/content/class-convertkit-mcp-ability-content.php index f691e51f9..8abfcea81 100644 --- a/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block.php +++ b/includes/mcp/abilities/content/class-convertkit-mcp-ability-content.php @@ -1,22 +1,21 @@ block->get_name() . '-block-' . $this->get_verb(); + return 'kit/' . $this->block->get_name() . '-' . $this->get_verb(); } diff --git a/wp-convertkit.php b/wp-convertkit.php index 014ee0bcb..085628b2f 100644 --- a/wp-convertkit.php +++ b/wp-convertkit.php @@ -108,16 +108,17 @@ require_once CONVERTKIT_PLUGIN_PATH . '/includes/blocks/class-convertkit-block-form-builder-field-custom.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/blocks/class-convertkit-block-product.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/blocks/helpers/class-convertkit-block-post-helper.php'; +require_once CONVERTKIT_PLUGIN_PATH . '/includes/blocks/helpers/class-convertkit-content-post-helper.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/block-formatters/class-convertkit-block-formatter.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/block-formatters/class-convertkit-block-formatter-form-link.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/block-formatters/class-convertkit-block-formatter-product-link.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/class-convertkit-mcp-ability.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/class-convertkit-mcp.php'; -require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block.php'; -require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-list.php'; -require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-insert.php'; -require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-update.php'; -require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/abilities/blocks/class-convertkit-mcp-ability-block-delete.php'; +require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/abilities/content/class-convertkit-mcp-ability-content.php'; +require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-list.php'; +require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-insert.php'; +require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-update.php'; +require_once CONVERTKIT_PLUGIN_PATH . '/includes/mcp/abilities/content/class-convertkit-mcp-ability-content-delete.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/plugin-sidebars/class-convertkit-plugin-sidebar.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/plugin-sidebars/class-convertkit-plugin-sidebar-post-settings.php'; require_once CONVERTKIT_PLUGIN_PATH . '/includes/pre-publish-actions/class-convertkit-pre-publish-action.php';