Создайте мету пользовательского заказа WooCommerce через AJAX на странице благодарности

#php #ajax #wordpress #woocommerce #orders

#php #ajax #wordpress #woocommerce #заказы

Вопрос:

Я пытаюсь использовать update_meta_data через AJAX на странице благодарности WooCommerce, но я застрял.

Вот что у меня есть на данный момент:

     //Following function gets called from the page already

    function renderForm() {
            echo "<script>
            jQuery(document).ready(function() {
                $('body').on('click', '#button', function(){

                    $.ajax({
                         type: 'POST',
                         url: 'https://thepropdrop.com/wp-admin/admin-ajax.php',
                         data: {
                            action: 'create_user_meta'
                         },
                         success: function(textStatus){
                            console.log('Success');
                         },
                        error: function(MLHttpRequest, textStatus, errorThrown){
                            alert('errorThrown');
                        }
                    });
              });
            });

        </script>";
    }

add_action("wp_ajax_create_user_meta", "create_user_meta");
add_action("wp_ajax_nopriv_create_user_meta", "create_user_meta");

function create_user_meta() {
   $order = wc_get_order($order_id);
   $order->update_meta_data('hasAnswered', 'Yes');
   $order->save();
   die();
}
  

Мы будем признательны за любую помощь, которую вы могли бы предоставить.


РЕДАКТИРОВАТЬ — Мой связанный код, который предоставит некоторый контекст:

Вот кнопка на thankyou.php:

 <span class="button gameStart">
        Let's do this
        </span>
        <script>
        jQuery(document).ready(function() {
            $('.gameStart').click(function(event){
              $(this).remove();
              $('.gameHeader').remove();
              $('.gamePage .gameContainer').css('display', 'block');
              $.ajax({
                  type: 'GET',
                  url: '<?php echo admin_url("admin-ajax.php");?>',
                  data: {
                      action: 'CCAjax'
                  },
                  success: function(textStatus){
                     $( '.gameForm' ).prepend( textStatus );
                  },
                  error: function(MLHttpRequest, textStatus, errorThrown){
                      alert(errorThrown);
                  }
              });
          });
        });
        </script>
                <div class="gameContainer">
            <div class="timerWrapper">
                <div id="timer">

                </div>
            </div>
            <div class="gameForm">
                        <h3>Which of the following countries has the largest land mass?</h3>

                        <div id='answerSubmitButton'>Submit answer</div>
            </div>
        </div>
  

Затем functions.php:

 function CCAjax() {
    get_template_part('template-parts/game');
    die();
}
add_action('wp_ajax_CCAjax', 'CCAjax');
  

Затем game.php:

 <?php
renderForm();
?>
  

Теперь вот полная функция формы рендеринга (она извлекает 3 потенциальных ответа из базы данных, а также имеет таймер обратного отсчета, поэтому я не опубликовал все это, я не хотел путать)

 function renderForm() {

    // Fetch contries object
    global $wpdb;
    $results = $wpdb->get_results("select * from ( select *,@curRow :=@curRow   1 as row_number from ( select * from ( select * from wpCountriesDB order by rand() limit 3 )b order by Mass desc )a JOIN (select @curRow :=0)r)x order by RAND()");

    // Create array for answers
    if(!empty($results)) {
        $i = 1;
        foreach ($results as $r) {
            echo "<div class='answerWrapper'>
            <span class='questionNumber'><span>$i</span></span>
            <label class='label' for='radio$i'>".$r->Country."</label>
            <input type='radio' id='radio$i' name='like' value='$r->row_number' />
            </div>";
            $i  ;
        }
    }

    // Display timer and check answer correct
    echo "<script>
        var timeLeft = 3000;
        var elem = document.getElementById('timer');

        var timerId = setInterval(countdown, 1000);

        function countdown() {
            if (timeLeft < 0) {
                clearTimeout(timerId);
                $('#answerSubmitButton').click();
            } else {
                elem.innerHTML = timeLeft   's';
                timeLeft--;
            }
        }

        jQuery(document).ready(function() {
            $('body').on('click', '#answerSubmitButton', function(){
                    var fetchInput = document.querySelector('.answerWrapper input[name='like']:checked');
              var fetchSelected = fetchInput.value;

              if (fetchSelected == 1) {
                        $.ajax({
                             type: 'POST',
                             url: 'ajaxURL',
                             data: {
                                 action: adding_custom_meta
                                },

                             success: function(textStatus){
                                    console.log('Success');
                             },
                             error: function(MLHttpRequest, textStatus, errorThrown){
                                     alert('errorThrown');
                             }
                     });
              } else {
                console.log('incorrect')
              }
          });
        });

    </script>";
}

