Netty Admin
asked on
Wordpress - Javascript - JQuery - AJAX - PHP - need assitance with scripts
Need assistance pulling the whole user object from WordPress and also have a question about where I should put my last JavaScript for this process.
ASKER
{
"id": 438,
"date_created": "2020-06-25T09:53:56",
"date_created_gmt": "2020-06-25T13:53:56",
"date_modified": "2020-06-25T09:53:56",
"date_modified_gmt": "2020-06-25T13:53:56",
"email": "testingwebhook@email.com",
"first_name": "testing",
"last_name": "newwebhookdata",
"role": "subscriber",
"username": "customer1593093203",
"billing": {
"first_name": "testing",
"last_name": "newwebhookdata",
"company": "",
"address_1": "4015 Starfish Lane",
"address_2": "",
"city": "Tampa",
"postcode": "33615",
"country": "",
"state": "Florida",
"email": "testingwebhook@email.com",
"phone": "(111) 444-7777"
},
"shipping": {
"first_name": "",
"last_name": "",
"company": "",
"address_1": "",
"address_2": "",
"city": "",
"postcode": "",
"country": "",
"state": ""
},
"is_paying_customer": false,
"avatar_url": "https://secure.gravatar.com/avatar/f2d79",
"meta_data": [
{
"id": 19605,
"key": "entry_id",
"value": "1228"
},
{
"id": 19606,
"key": "_gform-entry-id",
"value": "1228"
},
{
"id": 19615,
"key": "gfID",
"value": "3"
},
{
"id": 19616,
"key": "ServiceRequested",
"value": "Bundle"
},
{
"id": 19617,
"key": "twitter",
"value": ""
},
{
"id": 19618,
"key": "facebook",
"value": ""
},
{
"id": 19619,
"key": "linkedin",
"value": ""
},
{
"id": 19620,
"key": "gplus",
"value": ""
},
{
"id": 19622,
"key": "wc_last_active",
"value": "1593043200"
}
],
"_links": {
"self": [
{
"href": "https://blabla/wp-json/wc/v3/customers/438"
}
],
"collection": [
{
"href": "https://blabla.com//wp-json/wc/v3/customers"
}
]
}
}
^^^This is all the data he wants and in JSON form
ASKER
or he specifically needs the following but would rather have it all if I can give it to him
- firstname
- lastname
- billing address (just address, unless there is address_2 [ste.# apt.#], )
- zipcode
Hi Netty,
That data looks like a WooCommerce Customer, not a WordPress User - they're 2 different objects.
And as for your Javascript, based on our previous conversations, it makes sense to put Javascript in your JS file (the one in your theme folder), and any PHP in your function.php file.
That data looks like a WooCommerce Customer, not a WordPress User - they're 2 different objects.
And as for your Javascript, based on our previous conversations, it makes sense to put Javascript in your JS file (the one in your theme folder), and any PHP in your function.php file.
ASKER
Ok so put the final function that validates the iframe postmessages via the event listener in the same JScript file that I have in the child theme folder?
ASKER
Yes I meant the woocommerce customer data that is pulled with:
wp_get_current_user()
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Chris,
this is the listener we setup before. It does a couple other things that we need to validate and unhide the Place Order button, going to put it in the JScript file we put in the child theme
this is the listener we setup before. It does a couple other things that we need to validate and unhide the Place Order button, going to put it in the JScript file we put in the child theme
window.addEventListener("message", (event) => {
if (event.origin !== "https://api-east.pestpac.com")
return;
let ccInfo = JSON.parse(event.data)
if (ccInfo.BillToID) {
jQuery(document).ready(function($) {
$('#cc_frame').hide().after(`<br><br><br><p>Credit Card Saved Successfully<br><br><br></p>`)
$("#payment #place_order.button.alt").fadeIn('slow')
});
} else if (ccInfo.Error) {
jQuery(document).ready(function($) {
$('#cc_frame').hide().after(`<br><br><br><hr class="redrule"><p style="color:red">Credit card not saved. Blablabla.</p><hr class="redrule"><br><br><br>`)
});
}
}, false);
ASKER
He is asking if I can send it all or if not send just
It would be nice if I had the ability to do either in case he wants to switch back, vice versa
- firstname
- lastname
- billing address (just address, unless there is address_2 [ste.# apt.#], )
- zipcode
It would be nice if I had the ability to do either in case he wants to switch back, vice versa
Hi Netty,
For your listener, you'd want something like this:
For your listener, you'd want something like this:
/**
* Listen for the window.message event
*/
$(window).on('message', function(e) {
if (e.originalEvent.origin !== 'https://api-east.pestpac.com') return;
let ccInfo = e.originalEvent.data
if (ccInfo.BillToID) {
$('#cc_frame').hide().after(`<br><br><br><p>Credit Card Saved Successfully<br><br><br></p>`)
$("#payment #place_order.button.alt").fadeIn('slow')
} else if (ccInfo.Error) {
$('#cc_frame').hide().after(`<br><br><br><hr class="redrule"><p style="color:red">Credit card not saved. Blablabla.</p><hr class="redrule"><br><br><br>`)
}
})
Because we're in jQuery here, you'll want to use originalEvent.data, rather than just event.data
Hey Netty,
How you get your customer info will depend on how your site is setup. Judging by the data you posted earlier, you're dealing with registered customers here, so you can grab their details as long as they're logged into your site.
As for what data you want to send - I would highly recommend you only send the data that is needed for any given operation. The full JSON data you posted ealier contains a lot of information, and most of it is actually useless. If the endpoint just needs firstname, lastname and billing address (including zip code), then just send that. Have a look at this:
How you get your customer info will depend on how your site is setup. Judging by the data you posted earlier, you're dealing with registered customers here, so you can grab their details as long as they're logged into your site.
As for what data you want to send - I would highly recommend you only send the data that is needed for any given operation. The full JSON data you posted ealier contains a lot of information, and most of it is actually useless. If the endpoint just needs firstname, lastname and billing address (including zip code), then just send that. Have a look at this:
/**
* Get the User data
*/
function get_user_data() : array
{
$userId = get_current_user_id();
$customer = new WC_Customer($userId);
$data = [
'FirstName' => $customer->get_first_name(),
'LastName' => $customer->get_last_name(),
'Billing' => $customer->get_billing(),
];
return $data;
}
ASKER
is this line supposed to have a space because "new" is doing something or does it also need an underscore
$customer = new WC_Customer($userId);
That's right as it is. In Object Oriented Programming, we instantiate a class by calling new ClassName(). WP_Customer is the class. The constructor for the class (the ctor) takes the ID as an argument, so we need:
new WC_Customer($userId);
new WC_Customer($userId);
ASKER
ok thank you for explaining it......I am still learning....hopefully by the next month or so I will understand the basics of programming language because I am watching videos and going to follow Harvard's online CS50 class as well so forgive me for not knowing how it works yet and I really appreciate the explanations.
No worries Netty - you're doing great. Stick at it - you'll have plenty of Eureka! moments where something that you've been struggling with will suddenly make perfect sense :)
To be fair - WordPress is not a great example to use when learning development - it does a lot of things in a really weird, non-standard way. As well as that, you're having to figure out programming in PHP (including some OOP) at the same time as learning Javascript, HTML and CSS, so it can be quite a challenge.
To be fair - WordPress is not a great example to use when learning development - it does a lot of things in a really weird, non-standard way. As well as that, you're having to figure out programming in PHP (including some OOP) at the same time as learning Javascript, HTML and CSS, so it can be quite a challenge.
ASKER
for some reason the billing info comes back with nothing in the fields
ASKER
the current user works with wp though and gets the user info but not pulling the billing.
ASKER
all the billing fields come back but with no data in fields
ASKER
I tried replacing this
$userId = get_current_user_id();
with this$userId = get_current_user();
ASKER
If I cannot figure this out soon then I am going to revert to the first solution that give this result and he is going to have to pull the rest of the needed data with another call on the backend because today is the deadline on this part and we are having a meeting about it soon....I haven't even got a valid test url to test the listener yet either so I am hoping the event listener will work as we have it
I really appreciate your help....lmk if there is a way we can figure out why the billing data is not getting pulled
I really appreciate your help....lmk if there is a way we can figure out why the billing data is not getting pulled
ASKER
also, I had him put a test valid URL in the response and the event listener does not seem to be working
ASKER
you sure we would set ccInfo to e.originalEvent.data ??
We do not get that info back from the third party until after the CC in inputted.
We do not get that info back from the third party until after the CC in inputted.
OK.
Couple of points - if you're getting Cannot read property 'secureUrl' of undefined, then the Curl request is not returning any valid data. You'll need to log that and see what's coming back from your Curl request. I'm guessing something has changed, because you had this part working previously.
As for the WooCommerce customer data - are you using the standard WooCommerce checkout for this. The way it works is that a user registered on your site is logged in and they work there way through the WooCommerce checkout process. This creates a Customer record linked to their User account. By grabbing the UserId of the currently logged in user, we can use that to get at their Customer record. It seems from the data you're dumping that the User doesn't have a standard WooCommerce Customer record, which is why the data is coming back empty. If you're not using the standard WooCommerce process (or the currently logged in user is not the Customer, then you may need to grab the data from the user_meta instead, but that will depend on your setup.
Couple of points - if you're getting Cannot read property 'secureUrl' of undefined, then the Curl request is not returning any valid data. You'll need to log that and see what's coming back from your Curl request. I'm guessing something has changed, because you had this part working previously.
As for the WooCommerce customer data - are you using the standard WooCommerce checkout for this. The way it works is that a user registered on your site is logged in and they work there way through the WooCommerce checkout process. This creates a Customer record linked to their User account. By grabbing the UserId of the currently logged in user, we can use that to get at their Customer record. It seems from the data you're dumping that the User doesn't have a standard WooCommerce Customer record, which is why the data is coming back empty. If you're not using the standard WooCommerce process (or the currently logged in user is not the Customer, then you may need to grab the data from the user_meta instead, but that will depend on your setup.
We do not get that info back from the third party until after the CC in inputted.
Your event listener (message) is only set up to listen for the postMessage event which fires AFTER the CC info has been input, so I'm not sure what you're referring to here.
ASKER
Ok how would I get the zipcode from the user meta? and also the reason I was getting the "cannot read property" error was because he wasn't handing me the response the same way as before.....fixed that and now I have a manual test URL that we are using but the listener is not working and displaying the "Credit Card Saved Successfully" message or the "Credit card not saved" message
ASKER
as for now my concern is to get the listener working.. Any suggestions on how to debug this part or try something else
Something else to check on - make sure you've removed the original event listener that you'd added in your snippets plugin. By putting it in the JS file, you should no longer include it in the snippets plugin
ASKER
yes it has been disabled from the snippets
For debugging the event listener, just dump the response get and see what that contains:
/**
* Listen for the window.message event
*/
$(window).on('message', function(e) {
console.log("MESSAGE DATA", e)
if (e.originalEvent.origin !== 'https://api-east.pestpac.com') return;
...
}
Look at your console and see what comes after the MESSAGE DATE bit.
In particular, pay attention to either data.origin or originalEvent.origin and make sure the remote server URL hasn't change. If it's not exactly as your if() statement, then the function will just quit before handling the data.
ASKER
it is not logging anything for that
ASKER
jQuery( function( $ ) {
$(document).ready( function() {
/**
* AJAX Call to grab the Order URL from the server via the custom url created in Azure logics
*/
$( document.body ).on( "click", "#payment #get_cc_order_url.get_cc_order_url", function(e) {
e.preventDefault();
$.ajax({
url : ccOrderParams.url,
data : {
action : 'get_order_url',
security : ccOrderParams.nonce,
},
type : 'post',
}).done(function(response) {
$('#cc_card_iframe').prop('src', response.data.secureURL)
}).fail(function(error) {
console.log("ERROR", error)
})
});
$(window).on('message', function(e) {
if (e.originalEvent.origin !== 'https://api-east.pestpac.com') return;
console.log("MESSAGE DATA", e)
let ccInfo = e.originalEvent.data
if (ccInfo.BillToID) {
$('#cc_card_iframe').hide().after(`<br><br><br><p>Credit Card Saved Successfully<br><br><br></p>`)
$("#payment #place_order.button.alt").fadeIn('slow')
} else if (ccInfo.Error) {
$('#cc_card_iframe').hide().after(`<br><br><br><hr class="redrule"><p style="color:red">Credit card not saved. blabla.</p><hr class="redrule"><br><br><br>`)
}
})
});
})
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
And put your console.log BEFORE the if() statement. If for some reason the origin doesn't match, then you function will exit before ever running the consol.e.log() line so you'll be left with no output:
$(window).on('message', function(e) {
// see what's coming in first!
console.log("MESSAGE DATA", e)
if (e.originalEvent.origin !== 'https://api-east.pestpac.com') return;
ASKER
ASKER
I need to create that third condition as well.....now that the link is not giving me a postmessage event as I put above because it is timed out it looks much different......so this is def an issue for testing as of now, I am asking him for a new URL now
^^^this is why I am not getting anything in the console.log even before the "if" because this third condition seems not to give a postMessage like the other two conditions
^^^this is why I am not getting anything in the console.log even before the "if" because this third condition seems not to give a postMessage like the other two conditions
We are adding an Event Listener - we're just doing it the jQuery way:
$(window).on('message', function(e) {
...
})
When we originally discussed this, you said there was a message sent when the window timed out - if that doesn't happen then you can't use a listener - there's no event to listen to.
ASKER
ok I got it.....Ok its working now!!!
after I added antoher document ready and put the function under that it worked.
Now two final things......need to add the one more condition and also need to display a small spinning icon a message that says" Retreiving Secure URL" for the time between when the button is clicked and the iframe is displayed
after I added antoher document ready and put the function under that it worked.
Now two final things......need to add the one more condition and also need to display a small spinning icon a message that says" Retreiving Secure URL" for the time between when the button is clicked and the iframe is displayed
ASKER
And is there any way to get the zip code from the user meta?? I have been googling and can not seem to find it
Right - you don't need a second document ready - you should ony have one, and both your functions go inside that:
As for the spinner - the jQuery AJAX method has an beforeSend property that allows you to run some code just before the AJAX call is made - that would be the best place to add some code to insert your spinner:
jQuery( function( $ ) {
$(document).ready( function() {
/**
* AJAX Call to grab the Order URL from the server via the custom url created in Azure logics
*/
$( document.body ).on( "click", "#payment #get_cc_order_url.get_cc_order_url", function(e) {
...
});
/**
* Message listener
*/
$(window).on('message', function(e) {
...
});
})
})
How you get the ZipCode will depend on how your data i sstored in the database. Like I said ealier, it seems that you're not using the standard WooCommerce customer process, so I don't know how you're storing that data. Generally, to get a Users meta data, you do this:$data = get_user_meta( $userId, $key );
But you'd need to know the key (could be zipcode ???) . That is entirely dependent on your own system and how it's set up. I don't know that so I can't give you a specific answer on that.As for the spinner - the jQuery AJAX method has an beforeSend property that allows you to run some code just before the AJAX call is made - that would be the best place to add some code to insert your spinner:
$.ajax({
url : ccOrderParams.url,
type : 'post',
data : {
action: 'get_order_url',
security: ccOrderParams.nonce,
},
beforeSend: function() {
// add in your spinner and please wait code here
},
}).done(function(response) {
// hide your spinner and please wait message here
$("#cc_card_iframe").prop('src', response.data.secureUrl)
}).fail(function(error) {
console.log("ERROR", error)
})
ASKER
cool been trying to find out how to get the zip code......I am going to try this other code and get report back...much appreciated.
ASKER
Success!
no need for the zip code anymore.....we got brand new URLs being returned every time now with the current config......only issue is for some odd reason when the postMessage gives the "Error" attribute for when the customer clicks cancel the "Credit Card Not Saved" message does not appear...…but when a card is entered correctly and postMessage has a "BillToID" attribute the script works fine and displays the "Credit Card Saved Successfully" message
^^^Will not display the Card not saved message
^^^^Does display the "Credit Card Saved Successfully" message correctly
This is really getting to me as it seems to be coded the same as the first message and it is listening for the same postMessage event
no need for the zip code anymore.....we got brand new URLs being returned every time now with the current config......only issue is for some odd reason when the postMessage gives the "Error" attribute for when the customer clicks cancel the "Credit Card Not Saved" message does not appear...…but when a card is entered correctly and postMessage has a "BillToID" attribute the script works fine and displays the "Credit Card Saved Successfully" message
^^^Will not display the Card not saved message
^^^^Does display the "Credit Card Saved Successfully" message correctly
This is really getting to me as it seems to be coded the same as the first message and it is listening for the same postMessage event
ASKER
Ok, I know why one was working and the other wasn't, It is because I had turned back on the snippet and only had one of the iframe ids changed to match the new id and that was the success message.....so it appears using the snippet works but the function inside the child theme jscript is not working at all.
ASKER
Got it working! I know you said that it should not need another jquery document ready but the only way that the console.log dumps data from the postMessage is only if I wrap the function in its own doc ready wrapper...
ASKER
All good on this!!! thank you. I am going to make a new question about the "message while waiting" and spinning icon.….
ASKER
Open in new window