# convertkit/3.4.4/includes/blocks/helpers/class-convertkit-block-post-helper.php

Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages, version 3.4.4. 311 lines.

- Page: https://pluginprobe.com/plugins/convertkit/3.4.4/code/includes/blocks/helpers/class-convertkit-block-post-helper.php
- Raw: https://pluginprobe.com/plugins/convertkit/3.4.4/raw/includes/blocks/helpers/class-convertkit-block-post-helper.php
- Modified: 2026-08-28T10:49:42+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/convertkit/3.4.4/code/includes/blocks/helpers/class-convertkit-block-post-helper.php#L10-L20`.

```php
<?php
/**
 * ConvertKit Block Post Helper class.
 *
 * @package ConvertKit
 * @author ConvertKit
 */

/**
 * Helper methods to find, insert, update and delete blocks within a WordPress Post's content.
 *
 * @package ConvertKit
 * @author  ConvertKit
 */
class ConvertKit_Block_Post_Helper {

	/**
	 * Finds all blocks matching the given block name in a Post's content.
	 *
	 * @since   3.4.0
	 *
	 * @param   int    $post_id     Post ID.
	 * @param   string $block_name  Programmatic Block Name.
	 * @return  WP_Error|array
	 */
	public static function find( $post_id, $block_name ) {

		// Get post.
		$post = get_post( $post_id );
		if ( ! $post ) {
			return new WP_Error(
				'convertkit_block_post_helper_post_not_found',
				/* translators: %d: post ID */
				sprintf( __( 'No post exists with ID %d.', 'convertkit' ), $post_id )
			);
		}

		// Parse blocks.
		$blocks = parse_blocks( $post->post_content );
		$found  = array();

		$occurrence_index = 0;

		foreach ( $blocks as $block ) {
			if ( ! isset( $block['blockName'] ) || $block['blockName'] !== $block_name ) {
				continue;
			}

			$found[] = array(
				'occurrence_index' => (int) $occurrence_index,
				'attrs'            => $block['attrs'],
			);

			++$occurrence_index;
		}

		return $found;

	}

	/**
	 * Inserts a new block into the Post's content at the specified position.
	 *
	 * @since   3.4.0
	 *
	 * @param   int    $post_id     Post ID.
	 * @param   string $block_name  Programmatic Block Name.
	 * @param   array  $attrs       Block Attributes.
	 * @param   string $position    One of 'prepend', 'append', 'index'.
	 * @param   int    $index       Zero-based top-level block index; only used when $position is 'index'.
	 * @return  WP_Error|array
	 */
	public static function insert( $post_id, $block_name, $attrs, $position = 'append', $index = 0 ) {

		// If the index is negative, bail.
		if ( $position === 'index' && (int) $index < 0 ) {
			return new WP_Error(
				'convertkit_block_post_helper_invalid_index',
				sprintf(
					/* translators: %d: index */
					__( 'The supplied index (%d) must be zero or a positive integer.', 'convertkit' ),
					(int) $index
				)
			);
		}

		// Get Post.
		$post = get_post( $post_id );
		if ( ! $post ) {
			return new WP_Error(
				'convertkit_block_post_helper_insert_block_post_not_found',
				/* translators: %d: Post ID */
				sprintf( __( 'No Post exists with ID %d.', 'convertkit' ), $post_id )
			);
		}

		// Parse blocks.
		$blocks = parse_blocks( $post->post_content );

		// Build the new block to insert.
		$new_block = array(
			'blockName'    => $block_name,
			'attrs'        => (array) $attrs,
			'innerBlocks'  => array(),
			'innerHTML'    => '',
			'innerContent' => array(),
		);

		// Resolve $position into a concrete zero-based splice point in the
		// top-level block array.
		switch ( $position ) {
			case 'prepend':
				$insert_at = 0;
				break;

			case 'index':
				$insert_at = max( 0, min( (int) $index, count( $blocks ) ) );
				break;

			case 'append':
			default:
				$insert_at = count( $blocks );
				break;
		}

		// Splice in the new block.
		array_splice( $blocks, $insert_at, 0, array( $new_block ) );

		// Determine the occurrence index of the newly inserted block, by
		// counting how many blocks of the same name precede it.
		$occurrence_index = 0;
		for ( $i = 0; $i < $insert_at; $i++ ) {
			if ( isset( $blocks[ $i ]['blockName'] ) && $blocks[ $i ]['blockName'] === $block_name ) {
				++$occurrence_index;
			}
		}

		// Update Post.
		$result = wp_update_post(
			array(
				'ID'           => $post_id,
				'post_content' => serialize_blocks( $blocks ),
			),
			true
		);

		// Bail if the update failed.
		if ( is_wp_error( $result ) ) {
			return $result;
		}

		// Return the occurrence index of the newly inserted block.
		return array(
			'post_id'          => $post_id,
			'occurrence_index' => $occurrence_index,
		);

	}

	/**
	 * Updates the attributes of an existing block in the Post's content.
	 *
	 * @since   3.4.0
	 *
	 * @param   int    $post_id           Post ID.
	 * @param   string $block_name        Programmatic Block Name.
	 * @param   int    $occurrence_index  Position to update block.
	 * @param   array  $attrs             Block Attributes.
	 * @return  WP_Error|array
	 */
	public static function update( $post_id, $block_name, $occurrence_index, $attrs ) {

		// Get Post.
		$post = get_post( $post_id );
		if ( ! $post ) {
			return new WP_Error(
				'convertkit_block_post_helper_update_block_post_not_found',
				/* translators: %d: post ID */
				sprintf( __( 'No Post exists with ID %d.', 'convertkit' ), $post_id )
			);
		}

		// Parse blocks.
		$blocks      = parse_blocks( $post->post_content );
		$block_index = 0;
		$matched     = false;

		foreach ( $blocks as $key => $block ) {
			// Skip if the block name does not match.
			if ( ! isset( $block['blockName'] ) || $block['blockName'] !== $block_name ) {
				continue;
			}

			// Update the block if the occurrence index matches.
			if ( $block_index === (int) $occurrence_index ) {
				$blocks[ $key ]['attrs'] = array_merge( (array) $block['attrs'], (array) $attrs );
				$matched                 = true;
				break;
			}

			++$block_index;
		}

		// Bail if the block was not found.
		if ( ! $matched ) {
			return new WP_Error(
				'convertkit_block_post_helper_occurrence_not_found',
				/* translators: 1: block name, 2: occurrence index, 3: post ID */
				sprintf( __( 'No occurrence #%2$d of block %1$s found in post %3$d.', 'convertkit' ), $block_name, (int) $occurrence_index, $post_id )
			);
		}

		// Update Post.
		$result = wp_update_post(
			array(
				'ID'           => $post_id,
				'post_content' => serialize_blocks( $blocks ),
			),
			true
		);

		// Bail if the update failed.
		if ( is_wp_error( $result ) ) {
			return $result;
		}

		// Return the occurrence index of the block that was updated.
		return array(
			'post_id'          => $post_id,
			'occurrence_index' => (int) $occurrence_index,
		);

	}

	/**
	 * Deletes a specific block from the Post's content.
	 *
	 * @since   3.4.0
	 *
	 * @param   int    $post_id           Post ID.
	 * @param   string $block_name        Programmatic Block Name.
	 * @param   int    $occurrence_index  Zero-based index among this block's occurrences in the post.
	 * @return  WP_Error|array
	 */
	public static function delete( $post_id, $block_name, $occurrence_index ) {

		// Get Post.
		$post = get_post( $post_id );
		if ( ! $post ) {
			return new WP_Error(
				'convertkit_block_post_helper_update_block_post_not_found',
				/* translators: %d: post ID */
				sprintf( __( 'No Post exists with ID %d.', 'convertkit' ), $post_id )
			);
		}

		// Parse blocks.
		$blocks      = parse_blocks( $post->post_content );
		$block_index = 0;
		$matched     = false;

		foreach ( $blocks as $key => $block ) {
			// Skip if the block name does not match.
			if ( ! isset( $block['blockName'] ) || $block['blockName'] !== $block_name ) {
				continue;
			}

			// Delete the block if the occurrence index matches.
			if ( $block_index === (int) $occurrence_index ) {
				unset( $blocks[ $key ] );
				$blocks  = array_values( $blocks );
				$matched = true;
				break;
			}

			++$block_index;
		}

		// Bail if the block was not found.
		if ( ! $matched ) {
			return new WP_Error(
				'convertkit_block_post_helper_occurrence_not_found',
				/* translators: 1: block name, 2: occurrence index, 3: post ID */
				sprintf( __( 'No occurrence #%2$d of block %1$s found in post %3$d.', 'convertkit' ), $block_name, (int) $occurrence_index, $post_id )
			);
		}

		// Update Post.
		$result = wp_update_post(
			array(
				'ID'           => $post_id,
				'post_content' => serialize_blocks( $blocks ),
			),
			true
		);

		// Bail if the update failed.
		if ( is_wp_error( $result ) ) {
			return $result;
		}

		// Return the occurrence index of the block that was deleted.
		return array(
			'post_id'          => $post_id,
			'occurrence_index' => (int) $occurrence_index,
		);

	}

}

```