add_action("wp_ajax_create_user_meta", "create_user_meta");
add_action("wp_ajax_nopriv_create_user_meta", "create_user_meta");

function create_user_meta() {

    $order = wc_get_order($order_id);
    $order->update_meta_data('hasAnswered', 'Yes');
    $order->save();
    die();

}
  

Должен ли я передавать идентификатор заказа в самом начале?

Комментарии:

1. wordpress.stackexchange.com/questions/216140/… Вы это проверяли?

2. but I am stuck — что это значит. Однажды я наступил на эту резинку и застрял… Во-первых, $order = wc_get_order($order_id); в create_user_meta $order_id не определено и поэтому никогда не найдет правильный порядок.

3. Попробуйте $order = wc_get_order($_POST['order_id']); вместо этого. Конечно, это предполагает, что вы отправили идентификатор заказа, чего вы не сделали. data: { action: 'create_user_meta'}, Поэтому вам придется отправить это по адресу. В конечной точке AJAX для WordPress он понятия не имеет, что вы делаете во внешнем интерфейсе (поскольку это общий URL, используемый для всех вызовов AJAX), вам придется сообщить об этом.

4. также плохой практикой является жестко кодировать URL, url: 'https://thepropdrop.com/wp-admin/admin-ajax.php', вместо этого использовать get_admin_url(null, 'admin-ajax.php') или что-то подобное для динамического получения URL. Таким образом, если вы когда-нибудь измените свое доменное имя, вам не придется просматривать весь ваш код, чтобы исправить это.

5. Спасибо обоим, что перезвонили мне. Я просто вручную ввел идентификатор заказа в функцию: $order = wc_get_order(‘354’); и это сработало — все, что мне нужно сделать, это выяснить, как отправить идентификатор заказа

Ответ №1:

Обновление (поскольку вы предоставили некоторый контекст с отсутствующим кодом):

Да, вы должны передать идентификатор заказа в самом начале с вашей страницы благодарности (шаблона).

Вам нужно по-другому переосмыслить свой код, поскольку вы не можете передать идентификатор заказа своей renderForm() функции. Идентификатор заказа необходимо передать через jQuery Ajax вашей Ajax-функции PHP WordPress, которой это необходимо (для добавления к заказу пользовательских метаданных).

