首页 > 解决方案 > 如何从 js/vue 应用程序执行 WordPress/WooCommerce 功能

问题描述

主要问题是: 我需要根据来自 vue-web-component 应用程序的数据在 WooCommerce 中创建一个新的自定义产品。然后将此产品添加到购物车并使其可购买。
我有一个想法,也许可以在 http 请求上执行 WooCommerce 函数,然后我什至可以通过 cookie 传递整个数据。我知道如何通过 PHP 函数创建新的 WooCommerce 产品,并且我知道如何通过 POST 请求将现有产品添加到购物车。问题是触发一个函数,当在 js-app 中按下“添加到购物车”按钮时,它将从 cookie 或其他方式接收数据。

将现有产品添加到购物车:(可能有用)

async function m_wc_add_to_cart( product_id ) {
    if ( 'undefined' === typeof wc_add_to_cart_params ) {
        // The add to cart params are not present.
        return false;
    }

    var product = new URLSearchParams();
    product.append('product_id', '43');
    product.append('quantity', '1');


    const endpoint = wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add_to_cart' )

    console.log('endpoint', endpoint)

    const config = {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    }

    axios.post(
        endpoint, 
        product,
        config
    )
    .then(function (response) {
        console.log(response);
        added_to_cart(response)         
    })
    .catch(function (error) {
        console.log(error);
    });
}

标签: phpwordpressvue.jswoocommerce

解决方案


我是WordPress新手,但我希望那里不会有任何垃圾↓↓↓</p>

我找到了两个解决方案,如何将新创建的产品添加到 WooCommerce 购物车。其中之一是通过自定义端点的回调,另一种是通过对外部 PHP 文件的 ajax 请求

自定义端点的回调

WordPress 中注册自定义端点时,可以定义一个将在请求后执行的函数:

functions.php:(
在 Wordpress 中注册自定义端点。回调定义了一个函数,该函数在请求后触发)

add_action( 'rest_api_init', function () {
  register_rest_route( 'my_own_namespace', 'my_own_route', array(
    'methods' => 'POST',
    'callback' => 'my_own_function',
  ) );
} );

使用my_own_function我创建了一个新产品并将其添加到购物车(下面的大部分代码来自这个答案):

functions.php:(
通过插入后创建新产品。函数作为回调触发)

function my_own_function(WP_REST_Request $request){

// Via post request I can send data (look at JS-code)
$price = $request['price'];

$post = array(
  'post_author' => $user_id,
  'post_content' => '',
  'post_status' => "publish",
  'post_title' => 'Lorem ipsum...',
  'post_parent' => '',
  // "post_type => product" defines, that this post will be inserted as a product
  'post_type' => "product",
);

$post_id = wp_insert_post( $post, $wp_error );

if($post_id){
$attach_id = get_post_meta($product->parent_id, "_thumbnail_id", true);
add_post_meta($post_id, '_thumbnail_id', $attach_id);
}

wp_set_object_terms( $post_id, 'Races', 'product_cat' );
wp_set_object_terms( $post_id, 'simple', 'product_type');

update_post_meta( $post_id, '_visibility', 'visible' );
update_post_meta( $post_id, '_stock_status', 'instock');
update_post_meta( $post_id, 'total_sales', '1');
update_post_meta( $post_id, '_downloadable', 'yes');
update_post_meta( $post_id, '_virtual', 'yes');
update_post_meta( $post_id, '_regular_price', "1" );
update_post_meta( $post_id, '_sale_price', "1" );
update_post_meta( $post_id, '_purchase_note', "" );
update_post_meta( $post_id, '_featured', "no" );
update_post_meta( $post_id, '_weight', "" );
update_post_meta( $post_id, '_length', "" );
update_post_meta( $post_id, '_width', "" );
update_post_meta( $post_id, '_height', "" );
update_post_meta( $post_id, '_sku', "");
update_post_meta( $post_id, '_product_attributes', array());
update_post_meta( $post_id, '_sale_price_dates_from', "" );
update_post_meta( $post_id, '_sale_price_dates_to', "" );
update_post_meta( $post_id, '_price', $price );
update_post_meta( $post_id, '_sold_individually', "" );
update_post_meta( $post_id, '_manage_stock', "no" );
update_post_meta( $post_id, '_backorders', "no" );
update_post_meta( $post_id, '_stock', "" );

// file paths will be stored in an array keyed off md5(file path)
$downdloadArray =array('name'=>"Test", 'file' => $uploadDIR['baseurl']."/video/".$video);

$file_path =md5($uploadDIR['baseurl']."/video/".$video);


$_file_paths[  $file_path  ] = $downdloadArray;
// grant permission to any newly added files on any existing orders for this product
// do_action( 'woocommerce_process_product_file_download_paths', $post_id, 0, $downdloadArray );
update_post_meta( $post_id, '_downloadable_files', $_file_paths);
update_post_meta( $post_id, '_download_limit', '');
update_post_meta( $post_id, '_download_expiry', '');
update_post_meta( $post_id, '_download_type', '');
update_post_meta( $post_id, '_product_image_gallery', '');

// add newly created product to cart
WC()->cart->add_to_cart( $post_id );
};

