# blocks/trunk/src/Transfer/TransferService.php

Blocks – Reusable Content, Shortcodes &amp; Site Variables, version trunk. 120 lines.

- Page: https://pluginprobe.com/plugins/blocks/trunk/code/src/Transfer/TransferService.php
- Raw: https://pluginprobe.com/plugins/blocks/trunk/raw/src/Transfer/TransferService.php
- Modified: 2026-07-13T20:34:48+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/blocks/trunk/code/src/Transfer/TransferService.php#L10-L20`.

```php
<?php

declare(strict_types=1);

namespace RenzoJohnson\Blocks\Transfer;

\defined( 'ABSPATH' ) || exit;

final class TransferService {

	public function __construct(
		private readonly TransferValidator $validator,
		private readonly BlockTransferRepository $blocks,
	) {
	}

	/** @return array<string, mixed> */
	public function export_payload(): array {
		$items = array();

		foreach ( $this->blocks->all() as $block ) {
			$post   = $block->get_post();
			$locale = \get_post_meta( (int) $block->id(), '_locale', true );

			$items[] = array(
				'title'      => (string) $block->title(),
				'status'     => $post instanceof \WP_Post ? $post->post_status : 'publish',
				'locale'     => \is_string( $locale ) ? $locale : '',
				'properties' => $block->get_properties(),
				'categories' => $this->blocks->term_names( (int) $block->id(), 'blocks_category' ),
				'tags'       => $this->blocks->term_names( (int) $block->id(), 'blocks_tag' ),
			);
		}

		return array(
			'format'    => TransferValidator::FORMAT,
			'plugin'    => 'blocks',
			'version'   => BLOCKS_VERSION,
			'site'      => (string) \home_url( '/' ),
			'exported'  => \gmdate( 'c' ),
			'blocks'    => $items,
			'variables' => array(),
		);
	}

	/**
	 * @param array<mixed, mixed> $payload
	 * @return array{created: int, updated: int, skipped: int, variables: int}|\WP_Error
	 */
	public function import_payload( array $payload, bool $overwrite ): array|\WP_Error {
		$validated = $this->validator->validate( $payload );

		if ( \is_wp_error( $validated ) ) {
			return $validated;
		}

		$created = 0;
		$updated = 0;
		$skipped = 0;

		foreach ( $validated['blocks'] as $item ) {
			if ( ! \is_array( $item ) ) {
				return new \WP_Error( 'blocks_import_internal', \__( 'Validated block data was lost.', 'blocks' ) );
			}

			$requested_locale = (string) $item['locale'];
			$effective_locale = '' !== $requested_locale ? $requested_locale : (string) \get_locale();
			$existing         = $this->blocks->find( (string) $item['title'], $requested_locale, $effective_locale );

			if ( $existing instanceof \Blocks && ! $overwrite ) {
				++$skipped;
				continue;
			}

			$creating = ! $existing instanceof \Blocks;
			$block    = $creating
				? \Blocks::get_template(
					array(
						'title'  => $item['title'],
						'locale' => $effective_locale,
					)
				)
				: $existing;

			if ( ! $block instanceof \Blocks ) {
				return new \WP_Error( 'blocks_import_model', \__( 'A block could not be prepared for import.', 'blocks' ) );
			}

			$block->set_title( (string) $item['title'] );
			$block->set_properties( (array) $item['properties'] );
			$block->post_status = (string) $item['status'];
			$post_id            = $block->save();

			if ( ! \is_int( $post_id ) || 0 >= $post_id ) {
				return new \WP_Error( 'blocks_import_save', \__( 'A block could not be saved.', 'blocks' ) );
			}

			$this->blocks->sync_feature_indexes( $block, $post_id );
			$term_result = $this->blocks->assign_terms( $post_id, (array) $item['categories'], (array) $item['tags'] );

			if ( \is_wp_error( $term_result ) ) {
				return $term_result;
			}

			if ( $creating ) {
				++$created;
			} else {
				++$updated;
			}
		}

		return array(
			'created'   => $created,
			'updated'   => $updated,
			'skipped'   => $skipped,
			'variables' => 0,
		);
	}
}

```
