WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10k stars 4.02k forks source link

Shortcodes are executing in backend #45732

Open vijayhardaha opened 1 year ago

vijayhardaha commented 1 year ago

Description

If I am adding a shortcode in shortcode blocks, it's code is executing in the backend, but the shortcode tag should be just raw text in the backend, they should not execute the inner code/query in backend.

Step-by-step reproduction instructions

Steps to reproduce the issue.

  1. Fresh install the WordPress
  2. Create a static homepage
  3. Install the WooCommerce plugin & import dummy data (it's not the woocommerce shortcode issue, for issue testing we use WooCommerce)
  4. Install Query Monitor for tracking
  5. Edit the homepage and on the block, the editor adds a shortcode block and put [products limit=10"]
  6. Save/Update the page
  7. Reload the page and open the query monitor panel
  8. Click the Queries tab, select woocommerce in the component dropdown, and select WP_Term_Query->get_terms() in the Caller dropdown
  9. Look for the SELECT DISTINCT t.term_id, tr.object_id query and expend Caller information, you'll find WC_Shortcodes::products() there

Shortcode code is executing on the backend page which should not happen, If you'll install the classic editor plugin then in the classic editor you'll not see shortcode code execution on the backend.

This current behavior slows down the backend page. for example with a website with 10000 products if someone adds a shortcode [products] by mistake without specifying the limit atts, then the backend will execute the query and the page will either break or load after 1-2 minutes.

Screenshots, screen recording, code snippet

Screenshot 2022-11-12 at 2 58 06 PM

Environment info

### wp-core ###

version: 6.1
environment_type: production

### wp-active-theme ###

name: Twenty Twenty-Three (twentytwentythree)
version: 1.0

### wp-plugins-active (2) ###

Query Monitor: version: 3.10.1, author: John Blackbourn, Auto-updates disabled
WooCommerce: version: 7.1.0, author: Automattic, Auto-updates disabled

### wp-server ###

server_architecture: Darwin 22.1.0 arm64
httpd_software: nginx/1.23.2
php_version: 7.4.33 64bit
php_sapi: fpm-fcgi

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

ocean90 commented 1 year ago

Also reported in https://core.trac.wordpress.org/ticket/57095.

t-hamano commented 1 year ago

I have tested it and I think it is indeed reproducible.

shortcode function:

add_shortcode(
    'test',
    function() {
        return wp_list_categories(array( 'echo' => false, 'include' => 999 ) );
    }
);

Query Monitor result:

shortcode

bobbingwide commented 1 year ago

The problem can be confirmed without any plugins, not even Gutenberg.

  1. Create a new post and add a shortcode such as [caption]This is the caption[/caption]
  2. Open the inspector and look at the Network tab
  3. Check the Preview or Response for the REST request to autosave/ save/ update post ID nn eg wp-json/wp/v2/posts/nn
  4. Look at content.raw and content.rendered.
  5. You'll see that the caption shortcode has been expanded.

image

I've been suffering from this problem for a very long time. Unfortunately, it's the way that the REST API works.

bobbingwide commented 1 year ago

I used my oik-bwtrace plugin to run some ad-hoc tracing against the_content. Attached hooks:

: 0   bw_trace_attached_hooks;9 bw_trace_backtrace;9
: 1   bw_trace_results;9
: 8   WP_Embed::run_shortcode;1 WP_Embed::autoembed;1
: 9   do_blocks;1
: 10   wptexturize;1 wpautop;1 shortcode_unautop;1 prepend_attachment;1 wp_filter_content_tags;1 wp_replace_insecure_home_url;1
: 11   capital_P_dangit;1 do_shortcode;1
: 20   convert_smilies;1
: 9999   bw_trace_results;9

backtrace

0. bw_lazy_backtrace C:\apache\htdocs\wordpress\wp-content\plugins\oik-bwtrace\libs\bwtrace.php:108 0
1. bw_backtrace C:\apache\htdocs\wordpress\wp-content\plugins\oik-bwtrace\includes\bwtrace-actions.php:666 0
2. bw_trace_backtrace(<!-- wp:paragraph -->
<p>Shortcode expanded during save. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>[caption]This is the caption[/caption]</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What can we do to confirm what's happening. trace `the_content`</p>
<!-- /wp:paragraph -->) C:\apache\htdocs\wp55\wp-includes\class-wp-hook.php:308 1
3. apply_filters(<!-- wp:paragraph -->
<p>Shortcode expanded during save. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>[caption]This is the caption[/caption]</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What can we do to confirm what's happening. trace `the_content`</p>
<!-- /wp:paragraph -->,array) C:\apache\htdocs\wp55\wp-includes\plugin.php:205 2
4. apply_filters(the_content,<!-- wp:paragraph -->
<p>Shortcode expanded during save. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>[caption]This is the caption[/caption]</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What can we do to confirm what's happening. trace `the_content`</p>
<!-- /wp:paragraph -->) C:\apache\htdocs\wp55\wp-includes\rest-api\endpoints\class-wp-rest-posts-controller.php:1857 2
5. prepare_item_for_response(object,object) C:\apache\htdocs\wp55\wp-includes\rest-api\endpoints\class-wp-rest-posts-controller.php:949 2
6. update_item(object) C:\apache\htdocs\wp55\wp-includes\rest-api\class-wp-rest-server.php:1171 1
7. respond_to_request(object,/wp/v2/posts/(?P<id>[\d]+),array,unsupported) C:\apache\htdocs\wp55\wp-includes\rest-api\class-wp-rest-server.php:1018 4
8. dispatch(object) C:\apache\htdocs\wp55\wp-includes\rest-api\class-wp-rest-server.php:442 1
9. serve_request(/wp/v2/posts/22) C:\apache\htdocs\wp55\wp-includes\rest-api.php:410 1
10. rest_api_loaded(object) C:\apache\htdocs\wp55\wp-includes\class-wp-hook.php:308 1
11. apply_filters(,array) C:\apache\htdocs\wp55\wp-includes\class-wp-hook.php:332 2
12. do_action(array) C:\apache\htdocs\wp55\wp-includes\plugin.php:565 1
13. do_action_ref_array(parse_request,array) C:\apache\htdocs\wp55\wp-includes\class-wp.php:399 2
14. parse_request() C:\apache\htdocs\wp55\wp-includes\class-wp.php:780 1
15. main() C:\apache\htdocs\wp55\wp-includes\functions.php:1332 1
16. wp C:\apache\htdocs\wp55\wp-blog-header.php:16 0
17. require(C:\apache\htdocs\wp55\wp-blog-header.php) C:\apache\htdocs\wp55\index.php:17 1
bobbingwide commented 1 year ago

The simplest test to demonstrate the_content is being run is to create a post containing Wordpress

The rendered content will have a capital P in WordPress.

ndiego commented 2 weeks ago

I ran into this again today. I'm not sure how easy it would be to fix, but this issue remains. Here's a quick way to test.

Register the following shortcode:

add_shortcode(
    'test',
    function() {
        return echo 'Testing';
    }
);

Add [test] to any post and then save. An error will appear, but the post will actually be saved. Refresh the page, and "Testing" will be echoed.

As previous folks have commented, shortcodes should not be fired at all in the Editor. A temporary solution is to add the following at the beginning of your shortcode callback function, but this is not ideal.

if ( is_admin() ) {
    return;
}

While I am the biggest proponent of custom blocks, there are still situations where shortcodes fill an important role. Fixing this issue would be a big win. I imagine this could also be an Editor performance issue assuming a user has multiple complex shortcodes in a post 🤔