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' );