最后,我从 js-app 发送一个 http 请求。我在这里使用axios。重要的是将参数作为查询字符串传递(使用URLSearchParams):

footer.php:(
我将脚本放在footer.php文件中。使用 axios 我发送一个带有查询字符串形式的数据的 http 请求):

<script>
  async function runPHP(){
    var args = new URLSearchParams();
    args.append('price', '199');

    axios.post("your_wp_url/index.php/wp-json/my_own_namespace/my_own_route", args)
    .then(function (response) {
      // In case 'my_own_function' returned some value, the response will contain it
      console.log(response)
    })
    .catch(function (error) {
      console.log(error);
    });
  }
</script>

<button onclick="loadDoc()">Via Custom Endpoint</button>

对外部 PHP 文件的 Ajax 请求

另一种解决方案是创建一个带有请求处理程序的 PHP 文件,我们将请求发送到该文件。

我在主题的根文件夹中创建了文件myActions.php,我在其中放置了一个 http 请求处理程序。还有一个 WP 功能,它创建一个新产品并将其添加到 Woo 购物车。注意:要在此文件中使用 WP 功能,您需要加载 wp-load.php 文件

myActions.php:(
新创建的带有请求处理程序的文件。要使 WP 功能可用,需要加载 wp-load.php 文件):

    //  wp-load.php makes WP functions available in this file
    define( 'WPPATH', dirname(dirname(dirname(dirname(__FILE__)))) . '/wp-load.php' );
    require_once(WPPATH);

    function my_own_function($price){
        //... almost the same as in the previous example previous
    }

    if(isset($_POST['action']) && !empty($_POST['action'])) {
        $action = $_POST['action']; // action is past as a POST request prop
        $price = $_POST['price']; // same happens with optional arguments
        switch($action) {
            case 'test' : my_own_function($price);break;
        }
    }

接下来,在 js-app 中,我通过 axios 发送一个 http 请求:

footer.php:(
我向文件myActions.php发送一个 http POST 请求。在 props 中,我传递了一个函数名和可选参数):

    <script>
        // Here I define a path to 'myActions.php' file
        const myActionsUrl = '<?php echo get_template_directory_uri() ?>'+'/myActions.php'

        var params = new URLSearchParams();
        params.append('action', 'my_own_function');
        params.append('price', '199');

        async function runPHP(){
            axios.post(myActionsUrl, params)
            .then(function (response) {
                console.log(response)
            })
            .catch(function (error) {
                console.log(error);
            });
        }
    </script>

    <button onclick="runPHP()">Run myActions!</button>

推荐阅读