Copy Options: Translate post IDs

This snippet works together with the Copy Options add-on to translate post IDs found in blog options.

/**
	@brief		Translate post IDs during options copying.
	@since		2019-04-15 15:27:44
**/
function bc_broadcast_copy_options_do_copy( $action )
{
	$keys_to_translate = [
		'related_post_id',	// Contains only one post ID in it
		'related_post_ids',	// Contains several, serialized post IDs
	];

	$bcd = [];		// Array of Broadcast_Data objects containing link info.
	$key_ids = [];		// Array of post IDs in the key to translate.
	$type = false;		// The type of setting for the key to translte.

	// Retrieve the broadcast data for the keys we are interested in.
	foreach( $keys_to_translate as $key )
		if ( isset( $action->options_to_copy[ $key ] ) )
		{
			$value = $action->options_to_copy[ $key ];
			$ids = false;
			
			// Here we handle the different ways multiple post IDs can be stored.
			if ( strpos( $value, ',' ) !== false )
			{
				$type[ $key ] = 'comma';
				$ids = explode( ',', $value );
			}
			$json = json_decode( $value );
			if ( $json !== null )
			{
				$type[ $key ] = 'json';
				$ids = $json;
			}
			$obj = maybe_unserialize( $value );
			if ( is_array( $obj ) )
			{
				$type[ $key ] = 'serialize';
				$ids = $obj;
			}
			if ( intval( $value ) == $value )
			{
				$type[ $key ] = 'single';
				$ids = [ intval( $value ) ];
			}

			// No IDs found? Ignore.
			if ( ! $ids )
				continue;

			ThreeWP_Broadcast()->debug( 'Extracted post IDs %s from key %s', $ids, $key );
			$key_ids[ $key ] = $ids;
			foreach( $ids as $id )
				$bcd[ $id ] = ThreeWP_Broadcast()->get_parent_post_broadcast_data( get_current_blog_id(), $id );
		}

	foreach( $action->options_to_copy as $option_name => $option_value )
	{
		foreach( $action->blogs as $blog_id )
		{
			switch_to_blog( $blog_id );
			foreach( $keys_to_translate as $key )
			{
				// The key must have post IDs in it.
				if ( ! isset( $key_ids[ $key ] ) )
					continue;

				// Retrieve the new post IDs
				$new_values = [];
				foreach( $key_ids[ $key ] as $old_post_id )
				{
					$new_post_id = $bcd[ $old_post_id ]->get_linked_post_on_this_blog();
					// Key must be valid.
					if ( $new_post_id < 1 )
						continue;
					$new_values []= $new_post_id;
				}

				if ( count( $new_values ) < 1 )
					continue;

				// Put the new_values back together again.
				switch( $type[ $key ] )
				{
					case 'comma':
						$new_value = implode( ',', $new_values );
						break;
					case 'json':
						$new_value = json_encode( $new_values );
						break;
					case 'serialize':
						$new_value = serialize( $new_values );
						break;
					default:
						$new_value = reset( $new_values );
						break;
				}

				ThreeWP_Broadcast()->debug( 'Setting new value %s for key %s', $new_value, $key );
				update_option( $key, $new_value );
			}
			restore_current_blog();
		}
	}
}
add_action( 'broadcast_copy_options_do_copy', 'bc_broadcast_copy_options_do_copy' );