Также другая ошибка (2 раза):

 jQuery(document).ready(function() {
  

это должно быть вместо (поскольку вы используете сокращение от jQuery $ ):

 jQuery(document).ready(function($) {
  

или (то же самое) более коротким способом:

 jQuery(function($) {
  

Оригинальный ответ:

В вашем скрипте есть некоторые ошибки и недостающие элементы, такие как идентификатор заказа, которые необходимо передать через jQuery ajax в вашу функцию PHP WordPress / Ajax, которая добавит пользовательские метаданные…

Также вы не предоставляете в своем коде вывод отображаемой кнопки…

Итак, вот полный пример, основанный на вашем пересмотренном коде, который отобразит кнопку на странице получения заказа (thankyou) и добавит пользовательские метаданные к вашему заказу:

 // PHP WordPress AJAX: Add custom meta data to the Order
add_action("wp_ajax_adding_custom_meta", "adding_custom_order_metadata");
add_action("wp_ajax_nopriv_adding_custom_meta", "adding_custom_order_metadata");
function adding_custom_order_metadata() {
    if( isset($_POST['order_id']) amp;amp; $_POST['order_id'] > 0 ){
        update_post_meta(esc_attr($_POST['order_id']), '_has_answered', 'Yes');
        echo json_encode($_POST['order_id']);
    }
    die();
}

// Display a button on thankyou page (  jQuery Ajax script)
add_action( 'woocommerce_thankyou', 'jquery_thank_you_page', 90, 1 );
function jquery_thank_you_page( $order_id ) {
    // Display the button on thankyou page
    echo '<a href="#" class="button alt" id="button">'.__("Update").'</a>';

    // The jQuery script (Ajax)
    ?>
    <script type="text/javascript">
    jQuery(function($) {
        $('body').on('click', '#button', function(e){
            e.preventDefault();
            $.ajax({
                 type: 'POST',
                 url: '<?php echo admin_url("admin-ajax.php");?>',
                 data: {
                    'action': 'adding_custom_meta',
                    'order_id': '<?php echo $order_id; ?>'
                 },
                 success: function(response){
                    console.log(response); // Just for testing
                 },
                error: function(error){
                    console.log(error); // Just for testing
                }
            });
        });
    });
    </script>
    <?php
}
  

Код вводится function.php файл вашей активной дочерней темы (или active theme). Протестировано и работает.

Использование update_post_meta() функции — намного лучшая и более легкая альтернатива, чем вызов экземпляра WC_Order объекта и использование метода after the save() .

Я изменил пользовательский мета-ключ заказа с hasAnswered на _has_answered


На странице «Заказ получен» отображается кнопка (идентификатор заказа возвращается, смотрите в консоли):

введите описание изображения здесь

В базе данных создаются пользовательские метаданные post:

введите описание изображения здесь

Комментарии:

1. Да, как только я переместил второй скрипт (в функции) в шаблон благодарности, он работает!

2. @JamesWaterhouse Настолько идеально, что теперь вам нужно будет выбрать приемлемый ответ между обоими в этой теме.

Ответ №2:

Что-то вроде этого

 function renderForm($order_id) { //add an argument
        echo "<script>
        jQuery(document).ready(function() {
            $('body').on('click', '#button', function(){

                $.ajax({
                     type: 'POST',
                     url: 'https://thepropdrop.com/wp-admin/admin-ajax.php',
                     data: {
                        action: 'create_user_meta',
                        order_id: {$order_id} //add to your request data
                     },
                     success: function(textStatus){
                        console.log('Success');
                     },
                    error: function(MLHttpRequest, textStatus, errorThrown){
                        alert('errorThrown');
                    }
                });
          });
        });

    </script>";
}
  

Затем в вашем обратном вызове AJAX

 function create_user_meta() {
   if(empty($_POST['order_id'])) {
       //return some error message
       die();
   }

   $order = wc_get_order($_POST['order_id']);  //get the id from the request
   $order->update_meta_data('hasAnswered', 'Yes');
   $order->save();
   die();
}
  

Поскольку у меня нет возможности узнать, как вы вызываете renderForm , у меня нет возможности узнать, как ввести в нее идентификатор заказа. Но в какой-то момент это должно быть либо аргументом, либо частью аргумента (в случае шорткода, $attr такого [renderForm order_id=45] как).

Вы также можете использовать что-то вроде

 $order_id = get_the_ID();
  

Или

 $order = get_post();
$order_id = $order->ID;
  

В зависимости от контекста того, как вы используете renderForm , вы, вероятно, не сможете использовать их в обратном вызове AJAX, потому что это новый запрос, поэтому вы теряете весь тот контекст, который был у вас при создании страницы.

Надеюсь, это имеет смысл.

Не тестировалось, но … возможно, это сработает… теоретически так и должно быть.

Комментарии:

1. Спасибо за вашу помощь, приятель — как только я перенес повторный JS-скрипт в шаблон благодарности, он отлично сработал!