Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions inc/classes/elementor-widgets/class-godam-gallery.php
Original file line number Diff line number Diff line change
Expand Up @@ -502,12 +502,17 @@ protected function render() {
);
}

$shortcode_atts_string = '';
foreach ( $shortcode_atts as $key => $value ) {
$shortcode_atts_string .= sprintf( ' %s="%s"', $key, esc_attr( $value ) );
}
// Pass the settings as an attributes array rather than building a
// "[godam_video_gallery …]" string, so a setting value is never parsed as
// shortcode syntax. Values stay strings, as the shortcode parser delivers them.
$shortcode_atts = array_map(
function ( $value ) {
return is_scalar( $value ) ? (string) $value : '';
},
$shortcode_atts
);

echo do_shortcode( '[godam_video_gallery' . $shortcode_atts_string . ']' );
echo rtgodam_render_shortcode_from_atts( 'godam_video_gallery', $shortcode_atts ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The gallery template escapes its output.
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,14 @@ public function update_entry_meta_display_godam_recorder( $meta_value, $value, $

$transcoded_url_meta_key = 'rtgodam_transcoded_url_everestforms_' . $form_id . '_' . $entry_id;
$transcoded_url_output = '';
$transcoded_url_source = '';
$transcoded_url = '';

if ( ! empty( $entry_data ) ) {
$transcoded_url = esc_url( $entry_data->meta[ $transcoded_url_meta_key ] ?? '' );
$transcoded_url_source = $entry_data->meta[ $transcoded_url_meta_key ] ?? '';
$transcoded_url = esc_url( $transcoded_url_source );

if ( ! empty( $transcoded_url ) ) {
$transcoded_url = "transcoded_url={$transcoded_url}";
$transcoded_url_output = sprintf(
"<div style='margin: 8px 0;' class='godam-transcoded-url-info'><span class='dashicons dashicons-yes-alt'></span><strong>%s</strong></div>",
$is_audio
Expand All @@ -151,8 +153,7 @@ public function update_entry_meta_display_godam_recorder( $meta_value, $value, $
if ( $is_audio ) {
$audio_output = '<audio controls style="width: 100%; margin-top: 10px;">';
if ( ! empty( $transcoded_url ) ) {
$audio_src = str_replace( 'transcoded_url=', '', $transcoded_url );
$audio_output .= sprintf( '<source src="%s" type="audio/mpeg">', esc_url( $audio_src ) );
$audio_output .= sprintf( '<source src="%s" type="audio/mpeg">', esc_url( $transcoded_url ) );
}
$audio_output .= sprintf( '<source src="%s" type="%s">', esc_url( $value ), esc_attr( $mime_type ) );
$audio_output .= esc_html__( 'Your browser does not support the audio element.', 'godam' );
Expand All @@ -164,7 +165,13 @@ public function update_entry_meta_display_godam_recorder( $meta_value, $value, $

$media_output = $audio_output;
} else {
$video_output = do_shortcode( "[godam_video src='{$value}' {$transcoded_url} ]" );
$video_output = rtgodam_render_shortcode_from_atts(
'godam_video',
array(
'src' => esc_url_raw( $value ),
'transcoded_url' => esc_url_raw( $transcoded_url_source ),
)
);

// Workaround, replace all line breaks and new lines with empty string.
$video_output = str_replace( array( "\r", "\n" ), '', $video_output );
Expand Down
11 changes: 9 additions & 2 deletions inc/classes/fluentforms/fields/class-recorder-field.php
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ public function render_recorder_field_markup( $response, $field, $form_id, $is_h
$transcoded_url = '';

if ( ! empty( $submission_meta ) ) {
$transcoded_url = esc_url( $submission_meta->value );
$transcoded_url = esc_url_raw( $submission_meta->value );
$transcoded_url_output = sprintf(
"<div style='margin: 8px 0;' class='godam-transcoded-url-info'><span class='dashicons dashicons-yes-alt'></span><strong>%s</strong></div>",
esc_html__( 'Video saved and transcoded successfully on GoDAM', 'godam' )
Expand All @@ -857,7 +857,14 @@ public function render_recorder_field_markup( $response, $field, $form_id, $is_h
/**
* Generate video output.
*/
$video_output = do_shortcode( "[godam_video src='{$video_url}' transcoded_url='{$transcoded_url}' aspectRatio='']" );
$video_output = rtgodam_render_shortcode_from_atts(
'godam_video',
array(
'src' => esc_url_raw( $video_url ),
'transcoded_url' => $transcoded_url,
'aspectratio' => '',
)
);
$video_output = '<div class="gf-godam-video-preview">' . $video_output . '</div>';

$download_url = sprintf(
Expand Down
11 changes: 9 additions & 2 deletions inc/classes/gravity-forms/class-gf-field-godam-video.php
Original file line number Diff line number Diff line change
Expand Up @@ -423,10 +423,17 @@ public function get_value_entry_detail( $value, $currency = '', $use_text = fals
if ( $is_video ) {

if ( $transcoded_url ) {
$transcoded_url = esc_url( $transcoded_url );
$transcoded_url = esc_url_raw( $transcoded_url );
}

$video_output = do_shortcode( "[godam_video src='{$file_path}' transcoded_url='{$transcoded_url}' aspectRatio='']" );
$video_output = rtgodam_render_shortcode_from_atts(
'godam_video',
array(
'src' => esc_url_raw( $file_path ),
'transcoded_url' => (string) $transcoded_url,
'aspectratio' => '',
)
);
$video_output = '<div class="gf-godam-video-preview">' . $video_output . '</div>';
$output_arr[] = $video_output;
}
Expand Down
56 changes: 45 additions & 11 deletions inc/classes/rest-api/class-dynamic-shortcode.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function get_rest_routes() {
'required' => false,
'type' => 'string',
'default' => '',
'sanitize_callback' => 'sanitize_text_field',
'sanitize_callback' => 'sanitize_key',
),
),
),
Expand All @@ -77,7 +77,8 @@ public function render_shortcode( WP_REST_Request $request ) {

$engagements = $request->get_param( 'engagements' );

$godam_context = $request->get_param( 'godam_context' );
// Slug characters only, whatever reaches this method.
$godam_context = sanitize_key( (string) $request->get_param( 'godam_context' ) );

/**
* Fires before resolving this attachment's URL/meta/sources, so
Expand Down Expand Up @@ -128,9 +129,7 @@ public function render_shortcode( WP_REST_Request $request ) {
'type' => 'video/quicktime' === $video_src_type ? 'video/mp4' : $video_src_type,
);

// Convert JSON to use custom placeholders instead of square brackets.
$sources_json = wp_json_encode( $sources );
$sources_with_placeholders = str_replace( array( '[', ']' ), array( '__rtgob__', '__rtgcb__' ), $sources_json );
$sources_json = wp_json_encode( $sources );

// Add action before shortcode rendering.
do_action( 'rtgodam_shortcode_before_render', $id );
Expand Down Expand Up @@ -161,18 +160,53 @@ public function render_shortcode( WP_REST_Request $request ) {
$video_date = apply_filters( 'rtgodam_shortcode_video_date', $video_date, $id );

ob_start();
$shortcode = "[godam_video id='{$id}' engagements='" . esc_attr( $engagements ) . "' sources='{$sources_with_placeholders}'";
$atts = array(
'id' => (string) $id,
'engagements' => (string) $engagements,
'sources' => $sources_json,
);

if ( ! empty( $godam_context ) ) {
$shortcode .= " godam_context='" . esc_attr( $godam_context ) . "'";
$atts['godam_context'] = $godam_context;
}

$shortcode .= ']';
/**
* Filters the attributes the player is rendered with.
*
* @since 2.5.1
*
* @param array $atts Attributes passed to the [godam_video] renderer.
* @param int $id Attachment ID.
*/
$atts = apply_filters( 'rtgodam_shortcode_atts', $atts, $id );

if ( has_filter( 'rtgodam_shortcode_output' ) ) {
// Keep sites that still change the shortcode string working. Every value in it is
// an ID, a slug, 'show'/'hide' or JSON with its brackets swapped for placeholders.
$shortcode = "[godam_video id='" . absint( $atts['id'] ?? $id ) . "' engagements='" . esc_attr( $atts['engagements'] ?? '' ) . "' sources='" . str_replace( array( '[', ']' ), array( '__rtgob__', '__rtgcb__' ), (string) ( $atts['sources'] ?? '' ) ) . "'";

// Add filter for shortcode.
$shortcode = apply_filters( 'rtgodam_shortcode_output', $shortcode, $id );
if ( ! empty( $atts['godam_context'] ) ) {
$shortcode .= " godam_context='" . esc_attr( $atts['godam_context'] ) . "'";
}

$shortcode .= ']';

/**
* Filters the shortcode string the player is rendered from.
*
* @since 1.1.4
* @deprecated 2.5.1 Use the rtgodam_shortcode_atts filter instead.
*
* @param string $shortcode The [godam_video] shortcode.
* @param int $id Attachment ID.
*/
$shortcode = apply_filters_deprecated( 'rtgodam_shortcode_output', array( $shortcode, $id ), '2.5.1', 'rtgodam_shortcode_atts' );

echo do_shortcode( $shortcode );
} else {
echo rtgodam_render_shortcode_from_atts( 'godam_video', $atts ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The player template escapes its output.
}

echo do_shortcode( $shortcode );
$html = ob_get_clean();

// Add filter for final HTML output.
Expand Down
12 changes: 8 additions & 4 deletions inc/classes/sureforms/class-form-submit.php
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,6 @@ public function render_custom_field_markup( $markup, $value ) {
$transcoded_url_output = '';

if ( ! empty( $transcoded_url ) ) {
$transcoded_url = esc_url( $transcoded_url );
$transcoded_url = "transcoded_url={$transcoded_url}";
$transcoded_url_output = sprintf(
"<div style='margin: 8px 0;' class='godam-transcoded-url-info'><span class='dashicons dashicons-yes-alt'></span><strong>%s</strong></div>",
$is_audio
Expand All @@ -368,15 +366,21 @@ public function render_custom_field_markup( $markup, $value ) {
if ( $is_audio ) {
$audio_output = '<audio controls>';
if ( ! empty( $transcoded_url ) ) {
$audio_output .= sprintf( '<source src="%s" type="audio/mpeg">', esc_url( str_replace( 'transcoded_url=', '', $transcoded_url ) ) );
$audio_output .= sprintf( '<source src="%s" type="audio/mpeg">', esc_url( $transcoded_url ) );
}
$audio_output .= sprintf( '<source src="%s" type="%s">', esc_url( $value ), esc_attr( $file_type['type'] ) );
$audio_output .= esc_html__( 'Your browser does not support the audio element.', 'godam' );
$audio_output .= '</audio>';

$media_output = '<div class="srfm-godam-audio-preview">' . $audio_output . '</div>';
} else {
$video_output = do_shortcode( "[godam_video src='{$value}' {$transcoded_url} ]" );
$video_output = rtgodam_render_shortcode_from_atts(
'godam_video',
array(
'src' => esc_url_raw( $value ),
'transcoded_url' => esc_url_raw( (string) $transcoded_url ),
)
);
$media_output = '<div class="srfm-godam-video-preview">' . $video_output . '</div>';
}

Expand Down
12 changes: 11 additions & 1 deletion inc/classes/wpforms/wpforms-field-godam-record-entry-edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,17 @@
<?php esc_html_e( 'Your browser does not support the audio element.', 'godam' ); ?>
</audio>
<?php else : ?>
<?php echo do_shortcode( "[godam_video poster='{$godam_thumbnail_url}' src='{$godam_value}' transcoded_url='{$godam_transcoded_url}']" ); ?>
<?php
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The player template escapes its output.
echo rtgodam_render_shortcode_from_atts(
'godam_video',
array(
'poster' => esc_url_raw( $godam_thumbnail_url ),
'src' => esc_url_raw( $godam_value ),
'transcoded_url' => esc_url_raw( $godam_transcoded_url ),
)
);
?>
<?php endif; ?>
</div>
<a
Expand Down
11 changes: 10 additions & 1 deletion inc/classes/wpforms/wpforms-field-godam-record-entry-view.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,16 @@ class="godam-video-link <?php echo ( empty( $value ) ? 'hidden' : '' ); ?>"
// No need to escape here, the entire template will be returned as strings,
// which will be later on escaped using wp_kses_post() by WPForms before rendering the field.
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo force_balance_tags( do_shortcode( "[godam_video poster='{$godam_thumbnail_url}' src='{$godam_attachment_url}' transcoded_url='{$godam_transcoded_url}']" ) );
echo force_balance_tags(
rtgodam_render_shortcode_from_atts(
'godam_video',
array(
'poster' => esc_url_raw( $godam_thumbnail_url ),
'src' => esc_url_raw( $godam_attachment_url ),
'transcoded_url' => esc_url_raw( (string) $godam_transcoded_url ),
)
)
);
?>
<?php endif; ?>
</div>
53 changes: 40 additions & 13 deletions inc/helpers/custom-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -2192,10 +2192,10 @@ function godam_preview_page_content( $video_id ) {
) . ' /-->'
);
} else {
$godam_shortcode = $godam_is_audio
? '[godam_audio id="' . $video_id . '"]'
: '[godam_video id="' . $video_id . '"]';
$godam_media_output = do_shortcode( $godam_shortcode );
$godam_media_output = rtgodam_render_shortcode_from_atts(
$godam_is_audio ? 'godam_audio' : 'godam_video',
array( 'id' => (string) $video_id )
);
}
?>
<div class="godam-video-preview--notice">
Expand Down Expand Up @@ -2293,6 +2293,30 @@ function rtgodam_get_block_source_from_context( $context ) {
return isset( $map[ $context ] ) ? $map[ $context ] : $context;
}

/**
* Render a registered shortcode from an attributes array.
*
* Calls the shortcode's callback directly, so each attribute value is passed to
* the renderer as plain data and is never parsed as shortcode syntax. Use it
* instead of do_shortcode() when a value comes from a request, a form
* submission or other stored user data.
*
* @since 2.5.1
*
* @param string $tag Shortcode tag, for example 'godam_video'.
* @param array<string, mixed> $atts Attributes, keyed in lowercase as the shortcode parser would key them.
* @return string The shortcode output, or an empty string when the shortcode is not registered or its callback cannot be called.
*/
function rtgodam_render_shortcode_from_atts( $tag, $atts = array() ) {
global $shortcode_tags;

if ( ! shortcode_exists( $tag ) || ! is_callable( $shortcode_tags[ $tag ] ) ) {
return '';
}

return (string) call_user_func( $shortcode_tags[ $tag ], $atts, '', $tag );
}

/**
* Generate HTML content for the video embed page.
*
Expand All @@ -2301,10 +2325,10 @@ function rtgodam_get_block_source_from_context( $context ) {
* making it suitable for embedding in iframes or modals.
*
* @param int $video_id The ID of the video attachment to embed.
* @param string $godam_context Optional. The player context passed to the godam_video shortcode (e.g. 'video-only').
* @param string $godam_context Optional. The player context passed to the godam_video shortcode (e.g. 'video-only'). Reduced to slug characters with sanitize_key().
* @param string $bg_color Optional. Hex background color applied as --godam-video-bg-color CSS variable on the wrapper.
* @param bool $show_engagements Optional. Whether to show engagements in the embed. Default false (no engagements shown).
* @param string $block_source Optional. Analytics placement slug forwarded to the player (e.g. 'video-gallery' for gallery iframes).
* @param string $block_source Optional. Analytics placement slug forwarded to the player (e.g. 'video-gallery' for gallery iframes). Reduced to slug characters with sanitize_key().
* @param int $host_post_id Optional. Post ID of the page embedding this iframe, so analytics attribute to the host page.
*
* @since 1.5.0
Expand All @@ -2319,6 +2343,10 @@ function godam_embed_page_content( $video_id, $godam_context = '', $bg_color = '
$video_id = intval( $video_id );
$engagements_value = rtgodam_is_engagement_feature_enabled() && $show_engagements ? 'show' : '';

// Both values arrive from the URL; keep them to slug characters.
$godam_context = sanitize_key( $godam_context );
$block_source = sanitize_key( $block_source );

if ( ! empty( $video_id ) ) {
/**
* Fires before resolving this attachment's post/mime data, so
Expand All @@ -2342,20 +2370,19 @@ function godam_embed_page_content( $video_id, $godam_context = '', $bg_color = '
<?php
} else {
// Display video content.
$godam_shortcode = '[godam_video id="' . $video_id . '"';
$godam_atts = array( 'id' => (string) $video_id );
if ( ! empty( $godam_context ) ) {
$godam_shortcode .= ' godam_context="' . esc_attr( $godam_context ) . '"';
$godam_atts['godam_context'] = $godam_context;
}
if ( ! empty( $engagements_value ) ) {
$godam_shortcode .= ' engagements="' . esc_attr( $engagements_value ) . '"';
$godam_atts['engagements'] = $engagements_value;
}
if ( ! empty( $block_source ) ) {
$godam_shortcode .= ' block_source="' . esc_attr( $block_source ) . '"';
$godam_atts['block_source'] = $block_source;
}
if ( ! empty( $host_post_id ) ) {
$godam_shortcode .= ' host_post_id="' . absint( $host_post_id ) . '"';
$godam_atts['host_post_id'] = (string) absint( $host_post_id );
}
$godam_shortcode .= ']';

$godam_wrapper_style = ! empty( $bg_color ) ? '--godam-video-bg-color: ' . $bg_color . ';' : '';
?>
Expand All @@ -2364,7 +2391,7 @@ class="godam-video-embed" data-godam-context="<?php echo esc_attr( $godam_contex
data-show-engagements="<?php echo esc_attr( $show_engagements ? 'true' : 'false' ); ?>"
style="<?php echo esc_attr( $godam_wrapper_style ); ?>"
>
<?php echo do_shortcode( $godam_shortcode ); ?>
<?php echo rtgodam_render_shortcode_from_atts( 'godam_video', $godam_atts ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- The player template escapes its output. ?>
</div>
<?php
}
Expand Down
4 changes: 4 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,10 @@ function set_transient( $key, $value, $expiration = 0 ) { // phpcs:ignore Generi
*/
require_once __DIR__ . '/stubs/hooks.php';
require_once __DIR__ . '/stubs/i18n.php';
// Shortcode registry and runner, so a test can register a shortcode and see whether
// text handed to do_shortcode() runs it. Loaded here so its do_shortcode() is the one
// that every test sees.
require_once __DIR__ . '/stubs/shortcode-runtime.php';
// HTTP / REST stubs for the Analytics microservice-proxy tests (fetch_top_videos
// / fetch_top_products): fake wp_remote_* responses + get_option, and minimal
// WP_REST_Request / WP_REST_Response so the proxy's error-vs-empty guard can be
Expand Down
Loading
Loading