So, I have written a piece of code after getting some help from SO and internet. I want to add a fees to the cart by calculating the distance between the vendor's location (billing_city) and customer's area via Google Maps API Distance-Matrix. Here, I use a dropdown after billing form to get the area of customer.
I am having problem of getting the value from cookies and pass the variable to next function. FYKI, I have inserted this code into my child theme functions.
add_action( 'wp_footer', 'calculate_distance_between_two_locations' );
function calculate_distance_between_two_locations($dist) {
// I am getting first item of the cart
foreach( WC()->cart->get_cart() as $cart_item ){
$product_id = $cart_item['product_id'];
break;
}
//Now I am fetching vendor's id and location of the item
$vendor_id = get_post_field( 'post_author', $product_id );
$vendor_location = get_user_meta($vendor_id, 'billing_city', true);
//Here I'm fetching the value from customer location
//I am using a dropdown/select named billing_myfield5
if (is_checkout()) {?>
<script type="text/javascript">
jQuery( document ).ready(function( $ ) {
$('#billing_myfield5').change(function(){
jQuery('body').trigger('update_checkout');
var location = $('#billing_myfield5 option:selected').text();
document.cookie="cusarea="+location;
});
});
</script>
<?php
}
//Encoding the customer's location for Google API
//and putting it into a variable
$customer_area = rawurlencode($_COOKIE ['cusarea']);
//I am setting Google API
$shippingurl = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=".$vendor_location."&destinations=".$customer_area."&key=MY_API_KEY";
//Now fetching json response from googleapis.com:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $shippingurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = json_decode(curl_exec($ch), true);
//If google responds with a status of OK
//Extract the distance text:
if($response['status'] == "OK"){
$dist = $response['rows'][0]['elements'][0]['distance']['text'];
}
//Getting the integers from the string
$dist_ance = preg_replace("/[^0-9\.]/", '', $dist);
//Finally putting the value in session
session_start();
$_SESSION['dist'] = $dist_ance;
}
So, now I should have a value in $_SESSION['dist']and I should be able to pass it to another function in same page. Here's the code I am using to calculate the cart fees.
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
function woo_add_cart_fee( $cart ){
if ( ! $_POST || ( is_admin() && ! is_ajax() ) ) {
return;
}
if($_SESSION['dist']){
$customshipcost = $dist_ance;
if ( is_admin() && ! defined ( 'DOING_AJAX' ))
WC()->cart->add_fee('Distance Delivery Charge', $customshipcost , true);
}
}
Well, I am having two problems actually. Any help would be really appreciated.
Sometimes I get the value from cookie, sometimes I don't. I use echo
to check whether it's giving me the value or not.
The session is not responding. I get a '0' as fees in my cart.
FYKI, I am just trying to show only numerical distance as fees in cart right now.
Here is the correct way to get the selected location value in the woocommerce_cart_calculate_fees action hook. I have moved all php code in this hooked function.
In a custom function hooked in woocommerce_after_checkout_form action hook, I have added your revised jQuery code.
I have test everything (but not the google API part and the distance calculation fee) and it works live: Each time a value is selected, it is updated in the fee function.
Here is the code:
add_action( 'woocommerce_after_checkout_form', 'custom_checkout_jquery_script', 10 );
function custom_checkout_jquery_script() {
// Setting the country in customer data and session
$country_code = 'BD'; // For Bangladesh
WC()->session->set( 'country', $country_code );
WC()->session->set( 'billing_country', $country_code );
WC()->session->set( 'shipping_country', $country_code );
WC()->customer->set_billing_country( $country_code );
WC()->customer->set_shipping_country( $country_code );
// The jQuery code
?>
<script type="text/javascript">
(function($){
// Initializing (get the default value)
var location = $('#billing_myfield5 option:selected').html();
document.cookie="cusarea="+location;
// To test the default location output in browser console dev tools
console.log('Selected Area: '+location);
// Get the live value when selected
$( 'form.checkout' ).on( 'change', '#billing_myfield5', function(){
location = $('#billing_myfield5 option:selected').html();
document.cookie="cusarea="+location;
$('body').trigger('update_checkout');
// To test the selected location output in browser console dev tools
console.log('Selected Area: '+location);
});
})(jQuery);
</script>
<?php
}
add_action( 'woocommerce_cart_calculate_fees', 'distance_shipping_fee', 10, 1 );
function distance_shipping_fee( $wc_cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if( empty($_COOKIE ['cusarea']) ) return; // Waiting for the selected area (cookie)
else $cookie = $_COOKIE ['cusarea'];
// Encoding the customer's location for Google API
$customer_area = rawurlencode( $cookie );
// I am getting first item of the cart
foreach( $wc_cart->get_cart() as $cart_item ){
$product_id = $cart_item['product_id'];
break;
}
// Get the vendor's id and location
$vendor_id = get_post_field( 'post_author', $product_id );
$vendor_location = get_user_meta($vendor_id, 'billing_city', true);
// Setting Google API URL ##
$gapi_key = "MY_API_KEY"; // Set HERE your google api key
$shippingurl = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=$vendor_location";
$shippingurl .= "&destinations=$customer_area&key=$gapi_key";
// Now fetching json response from googleapis:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $shippingurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = json_decode(curl_exec($ch), true);
// If google responds with a status of OK: Extract the distance text:
if($response['status'] == "OK")
$dist = $response['rows'][0]['elements'][0]['distance']['text'];
// Getting the integers from the string
$distance = preg_replace("/[^0-9\.]/", '', $dist);
if( $distance > 0 ){
$customshipcost = $distance;
// Displaying the selected location in the fee label
$wc_cart->add_fee( "Distance Delivery fee ($cookie)", $customshipcost , true);
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
All code is tested on Woocommerce 3+ and works.
This will solve your coockie and session problem
Related
I hope I am not expecting too much. Any help would be extremely useful for me, because I am stuck for days now.
I created a relatively simple wordpress plugin in php.
What is the plugin supposed to do ?
-The plugin is supposed to communicate with external api and import product data in json file.
Import is started by pressing "start import" button that is created by pluin in the wordpress menu - import products.
Example request:
curl -X GET
-H 'X-Api-Key: [api-key]'
https://example.com/products/[PRODUCT ID]
[PRODUCT ID] is supposed to range from 1 to 10000
Plugin receives json file with product feed for every single request - every single [PRODUCT ID]
Plugin creates a woocommerce product and attaches imported information.
Does the plugin work ?
Yes and no, It imports first 100 products (in about 1min) correctly and then it just stops, sometimes resulting in error related to the request taking too much time to finish.
I know that the plugin doesn't work because the import script is executed in the browser and gets timed out.
I also know that I should do this process in the background, split it into batches and queue execution. The thing is I tried many ways to do so but failed miserably.
I have composer and action scheduler installed.
Unfortunately everytime I try to split this into batches, use action scheduler It just doesn't work or imports first product and stops.
I know that I'm dealing with large amount of products, I don't have error handling, checking if imported product exists etc, but I really have to run this import once
so there is no need to make this plugin very refined. This has to run, import products and I can get rid of it.
I do have wp debug on, so my attepmts on using action scheduler didn't create any errors or fatal errors, but it just didn't work properly.
I have 1500MB Ram available, this is shared hosting server, I/O 1MB, 60 available processes, 88000/600000 Inodes used, 5/200GB disc space used.
I increased php maxExecutionTime to 3000, memorylimit 1536M, maxInputTime 3000, but that didn't change anything.
I'm attaching my working code below. This is the version without my poor attemts on using action scheduler, splitting it into batches and running it in the backgroud.
I feel like this is going to be easier to read.
This code below runs in the web browser and works, but gets timed out.
I will be extremely grateful for any help with running it in the background.
Is it possible to just run this script from SSH linux terminal so it doesn't get timed out ?
`
<?php
/**
* Plugin Name: Product Importer
* Description: Imports products from an external API
* Version: 1.0
* Author: me
* Author URI: http://www.example.com
*/
// Include the Autoscheduler library
require_once '/home/user/vendor/woocommerce/action-scheduler/action-scheduler.php';
add_action('admin_menu', 'add_import_button');
function add_import_button() {
add_menu_page('Import Products', 'Import Products', 'manage_options', 'import_products', 'import_products_page');
}
function import_products_page() {
echo '<h1>Import Products</h1>';
echo '<form method="post">';
echo '<input type="submit" name="start_import" value="Start Import">';
echo '</form>';
if (isset($_POST['start_import'])) {
import_function();
}
}
function import_function() {
$product_id = 1;
while($product_id < 10000){
$product_id++;
$api_key = 'my-api-key';
$headers = array(
'X-Api-Key: ' . $api_key,
);
$url = 'https://example.com/products/';
$product_url = $url . $product_id;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $product_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$product_data = json_decode($response, true);
// post array etc
// Set other product data as required.
}
}
}
`
One of the ways to solve this issue is using recursion where the code can run in the background. Take a look at the example below
require_once '/home/user/vendor/woocommerce/action-scheduler/action-scheduler.php';
add_action('admin_menu', 'add_import_button');
function add_import_button() {
add_menu_page('Import Products', 'Import Products', 'manage_options', 'import_products', 'import_products_page');
}
function import_products_page() {
echo '<h1>Import Products</h1>';
echo '<form method="post">';
echo '<input type="hidden" name="product_id" value="1">'; // optional
echo '<input type="submit" name="start_import" value="Start Import">';
echo '</form>';
if (isset($_POST['start_import'])) {
import_function();
}
}
// AJAX function
add_action( 'wp_ajax_nopriv_import_function', 'import_function' );
add_action( 'wp_ajax_import_function', 'import_function' );
function import_function() {
$product_id = ( ! empty( $_POST['product_id'] ) ) ? $_POST['product_id'] : 1;
$url = 'https://example.com/products/';
$args = array(
'headers' => array(
'Content-Type' => 'application/json',
'X-Api-Key' => 'apikey12345'
)
);
// this call the function and return the body
$results = wp_remote_retrieve_body(wp_remote_get($url . $product_id, $args));
// convert to array
$results = json_decode( $results );
// Stop the code execution on this conditions
if( ! is_array( $results ) || empty( $results ) ){
return false;
}
// Do your product creation here...
$product_id++; // increase $product_id
wp_remote_post( admin_url('admin-ajax.php?action=import_function'), [
'blocking' => false, // needed for the script to continue running on the background
'sslverify' => false, // needed if working on localhost.
'body' => [
'product_id' => $product_id
]
] );
}
OK, I managed to get it to work. I assume that it's dumb way to do this, but since it works it's fine for me. The only thing that is problematic now is the fact that the code for image import that I used previously (when code ran in browser) now makes the plugin stuck. Without it it works great and fast. Here is my current code:
<?php
/**
* Plugin Name: Product Importer
* Description: Imports products from an external API
* Version: 3.0
* Author: me
* Author URI: http://www.example.com
*/
register_activation_hook( __FILE__, 'schedule_import' ); //plugin starts when activated, fine for me
function schedule_import() {
wp_schedule_single_event( time(), 'import_products' );
}
add_action( 'import_products', 'import_function' );
function import_function() {
$batch_size = 50; //when split into batches it worked faster than one products after another, so ok
$batch_delay = 60; //give it some time to finish batch, to avoid problems
$last_imported_product_id = get_option( 'last_imported_product_id', 1 ); //need it for incrementation and rescheduling
$api_key = 'apikey123456789';
$headers = array(
'X-Api-Key: ' . $api_key,
);
$url = 'https://example.com/products/';
for ( $i = 0; $i < $batch_size; $i++ ) {
$product_id = $last_imported_product_id + $i;
$product_url = $url . $product_id;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $product_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$product_data = json_decode($response, true);
$post = array(
'post_title' => $product_data['name'],
'post_content' => $product_data['description'],
'post_status' => 'publish',
'post_type' => 'product',
'meta_input' => array(
'_virtual' => 'yes',
'_regular_price' => $product_data['price'],
),
);
$post_id = wp_insert_post($post);
update_post_meta($post_id, '_sku', $product_data['Id']);
wp_set_object_terms($post_id, 'external', 'product_type');
$external_url = 'https://example.external.url';
update_post_meta( $post_id, '_product_url', $external_url );
update_option( 'last_imported_product_id', $product_id + 1 ); //incrementation of product_id for rescheduling
wp_schedule_single_event( time() + $batch_delay, 'import_products' ); //rescheduling
}
}
This above works well. However when I add my old code for image imports it imports nothing or 1 product (without image lol) and becomes stuck. After a minute it imports the same product over and over again. Old code for image import:
// Get the product images
$images = $product_data['images']['screenshots'];
$image_ids = [];
foreach ($images as $image) {
// Download the image
$image_url = $image['url'];
$response = wp_remote_get($image_url);
if (is_array($response)) {
$image_data = $response['body'];
$filename = basename($image_url);
$file_array = array(
'name' => $filename,
'tmp_name' => download_url($image_url),
);
// Insert the image into the media library
$attach_id = media_handle_sideload($file_array, $post_id);
if (!is_wp_error($attach_id)) {
array_push($image_ids, $attach_id);
}
}
// Set the product image gallery
update_post_meta($post_id, '_product_image_gallery', implode(',', $image_ids));
// Set the product featured image
update_post_meta($post_id, '_thumbnail_id', $image_ids[0]);
And no, I don't put it after rescheduling, but after $post array.
Honestly no idea why it would crash, tried smaller batches, longer wait between batches etc. I assume the code for images import is just very poorly written. Any solutions for this problem are going to be very appreciated ! :)
PS: I am totally fine with importing the first image available (there is around 6) and setting it up as thumbnail for product. I can give up on the gallery since It's going to slow down the process anyway.
EDIT: here is the fragment of json file received from api. (for better context of importing images):
"images":{
"screenshots":[
{
"url":"https://example.jpg",
"thumbnail":"https://example.jpg"
},
{
"url":"https://example.jpg",
"thumbnail":"https://example.jpg"
},
{
"url":"https://example.jpg",
"thumbnail":"https://example.jpg"
etc....
I use the following code in my functions.php to redirect my WooCommerce 'order received' page to an custom URL:
// Redirect WooCommerce Order Received Page to Post
add_action( 'woocommerce_thankyou', 'rwl_redirectcustom');
function rwl_redirectcustom( $order_id ){
$order = wc_get_order( $order_id );
$url = 'https://my-website.com';
if ( ! $order->has_status( 'failed' ) ) {
wp_safe_redirect( $url );
exit;
}
}
Now I want to redirect instead to an static URL 'https://my-website.com' to a dynamic URL which is stored in an ACF field called 'paywall_post_url' of a post.
I have tried this
$url = get_permalink( get_post_meta( 'paywall_post_url' ) );
But this didn't worked. Where is my mistake?
Thanks
get_post_meta() requires you to pass the post ID and meta key.
you want to use the acf function get_field()
$url = get_permalink( get_field( 'paywall_post_url' ) );
this is if you saved the field as a post ID. otherwise it should be:
$url = get_field( 'paywall_post_url' );
This is the WordPress php code I am planning to implement. The code is a plugin that post a form data to external Api. The plan is I want the success response to be displayed on WordPress Front-end using shortcodes. Currently i don't have an external api to test it but i am also not if this the right way to get what i want so is it? Thanks in advance.
add_action('wpforms_process_complete', 'wpairform_api_sender', 10, 4);
function wpairform_api_sender($fields, $entry, $form_data, $entry_id)
{
//if form ID is 1
if ($form_data['id'] == 10240) {
$api_url = 'https://hook.integromat.com/tzeseygrctyxjbsxfp7psbbkt40j8tc2';
$body = array(
'text' => $fields['1']['value'],
);
$response = wp_remote_post($api_url, array('body' => $body));
if( is_wp_error( $response )){
$error_message = $response->get_error_message();
return "Something went wrong: $error_message";
}
if( 200 !== wp_remote_retrieve_response_code( $response )){
return;
}
if (200 === wp_remote_retrieve_response_code( $response )) {
//$response_body = wp_remote_retrieve_body( $response );
//var_dump($response_body->message);
function github_issues_func($atts)
{
return wp_remote_retrieve_body($response);
}
add_shortcode("github_issues", "github_issues_func");
}
}
}
If all you want to do is to get that response from the API and show it on your Front End, you can save that in a transient instead of generating a shortcode each time the form runs, you can read more about transients here
Wordpress version 4.7.5
I am signing up new users from Instagram, I am successfully able signup the new user. after signup I am trying to logged in the user.
I can use hook, but would like better solution than the dirty one, I
have posted as that will be totally unuseful .
if( $user_created ) {
$new_user = get_user_by( 'id', $user_created );
//$loggedin = programmatic_login( $new_user->user_login );
//ob_start();
if ( !is_user_logged_in() ) {
wp_clear_auth_cookie();
wp_set_current_user( $user_created, $new_user->user_login );
wp_set_auth_cookie( $user_created, true );
do_action( 'wp_login', $new_user->user_login );
// wp_safe_redirect(site_url() . '/profile/');
// exit;
// $redirect_to=user_admin_url();
// wp_safe_redirect($redirect_to);
// exit();
}
//ob_end_clean();
} ?>
<script>jQuery(document).ready(function(){ window.location.href = "<?php echo site_url() . '/profile/'; ?>";});</script> <?php
also tried with a custom programmatic_login function from another post.
if I am trying to var_dump wp_get_current_user() and $_COOKIE below this, I am getting user object for wp_get_current_user() and array(1) { ["wordpress_test_cookie"]=> string(15) "WP Cookie check" } for $_COOKIE .
Important Edit
The code is inside a function, which is hooked to a hook, that is called in side a page that is after header is getting displayed, so we could not use init here. any other way of doing it and also because of this wp_safe_redirect() or header('Location: ') also not working .
Important Update with what I have just tried
A dirty work around
when I created the user from Instagram login, After successful creation I redirected the user to a page with get parameter something like ?user_id=$inserted_id and on wp hook, I tried to get the GET['user_id'] and logged it and it worked, trying to find a proper solution.
if ( $wpdb->insert_id ){ //that is registration with instagram
?>
<script>jQuery(document).ready(function(){ window.location.href = "<?php echo get_bloginfo('url') . '/profile/?id=' . $wpdb->insert_id; ?>";});</script>
<?php
}
and then
add_action( 'wp', 'login_current_user' );
function login_current_user(){
if ( is_page() && get_the_id() == 863 ){
if ( isset( $_GET['id'] ) ){
if ( !is_user_logged_in() ) {
$user_id = $_GET['id'];
$user = get_user_by( 'id', $user_id );
wp_clear_auth_cookie();
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id, true );
do_action( 'wp_login', $user->user_login );
if ( is_user_logged_in() ){
$redirect_to=site_url() . '/profile';
wp_safe_redirect($redirect_to);
exit();
}
}
}
}
}
Proble with dirty trick. If the id we are passing as get parameter
exists in wp_users table then with no verification that will be logged
in .
Update
I created a user_meta before redirecting to profile page and after verification login the user and removed the usermeta, just like an OTP . Trying to make it better if possible.
Below the code:-
if ( $wpdb->insert_id ){ //that is registration with instagram
$temporary_token = sha1(rand());
update_user_meta( $wpdb->insert_id, 'temporary_token', $temporary_token);
?>
<script>jQuery(document).ready(function(){ window.location.href = "<?php echo get_bloginfo('url') . '/profile/?id=' . $wpdb->insert_id . '&token=' . $temporary_token; ?>";});</script>
<?php
}
and then
add_action( 'wp', 'login_current_user' );
function login_current_user(){
if ( is_page() && get_the_id() == 863 ){
if ( isset( $_GET['id'] ) ){
if ( !is_user_logged_in() ) {
$user_id = $_GET['id'];
$user = get_user_by( 'id', $user_id );
if ( $_GET['token'] == get_user_meta( $user_id, 'temporary_token', true ) ){
delete_user_meta( $user_id, 'temporary_token', $_GET['token'] );
wp_clear_auth_cookie();
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id, true );
do_action( 'wp_login', $user->user_login );
if ( is_user_logged_in() ){
$redirect_to=site_url() . '/profile';
wp_safe_redirect($redirect_to);
exit();
}
}
}
}
}
}
If headers have been sent before wp_clear_auth_cookie() or wp_set_auth_cookie() are called then neither will work as both rely on PHP's setcookie function. The after_setup_theme action will occur before headers have been sent so hooking that and setting the cookies there should fix the issue.
function myPlugin_createUser(){
// Probably need to put code that creates user here too otherwise $user_created will never return true
if( $user_created ) {
$new_user = get_user_by( 'id', $user_created );
if ( !is_user_logged_in() ) {
wp_clear_auth_cookie();
wp_set_current_user( $user_created, $new_user->user_login );
wp_set_auth_cookie( $user_created, true );
do_action( 'wp_login', $new_user->user_login );
}
}
}
add_action( 'after_setup_theme', 'myPlugin_createUser' );
Update:
If you're outputting view elements before triggering your createUser function it won't work so we need to make sure they run completely independent of each other. Below I've put together a simple example of how to achieve this - to the view we output a link which passes a GET parameter, this parameter is picked up by the plugin and runs the action before anything is rendered allowing us to set the cookie.
my-plugin.php
// Note: you'll need to include a completed version of myPlugin_createUser() function as above for these examples to work
add_shortcode( 'my-plugin', function() {
// I've used a GET request for simplicity- a form + POST request may be more practical for your purposes and will prevent caching issues.
echo "<a href='?my_plugin_login_user=1'>Login</a>";
});
// Check for our GET parameter
if( isset( $_GET['my_plugin_login_user'] ) ) {
// Nothing should be rendered yet as plugin template hasn't even started loading yet so cookies should set fine
add_action( 'plugins_loaded', 'myPlugin_createUser' );
}
page-my-template.php
<div> ...
<?php
do_shortcode( 'my-plugin' );
?>
</div>
Update 2:
If using Instagrams Authentication API the explicit flow outlined https://www.instagram.com/developer/authentication/ (most of the examples used below are taken from there) is probably the best approach. Below I'll give a brief rundown of how you could implement it. Much of it is taken from there with notes added.
Send the user off to https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code
You could include the WordPress user ID as a parameter on the callback URL or if the user hasn't yet been created and you need to maintain state then you'll need to generate a temporary token that you can use later that's been associated with said data or store that data client side if it's not sensitive which is probably easier and better as it doesn't require a user to be logged in to function.
The user will then login
Not much to say about this step - if an error occurs they'll be redirected to http://your-redirect-uri?error=access_denied&error_reason=user_denied&error_description=The+user+denied+your+request
If login is successful the user will be redirected to http://your-redirect-uri?code=CODE
The CODE passed back on the redirect URL we can redeem for an access token.
So from here there's a multitude of ways we can handle it but essentially what we need is an endpoint for the redirect that we have sufficient control over to send HTTP headers before any of the HTTP response body is sent.
Methods of approaching this (not an exhaustive list):
Conditionally hooking on pages Instagram auths are allowed (as in your examples). This has the advantage of not requiring an additional redirect.
Custom page template
External script that manually bootstraps WordPress does what we need, then redirects back in
So now once we've got an endpoint setup we need to redeem the CODEfor an access token. Adapted this snippet from https://gist.github.com/arturmamedov/7f5a90b85a20e06e344ebb88dc898d25
$uri = 'https://api.instagram.com/oauth/access_token';
$data = [
'client_id' => '213esdaedasdasd12...YOUR_CLIENT_ID',
'client_secret' => 'a8b4aaf06c0da310...YOUR_CLIENT_SECRET',
'grant_type' => 'authorization_code',
'redirect_uri' => 'http://www.YOUR_REDIRECT_URL.it', // The exact redirect URL as used previously
'code' => $_GET['code']
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri); // uri
curl_setopt($ch, CURLOPT_POST, true); // POST
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // POST DATA
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // RETURN RESULT true
curl_setopt($ch, CURLOPT_HEADER, 0); // RETURN HEADER false
curl_setopt($ch, CURLOPT_NOBODY, 0); // NO RETURN BODY false / we need the body to return
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // VERIFY SSL HOST false
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // VERIFY SSL PEER false
$result = json_decode(curl_exec($ch));
$result will be an object representation of the JSON response:
{
"access_token": "fb2e77d.47a0479900504cb3ab4a1f626d174d2d",
"user": {
"id": "1574083",
"username": "snoopdogg",
"full_name": "Snoop Dogg",
"profile_picture": "..."
}
}
From here we just create our user/authenticate with WordPress and redirect to the desired page/render the template (no need to redirect if handled via conditional hooks) and restore the page state if needed.
I have a problem.
I'm trying to use an API from import.io for manage automatically the stock of products I reselling.
The API returns a value to me and I use this value to determine if the product is in stock or not.
Each group/category uses a different API (because each group is a different origin shop. This code is only for one category, I need to figure out how to make that works for dev the others).
I created this code and I'm trying to make it work in function.php
I have a custom field that has the url source to each product and I want to use it as a parameter to the api.
After checking which group is the product, it gets the data so I can update the stock.
The problem is that I do not know how to update the stock of WooCommerce in this way :O And I'd like to have that verification was done when the single product page was opened by the customer.
Can someone take a look at my code and give me some suggestions?
Thank you!
$userGuid = "c5ed744c-7c10-46d1-9c43-22c6eef5aaca";
$apiKey = "private";
// Issues a query request to import.io
function query($connectorGuid, $input, $userGuid, $apiKey) {
$url = "https://query.import.io/store/connector/" . $connectorGuid . "/_query?_user=" . urlencode($userGuid) . "&_apikey=" . urlencode($apiKey);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"import-io-client: import.io PHP client",
"import-io-client-version: 2.0.0"
));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array("input" => $input)));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result);
}
//This is a custom field
$url_font = apply_filters('custom_url_font', get_post_meta($post->ID, '_url_font', true));
add_action('woocommerce_before_shop_loop_item_title','category_stock');
function category_stock() {
global $woocommerce,$product, $post;
$post_id = $post->ID;
$groupcat = 608; // category id for the this api
$terms = get_the_terms( $post_id, 'product_cat' ); //get taxonamy of the products
if ( $terms && ! is_wp_error( $terms ) ) :
foreach ( $terms as $term ) {
$catid = $term->term_id;
if($groupcat == $catid) {
$result = query("d9df1137-b402-40ef-b472-35db84684fbe", array(
"webpage/url" => $url_font,//this is the url from the custom field
), $userGuid, $apiKey, false);
if(($result->results[0]->stock)=="INSTOCK")
{
update_post_meta($post->ID, '_stock', '10');
}
else{
update_post_meta($post->ID, '_stock', '0');
}
}
}endif;
}