Создавайте мета-заказ WooCommerce с помощью AJAX на странице благодарности - PullRequest
0 голосов
/ 03 марта 2019

Я пытаюсь использовать 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();

}

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

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

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

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

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

Еще одна ошибка - (2 раза) :

jQuery(document).ready(function() {

, которые должны быть вместо (поскольку вы используете JQuery Shorttand $) :

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

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

jQuery(function($) {

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

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

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

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

// 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']) && $_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 вашей активной дочерней темы (или активнойEME). Протестировано и работает.

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

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


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

enter image description here

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

enter image description here

0 голосов
/ 03 марта 2019

Примерно так:

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, потому что это новый запрос, поэтому вы потеряете любой из этого контекстау вас было при создании страницы.

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

Не проверено, но ... возможно, это будет работать ... должно быть в теории.

...