在“谢谢”页面上通过AJAX创建WooCommerce自定义订单元

时间:2019-03-02 21:23:04

标签: php ajax wordpress woocommerce orders

我试图在WooCommerce感谢页面上通过AJAX使用update_meta_data,但是我被卡住了。

这是我到目前为止所拥有的:

    //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();

}

我是否必须一开始就通过订单ID?

2 个答案:

答案 0 :(得分:2)

更新(因为您提供了缺少代码的上下文)

  

是的,您必须从谢谢页面(模板)的最开始处传递订单ID。

您需要重新思考代码,因为您无法将订单ID 传递给renderForm()函数。 需要将订单ID通过jQuery Ajax传递到需要它的PHP Wordpress Ajax函数(将自定义元数据添加到订单中)。

另一个错误是(两次)

jQuery(document).ready(function() {

需要改为(因为您正在使用jQuery shortand $

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

或(相同),简称:

jQuery(function($) {

原始答案:

脚本中存在一些错误和遗漏的东西,例如订单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文件中。 经过测试可以正常工作。

  

使用update_post_meta()函数比调用WC_Order对象的实例并在the save()方法之后使用要好得多,也更轻巧。

     

我已将订单自定义元键从hasAnswered更改为_has_answered


在“收到订单”页面上,显示的按钮(返回订单ID,请在控制台中查看):

enter image description here

在数据库中,将创建自定义帖子元数据:

enter image description here

答案 1 :(得分:1)

类似这样的东西

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,因此我也无法知道如何在其中输入订单ID。但是在某些时候,它必须是参数或参数的一部分(对于短码$attr,例如[renderForm order_id=45])。

您也许还可以使用类似的东西

$order_id = get_the_ID();

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

根据使用renderForm的上下文,您可能无法在AJAX回调中使用它们,因为这是一个新请求,因此您会失去构建页面时所拥有的任何上下文。

希望如此。

未经测试,但是...也许可以工作...理论上应该如此。

相关问题