De ce funcția 'do_shortcode' a unui plugin poate să nu funcționeze într-o cerere AJAX?
tl;dr: Shortcode-ul Contact Form 7 nu funcționează într-o cerere AJAX când este apelat cu do_shortcode
functions.php
add_action('wp_ajax_ps_get_survey_form', 'ps_get_survey_form');
add_action('wp_ajax_nopriv_ps_get_survey_form', 'ps_get_survey_form');
function ps_get_survey_form() {
echo do_shortcode( '[contact-form-7 id="397" title="Contact form 1"]' );
die();
}
script.js
jQuery(document).ready(function($){
$('#survey-modal').fancybox({
href: ajaxurl,
ajax: {
type : "POST",
data : {action: 'ps_get_survey_form'}
}
});
});
Totuși,
echo do_shortcode( '[contact-form-7 id="397" title="Contact form 1"]' )
returnează chiar string-ul shortcode-ului. Funcționează corect dacă îl pun într-un template.
Am încercat diverse metode (inclusiv lucruri absurde cum ar fi înfășurarea într-un post/aplicarea filtrului the_content, declanșarea manuală a diverselor acțiuni la care se conectează CF7), dar refuză să se transforme într-un formular.
Cum pot depana această problemă?
EDIT
@Kaiser sugerează în mod logic că nu am acces la do_shortcode. Am încercat să verific acest lucru, cu următorul rezultat:
function ps_get_survey_form() {
//include( ABSPATH . 'wp-includes/shortcodes.php' );
//Cauzează eroare fatală: nu se poate redeclara add_shortcode
if ( function_exists( 'do_shortcode ' ) ) {
echo "do_shortcode există";
} else {
echo "do_shortcode nu există"; // acest mesaj este afișat
}
do_shortcode( 'foo' ); // eșuează în tăcere, chiar dacă funcția aparent nu a fost definită
//foo(); // Cauzează eroare fatală așa cum era de așteptat
//echo do_shortcode( '[contact-form-7 id="397" title="contact form 1"]' );
die();
}

WP Ajax rulează atât apeluri publice cât și cele închise prin intermediul admin.php
. Aceasta înseamnă că nu ai acces la întregul mediu wp, cum ar fi do_shortcode()
, care se află în /wp-includes/shortcodes.php
.
Această limitare poate fi depășită (la fel ca și pentru oEmbed). Următorul exemplu poate fi folosit în callback-ul tău AJAX pentru a activa atât handler-ele oEmbed cât și cele pentru shortcode-uri pentru proprietatea \WP_Post::post_content
.
/** \WP_Post $post */
$post = get_post();
/** @var \WP_Embed $wp_embed */
global $wp_embed;
$wp_embed->post_ID = $post->ID;
// shortcode [embed]
$wp_embed->run_shortcode( $post->post_content );
// link-uri simple pe propria linie
$wp_embed->autoembed( $post->post_content );
// Activează shortcode-urile
do_shortcode( $post->post_content );
PROTip: Nu apela niciodată direct echo do_shortcode( '[some-short-code arg="foo"]' );
. Un shortcode este doar un substitut pentru editor. Fiecare shortcode trebuie să aibă un callback asociat. Folosește callback-ul în schimb. Asta te scapă de verificări costisitoare cu Regex.

Răspunsul este să ocolim restricțiile admin-ajax prin gestionarea manuală, așa cum sugerează @OneTrickPony.
add_action( 'init', function() {
ps_register_shortcode_ajax( 'ps_get_survey_form', 'ps_get_survey_form' );
} );
function ps_register_shortcode_ajax( $callable, $action ) {
if ( empty( $_POST['action'] ) || $_POST['action'] != $action )
return;
call_user_func( $callable );
}
function ps_get_survey_form() {
echo do_shortcode( '[contact-form-7 id="397" title="formular de contact 1"]' );
die();
}
