0

Inside My custom wordpress plugin to translate all posts depending on get_locale() I created a php file that's add_filter() to each post content element.

Ajax requests are called from functions.php and depending php files inside themes folder.

My php code works fine for all page loaded without Ajax. I want to allowed my plugin to be load before all ajax call/request. I don't know if I have to hook wp_ajax_() inside my php plugin or if an other solution exist or if I've forgotten to apply a wp function when I call ajax so that any plugin can be read automatically.

my typical php ajax :

add_action('wp_ajax_nopriv_filter_date', 'filter_ajax_date');
add_action('wp_ajax_filter_date', 'filter_ajax_date');

function filter_ajax_date(){
    "my wp_query"
    wp_reset_query();
    wp_die();
}

When I click on button "date filter" I load posts from other date period using ajax filter_ajax_date function.

At the end of "my code" I tried to use alone : if( wp_doing_ajax() ) {} and with 'add_action' from this code:

add_action( 'admin_init', 'my_ajax_checker', 10, 2);

function my_ajax_checker() {
    if( wp_doing_ajax() ) {
         add_action('plugins_loaded', 'atv_convert_multilingual');
    }
}

No one works.

My code (my-plugin/includes/multilingual-query.php):

function atv_convert_multilingual(){

    if(!is_admin() ){       
        add_filter('the_title','atv_translate_title',10,2);
        add_filter('the_content','atv_translate_content',7);
        add_filter('get_the_excerpt','atv_translate_excerpt',9,2);
        add_filter('get_post_metadata', 'atv_translate_meta_subtitle', 10, 4);
        add_filter('get_post_metadata', 'atv_translate_meta_forwho', 10, 4);
    }

    function atv_translate_lang_post($post_object, $object_id, $whichelement, $metaform = null, $meta_key = null){}

    function atv_translate_title($title, $object_id){
        $whichelement = 'title'; $post_object = $title;
        return  atv_translate_lang_post($post_object, $object_id, $whichelement, null);
    }
}
add_action('plugins_loaded', 'atv_convert_multilingual');

For debugging purposes and to avoid my bad practices, here is the function to retrieve the content of the post/postmeta will be modified using add_filter :

function atv_translate_lang_post($post_object, $object_id, $whichelement, $metaform = null, $meta_key = null){

    if ( 'liste_associations' == get_post_type()) {
        $englishforalllang = 'en_GB';               
        if(get_locale() == 'fr_FR'){
            return $post_object;
        }elseif(get_locale() != 'fr_FR' || get_locale() == $englishforalllang ){
            // For POST meta
            if(isset($meta_key) && $metaform == $meta_key){
                $ifposthasmetalang = '/^_[a-z]{2}_[A-Z]{2}$/'; 
                $meta_id = get_post_meta($object_id);
                foreach($meta_id as $metakey => $metaval){
                    if(preg_match($ifposthasmetalang, $metakey)){
                        if($metakey ==  '_'.$englishforalllang || $metakey != '_'.$englishforalllang ){
                            $datalang = get_post_meta( $object_id, $metakey, true );
                            $langcontent = unserialize(base64_decode($datalang));
                                        
                            $post_object = $langcontent[$whichelement];
                        }
                    }
                }
            }
            // For POST elements
            if(!isset($meta_key) && !isset($metaform)){
                $ifposthasmetalang = '/^_[a-z]{2}_[A-Z]{2}$/'; 
                global $post;
                if($whichelement == 'title' || $whichelement == 'content'){
                     $meta_id = get_post_meta($object_id);
                }elseif($whichelement == 'excerpt'){
                    $meta_id = get_post_meta($post->ID);
                }
                foreach($meta_id as $metakey => $metaval){
                    if(preg_match($ifposthasmetalang, $metakey)){
                        if($metakey ==  '_'.$englishforalllang || $metakey != '_'.$englishforalllang ){
                            if($whichelement == 'title' || $whichelement == 'content'){
                                $datalang = get_post_meta( $object_id, $metakey, true );
                            }elseif($whichelement == 'excerpt'){
                                $datalang = get_post_meta( $post->ID, $metakey, true );
                            }
                            $langcontent = unserialize(base64_decode($datalang));
    
                            $post_object = $langcontent[$whichelement];
                                            
                        }
                    }
                }
            }
            return $post_object;
        }
    }
  }
