diff --git a/inc/classes/metform/class-metform-integration.php b/inc/classes/metform/class-metform-integration.php index 31d96c2e7..0a6d5b32d 100644 --- a/inc/classes/metform/class-metform-integration.php +++ b/inc/classes/metform/class-metform-integration.php @@ -95,7 +95,7 @@ public function add_additional_css_for_godam_player() { * @since 1.4.0 * * @param string $layer Layer name. - * @param string $layer_id Layer ID. + * @param int $layer_id Layer ID. * * @return void */ @@ -121,13 +121,13 @@ public function add_css_for_the_layer_inside_iframe( $layer, $layer_id ) { * @since 1.4.0 * * @param string $layer Layer name. - * @param string $layer_id Layer ID. + * @param int $layer_id Layer ID. * * @return void */ public function render_layer_form_for_video_editor( $layer, $layer_id ) { if ( 'metform' === $layer && ! empty( $layer_id ) ) { - echo do_shortcode( "[metform form_id='{$layer_id}']" ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo do_shortcode( sprintf( "[metform form_id='%d']", absint( $layer_id ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } } } diff --git a/inc/classes/ninja-forms/class-ninja-forms-integration.php b/inc/classes/ninja-forms/class-ninja-forms-integration.php index 9b219a603..0568d4d1b 100644 --- a/inc/classes/ninja-forms/class-ninja-forms-integration.php +++ b/inc/classes/ninja-forms/class-ninja-forms-integration.php @@ -121,7 +121,7 @@ public function add_additional_css_for_godam_player() { * @since 1.4.0 * * @param string $layer Layer name. - * @param string $layer_id Layer ID. + * @param int $layer_id Layer ID. * * @return void */ @@ -150,13 +150,13 @@ public function add_css_for_the_layer_inside_iframe( $layer, $layer_id ) { * @since 1.4.0 * * @param string $layer Layer name. - * @param string $layer_id Layer ID. + * @param int $layer_id Layer ID. * * @return void */ public function render_layer_form_for_video_editor( $layer, $layer_id ) { if ( 'ninja-forms' === $layer && ! empty( $layer_id ) ) { - echo do_shortcode( "[ninja_form id='{$layer_id}']" ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo do_shortcode( sprintf( "[ninja_form id='%d']", absint( $layer_id ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } } diff --git a/inc/templates/render-video-editor-form-layer.php b/inc/templates/render-video-editor-form-layer.php index 0ba929bc7..d8830590e 100644 --- a/inc/templates/render-video-editor-form-layer.php +++ b/inc/templates/render-video-editor-form-layer.php @@ -19,8 +19,8 @@ // We need to remove the admin bar for this template to avoid to display it on the video editor page. add_filter( 'show_admin_bar', '__return_false' ); // phpcs:ignore WordPressVIPMinimum.UserExperience.AdminBarRemoval.RemovalDetected -$godam_layer = get_query_var( 'rtgodam-render-layer' ); -$godam_layer_id = get_query_var( 'rtgodam-layer-id' ); +$godam_layer = sanitize_key( get_query_var( 'rtgodam-render-layer' ) ); +$godam_layer_id = absint( get_query_var( 'rtgodam-layer-id' ) ); ?> @@ -38,7 +38,7 @@ * @since 1.4.0 * * @param string $godam_layer The type of layer being rendered. - * @param string $godam_layer_id The ID of the layer being rendered. + * @param int $godam_layer_id The ID of the layer being rendered. */ do_action( 'rtgodam_render_layer_for_video_editor_before', $godam_layer, $godam_layer_id ); ?> @@ -55,7 +55,7 @@ * @since 1.4.0 * * @param string $godam_layer The type of layer being rendered. - * @param string $godam_layer_id The ID of the layer being rendered. + * @param int $godam_layer_id The ID of the layer being rendered. */ do_action( 'rtgodam_render_layer_for_video_editor', $godam_layer, $godam_layer_id ); ?> @@ -67,7 +67,7 @@ * @since 1.4.0 * * @param string $godam_layer The type of layer being rendered. - * @param string $godam_layer_id The ID of the layer being rendered. + * @param int $godam_layer_id The ID of the layer being rendered. */ do_action( 'rtgodam_render_layer_for_video_editor_after', $godam_layer, $godam_layer_id ); ?> diff --git a/tests/php/FormLayerPreviewIdTest.php b/tests/php/FormLayerPreviewIdTest.php new file mode 100644 index 000000000..cab76df9d --- /dev/null +++ b/tests/php/FormLayerPreviewIdTest.php @@ -0,0 +1,101 @@ + array() ); + + // Register only the preview callbacks, on constructor-less instances. + foreach ( array( Metform_Integration::class, Ninja_Forms_Integration::class ) as $class ) { + $object = ( new \ReflectionClass( $class ) )->newInstanceWithoutConstructor(); + add_action( 'rtgodam_render_layer_for_video_editor_before', array( $object, 'add_css_for_the_layer_inside_iframe' ), 10, 2 ); + add_action( 'rtgodam_render_layer_for_video_editor', array( $object, 'render_layer_form_for_video_editor' ), 10, 2 ); + } + } + + protected function tearDown(): void { + unset( $GLOBALS['rtgodam_stub'], $GLOBALS['rtgodam_hooks'] ); + parent::tearDown(); + } + + /** + * Render the preview template for the given query vars and return the + * shortcode strings that reached do_shortcode(). + * + * @param string $layer Value of `rtgodam-render-layer`. + * @param mixed $layer_id Value of `rtgodam-layer-id`. + * @return string[] + */ + private function render_preview( $layer, $layer_id ) { + $GLOBALS['rtgodam_stub']['query_vars'] = array( + 'rtgodam-render-layer' => $layer, + 'rtgodam-layer-id' => $layer_id, + ); + $GLOBALS['rtgodam_stub']['shortcodes'] = array(); + + ob_start(); + include dirname( __DIR__, 2 ) . '/inc/templates/render-video-editor-form-layer.php'; + ob_end_clean(); + + return $GLOBALS['rtgodam_stub']['shortcodes']; + } + + /** A plain numeric id still builds the same shortcodes as before. */ + public function test_numeric_id_builds_the_expected_shortcodes() { + $this->assertSame( array( "[ninja_form id='42']" ), $this->render_preview( 'ninja-forms', '42' ) ); + $this->assertSame( array( "[metform form_id='42']" ), $this->render_preview( 'metform', '42' ) ); + } + + /** Anything after the leading digits never reaches the shortcode. */ + public function test_non_numeric_id_reaches_the_shortcode_as_an_integer() { + $value = "7'][gd1_marker]x"; + + $this->assertSame( array( "[ninja_form id='7']" ), $this->render_preview( 'ninja-forms', $value ) ); + $this->assertSame( array( "[metform form_id='7']" ), $this->render_preview( 'metform', $value ) ); + } + + /** An id with no leading digits becomes 0 and renders nothing. */ + public function test_id_without_digits_renders_no_shortcode() { + $this->assertSame( array(), $this->render_preview( 'ninja-forms', "'][gd1_marker]" ) ); + $this->assertSame( array(), $this->render_preview( 'metform', "'][gd1_marker]" ) ); + } + + /** The callbacks also cast on their own, for callers other than the template. */ + public function test_callbacks_cast_a_string_id_when_called_directly() { + $ninja = ( new \ReflectionClass( Ninja_Forms_Integration::class ) )->newInstanceWithoutConstructor(); + $metform = ( new \ReflectionClass( Metform_Integration::class ) )->newInstanceWithoutConstructor(); + + $ninja->render_layer_form_for_video_editor( 'ninja-forms', "9'][gd1_marker]" ); + $metform->render_layer_form_for_video_editor( 'metform', "9'][gd1_marker]" ); + + $this->assertSame( array( "[ninja_form id='9']", "[metform form_id='9']" ), $GLOBALS['rtgodam_stub']['shortcodes'] ); + } +} diff --git a/tests/stubs/form-layer-preview-functions.php b/tests/stubs/form-layer-preview-functions.php new file mode 100644 index 000000000..e9739c18b --- /dev/null +++ b/tests/stubs/form-layer-preview-functions.php @@ -0,0 +1,64 @@ +