Shortcode Items parse_find and replace_id actions

As of version 43.13, the shortcode-related add-ons (Attachments, Menus, Posts and Terms) offer two actions that allow for customized parsing of the shortcodes: broadcast_shortcode_items_parse_find and broadcast_shortcode_items_replace_id. The actions are called in src / classes / classes / shortcodes_items / Shortcode_Items.php.

The actions allow for non-standard, customized shortcode attributes to be parsed. In the example below, the attribute “logos” contains JSON-encoded attachment IDs that are also urlencoded().

To use the code below, setup your Shortcode Attachments add-on with a shortcode with the name of the shortcode to detect in the post. Then put the following in your functions.php.

/**
	@brief		Convenience function to validity check the shortcode data.
	@since		2018-11-14 15:20:18
**/
function bc_broadcast_shortcode_items_extract_array( $action )
{
	// We are looking for the shortcode attachments class.
	if ( $action->called_class != 'threewp_broadcast\premium_pack\shortcode_attachments\Shortcode_Attachments' )
		return false;

	// We are looking for the logos attribute.
	if ( ! isset( $action->find->values[ 'logos' ] ) )
	{
		ThreeWP_broadcast()->debug( 'bc_broadcast_shortcode_items_extract_array: No logos found.' );
		return false;
	}

	// Extract the ids.
	$value = $action->find->values[ 'logos' ][ 'ids' ];
	// We want only the first, since there will be only one.
	$value = reset( $value );

	// decode
	$value = urldecode( $value );

	// And json decode.
	$logo_images = json_decode( $value );

	// Check that the decoded json is valid.
	if ( ! is_array( $logo_images ) )
	{
		ThreeWP_broadcast()->debug( 'bc_broadcast_shortcode_items_extract_array: Invalid json.' );
		return false;
	}

	return $logo_images;
}

/**
	@brief		Specially parse a json encoded object in a shortcode that contains IDs.
	@since		2018-11-14 15:09:44
**/
function bc_broadcast_shortcode_items_parse_find( $action )
{
	$logo_images = bc_broadcast_shortcode_items_extract_array( $action );
	if ( ! $logo_images )
		return;

	foreach( $logo_images as $logo_image )
	{
		if ( ! isset( $logo_image->image ) )
			continue;
		$image_id = $logo_image->image;
		try
		{
			$image_id = intval( $image_id );
			$action->broadcasting_data->add_attachment( $image_id );	// This throws an exception if the image does not exist.
			ThreeWP_broadcast()->debug( 'broadcast_shortcode_items_parse_find: Added image %s', $image_id );
		}
		catch ( \Exception $e )
		{
			ThreeWP_broadcast()->debug( 'broadcast_shortcode_items_parse_find: Error adding a json encoded image from %s', $action->find->original );
		}
	}

	// Tell shortcode_items to not process the shortcode further.
	$action->finish();
}
add_action( 'broadcast_shortcode_items_parse_find', 'bc_broadcast_shortcode_items_parse_find' );

/**
	@brief		Replace the image IDs in this json encoded shortcode.
	@since		2018-11-14 15:17:58
**/
function bc_broadcast_shortcode_items_replace_id( $action )
{
	$logo_images = bc_broadcast_shortcode_items_extract_array( $action );
	if ( ! $logo_images )
		return;

	foreach( $logo_images as $logo_image )
	{
		if ( ! isset( $logo_image->image ) )
			continue;
		$old_id = $logo_image->image;
		$new_id = $action->broadcasting_data->copied_attachments()->get( $old_id );
		if ( $new_id < 1 ) continue; ThreeWP_broadcast()->debug( 'broadcast_shortcode_items_replace_id: Replacing image %s with %s in %s',
			$old_id,
			$new_id,
			$action->find->original );
		$logo_image->image = $new_id;
	}

	// Generate the new json value.
	$new_json = json_encode( $logo_images );
	$new_json = urlencode( $new_json );

	$action->item = str_replace( $action->find->values[ 'logos' ][ 'ids' ][ 0 ], $new_json, $action->find->original );

	// Tell shortcode_items to not process the shortcode further.
	$action->finish();
}
add_action( 'broadcast_shortcode_items_replace_id', 'bc_broadcast_shortcode_items_replace_id' );