6
  • note that nesting function definitions the way that last code snippet does is very bad practice and may cause fatal errors in the latest versions of PHP and deprecation errors
    – Tom J Nowell
    Sep 12, 2023 at 14:59
  • also notice that the code you linked to has added that function to multiple hooks, not just admin_init, and carries warnings from high rep users in ]the comments that it would break a lot of things. What are you trying to do that originally lead you to this? Also wp_reset_query should only be used with query_posts which shouldn't be used in 99% of cases.
    – Tom J Nowell
    Sep 12, 2023 at 15:02
  • So must I repeat each add_filter() using conditions of atv_translate_lang_post ? isn't there a best practice that reduces the amount of code required? Because if I decide to remove the nesting of functions as suggested, my code risks becoming extremely long for the use of the same conditions. Can you suggest another way of implementing my code without generating errors?
    – imagIne
    Sep 12, 2023 at 15:38
  • I don't know why you would need the conditions like that, add_action doesn't need to be at the same level as the function declarations, you can define all functions at the top scope level, nesting is never necessary, and you shouldn't need to duplicate it all
    – Tom J Nowell
    Sep 12, 2023 at 16:17
  • I see you're using get_locale to identify the users locale, but how are you setting it? I also see this: if ( 'liste_associations' == get_post_type()) { but this only works if there's a current post set. On an AJAX request there is no context from where the AJAX request was fired from to figure that out either! I'm assuming $post_object is a WP_Post object? If so you could test the posts type that way via something like $post_object->post_type or $post_object->type instead of get_post_type()? And have you confirmed get_locale returns what you expect it to?
    – Tom J Nowell
    Sep 12, 2023 at 16:21

1 Answer 1

0

This will never work:

add_action( 'admin_init', 'my_ajax_checker', 10, 2);

function my_ajax_checker() {
    if( wp_doing_ajax() ) {
         add_action('plugins_loaded', 'atv_convert_multilingual');
    }
}

This is because by the time admin_init runs, plugins_loaded has already happened! Making this code would would require the code to travel backwards in time.

Instead it would be much simpler to do this:

add_action('plugins_loaded', 'atv_convert_multilingual');

Or this:

if( wp_doing_ajax() ) {
     add_action('plugins_loaded', 'atv_convert_multilingual');
}

Take a look at https://www.rarst.net/wordpress/wordpress-core-load/ for more information on the order that hooks fire in WordPress

6
  • Thanks, I already test with your solutions: My code works only for non ajax request using add_action('plugins_loaded', 'atv_convert_multilingual'); . Using this action inside if( wp_doing_ajax() ) {} do nothing and ajax request ignore my plugin translation.
    – imagIne
    Sep 12, 2023 at 15:27
  • then I don't believe this is actually the problem unless you can demonstrate that this function is not running by putting a wp_die in it and not seeing that happen. There is something going on that is not mentioned in your question, code that is missing. plugins_loaded always runs, the only reason your action might not run is if it's added after plugins_loaded has ran. You should update your question with more information and code about how functions like atv_translate_lang_post work, and how you're performing translation as it's difficult if not impossible to debug otherwise
    – Tom J Nowell
    Sep 12, 2023 at 15:30
  • creating my own template, are there any native wordpress functions that need to be added to functions.php so that my theme understands the action of the plugins and more specifically the ajax functions inside functions.php?
    – imagIne
    Sep 12, 2023 at 15:45
  • I understand, I have added atv_translate_lang_post() function.
    – imagIne
    Sep 12, 2023 at 15:48
  • Well, if( wp_doing_ajax() ) { add_action('plugins_loaded', 'atv_convert_multilingual'); }works fine with simple filter of $titleon ajax request. I have a problem with $object_id and to catch post_type as you suggest. yet I have created conditions to retrieve get_locale and post_type from Ajax request but I still stuck to access variable of locale and post_type.
    – imagIne
    Sep 13, 2023 at 17:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.