Link to home
Start Free TrialLog in
Avatar of Netty Admin
Netty AdminFlag for United States of America

asked on

Help with Custom PHP script for Woocommerce Checkout page on WordPress site.

PHP Script: Trying to pull a custom URL from the backend of our wordpress database and have it displayed in an iFrame in a particular field on our woocommerce checkout page. I have it working but it is not consistent and I am using a “filter” but I believe it requires as “action” Maybe would be better to also create a button that initiates the iframe.


This is the current working script. I do not know anything about PHP or WordPress, I have just been tasked to get this to work:

add_filter('woocommerce_checkout_get_value', function($input,$key){
      
      $current_user = get_current_user_id();
      switch ($key):
      case 'order_custom_url_input';
      $url = get_user_meta($current_user,'order_url_string',true);
    echo '<iframe ... src="'.urldecode($url).'"></iframe>';
      return $url;
      endswitch;
      
},10,2);


What I did here was create a custom field for the checkout page with ID "order_custom_url_input" and this script grabs the custom URL from the backend (which is provided by a third party credit card processor) and it then populates the input field and echos an iFrame above it. It seems to work with some browsers and systems but not all and not all the time. I belive it can be written a different way with an "action" and without the need for it to populate the custom input field I made.
Avatar of Netty Admin
Netty Admin
Flag of United States of America image

ASKER

Also this method has the URL displayed in the input field underneath the iFrame which is not a clean looking layout. I attempted to add a custom css class to the order_custom_url_input and then a custom CSS element to give the field zero opacity and it seems to work from within the wpadmin dashboard but then it seems to disappear the iFrame in other browsers.

.custom-row1 {
 opacity: 0;

User generated image^^This is how it appears with the current script. It does not work all of the time and on certain browsers/platforms. It acts strangely as sometimes is will work for example on an iPhone in Safari and then other times nothing loads into the iFrame and sometimes not even into the input box. Even After clearing all the cache manually and running ccleaner before the tests as well because it will definitely give issues if I do not clear the cache when retesting.

At one point though it seemed to give me this above result almost every time when on windows on Chrome.

Then after I applied the custom CSS class and element the URL/input box would disappear and make it look proper occasionally but then I started getting the iFrame and the input box/url text not showing up so I reverted it back to no additional CSS.

ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
User generated image
Hey Chris, thank you for assisting me.

Ok I edited the custom field within the Order section of the checkout page that currently has HTML code telling the customer about us collecting their info and I attempted to put the do_action code in it in order to declare where the iframe should load. For some reason when I hit save the php code disappears. There must be another place to insert this type of code or another way to tell it where to place the iframe.

After the save it completely disappears:

User generated imageAlso I think I found the right hook:  woocommerce_after_checkout_shipping_form

is this where I insert it into the action? this syntax appears to be different from the add_filter that I did have working with the hook above "woocommerce_checkout_get_value"

add_action('woocommerce_after_checkout_shipping_form', 'show_cc_iframe');
function show_cc_iframe() {
    $current_user = get_current_user_id();
    $url = get_user_meta($current_user, 'order_url_string', true);
    echo '<iframe src="' . urldecode($url) . '"></iframe>';
}

Can you help me find where exactly I need to declare the position of the iframe and Can you please help me get the exact syntax for this? I really appreciate your help.
Chris,
The syntax you provided for the add_action seems to be working now. I just need to find a way to tell it where to place the iframe as it will not let me put that php code into that checkout field under "label" even though it accepts HTML.
Thank you.
Ahh right. Adding the do_action() call usually goes in the soruce file (php). I thought you were editing that directly - didn't realise you were trying to add in content from the Admin area,

How you add it in will depend on what that editor is (the bit that you're adding the field to). Doesn't look like standard WordPress, so I'm guessing it's a plugin of some sort.

In WordPress, hooks are just different places where certain events are fired. There are plenty of build-in action hooks that allow you to fire code at a given point. The one you mention - woocommerce_after_checkout_shipping_form - just means that it will fire after the shipping form (likely on the checkout page). If that's NOT where you want the iFrame to go, then don't use that hook. Plugins can add their own hooks as well, but I don't know how you're generating that page, or the content for it, so I can't really give you a specific answer.

There may well be a hook already in place that you can use - the page you're editing will have hooks - it's just a case of figuring out which ones.

Let me know what plugin you're using and how you're generating the page and I may be able to offer further guidance

Chris,

Your syntax was perfect and this is EXACTLY what I needed. I really appreciate your quick response with this information.

User generated image
as far as placing it instead of adding the  <?php do_action('show_cc_iframe'); ?> which it was not allowing I just found the best hook and then inserted HTML as PRINT in the script to get what I want accomplished

User generated image


Only problem now is that it does not work consistently across all browsers.

The last working screenshot I sent you was from Chrome on a windows machine. But now when I try firefox on a windows machine I get this:

User generated image
Is there a better way to write this line:
echo '<iframe src="' . urldecode($url) . '"></iframe>';

A way to get it to work on all browsers and platforms?

Chris I wrote those last two comments before I read you newest comment. Yes you were right, I needed to find the proper hook for specific placement and I found the right one and placed it in a new place that our site admin was wanting it in along with the HTML code added via the PRINT line.

The plugin is WooCommerce

Now the only issue is getting it to work on all browsers/platforms. Do you know a better more universal way to write that iframe line: echo '<iframe src="' . urldecode($url) . '"></iframe>';

Or maybe there is another way to get this to work universally,


Good stuff.

Not sure why it's not loading up on FireFox, but I suspect it has to do with he protocol. If your order_url_string value is http:// and your Credit Card info page is https:// (which is should be), then FireFox will prevent loading the iFrame because it sees it as security issue. Once you've loaded up your page, press F12 on your keyboard and you'll see the Web Developer tool. From there you can examine the Console for any errors (you may need to refresh your page) and you can use the inspector to see eactly what HTML has been generated - including looking at the src property of the iFrame.
That Admin panel with the General | Appearance | Advance tabs on it don't look like standard WooCommerce.
yes when running it on firefox it does not appear to pull the source:

User generated image
the URL is populated to the backend order_url_string and the value is confirmed Https
 User generated image^^You can see it is HTTPS from this previous image where the value was previously being pulled and returned to this input box with the filter I was running
Hmmm. OK. As a quick test, forget about the iFrame for a minute - just run a check to make sure that the URL is being called correctly and dump it out. Comment out the echo "<iframe... line and put this in it's place:

var_dump($current_user, $url);

Open in new window

Run your page and see what you get.
it appears to be just the Woocommerce plugin although it is the latest updated version:

User generated image
Yeah - that's not the standard out-of-the-box WooCommerce - it's got a few additional plugins loaded : Woo Discount Rules, Abandoned Carts, Multistep Checkout, Checkout FIelds, Booster Tools, Booster Settings - none of those are standard.

I'm guessing you're editing in either the Multistep Checkout or the Checkout FIelds
Ok I did it and this is what I got in firefox:



User generated image
But I got the url in chrome:
User generated image

It Is 177 and 176 for the user value because I am doing two diff attempts from two diff accounts......each time a new account is created a new unique URL is populated for that user in the backend and then it is only valid for a certain period of time but if it expires it still displays a message
so on another note when it expires it displays this:
User generated image but for some reason it does not appear to pull the URL when on firefox
OK. I'm a little suspicious that this is a FireFox issue, because this is all happening on the server, and at that point, the code has absolutely NO concept of which browser it's going to display in.

Let's do another test and see what we get. Instead of checking for the User ID, let's just force it. Change your code to this:

$url = get_user_meta(176, 'order_url_string', true); 
var_dump($url);

Open in new window

Because we know that User 176 gives us a valid URL, we're gonna force FireFix to use this User. Run it in Firefox and see what you get.
ok odd it seems to work with using 176 but not the new 177:
Here is 177
User generated imagehere is 176
User generated imagethere is a user registration plugin that is suppose to login the user account once the initial info is created and then the url gets populated in the backend from worldpay via an API......now if this is only occurring on firefox then maybe there is something wrong with the initial user account creation or login via the plugin or some other initial issue with firefox's interaction with the server

the 177 was the firefox created user and the 176 was the chrome created user
OK, so it looks like the problem is elsewhere. If you have access to your DB (phpMyAdmin or directly), then you can run the following query:

SELECT user_id, meta_value FROM wp_usermeta WHERE user_id IN (176, 177) AND meta_key = "order_url_string"

This will show you what's actually stored in your Database for those 2 users (assumes you haven't changed the prefix of your tables from the default wp_)

It looks like the code for generating the iFrame is actually working - it's something else that's going on that's causing your problem, so you'll need to start digging into how and where that data is generated and how it's stored in your DB.
If you've only done a test with 2 users - 176 and 177, I would suggest that it's far too early to put this down to Firefox / Chrome - it may just be coincidence. You say an API call is made to WordPay to grab the URL - maybe that failed for some reason. Again, because that's happening at the server level, it's unlikely to be a browser based problem.

I would also suggest you run the registration process several more times (dozens if needed) - in both browser. If it consistently fails in Firefox, then you've narrowed down your problem. If failures occur across both, then put the browser issue out of your mind and examine the PHP code. To help you, I would suggest you turn on Debugging and Error Reporting in WordPress and make sure your PHP code dumps relevant data to the log file. This way you'll get a much clearer picture of what's going on.
I have been running into this issue on and off all weekend with the filter as well. It seems to work on and off on all the browsers so your are right I do not think it is isolated to firefox but it is weird as it seems to work consistently on Chrome for a while so I thought it was the iframe line of the code but maybe it is the line that pulls the URL but what does not make sense to me is that it is pulling the 176 but not the 177. I have made a 100 test users and just can never seem to get consistency. That was when I was using the filter so I thought the new Action would resolve the consistency issue. I am going to get the query ran and let you know what I get back.
No worries

Inconsistencies are a developers worst nightmare. It makes debugging really painful as you can't replicate the problem time after time. You're going to have start logging info in debug mode and keep trying registrations until one fails. Then you look at the log files and see what differs. You may also need to examine your registration code and check for logic bugs. Make sure you have bomb-proof error checking in place.

It seems to me that for some reason, the URL data is not being written to the DB - so the code that makes that happen would be the logical starting point for debugging. All this work with the iFrame looks to have nothing to do with the actual problem you have.
User generated image 
            Chris StanyonWebDev  
          CERTIFIED EXPERT        
          Most Valuable Expert 2018         
          Distinguished Expert 2019         
 
          HelpfulCommented: 3h  
     
            Yeah - that's not the standard out-of-the-box WooCommerce - it's got a few additional plugins loaded : Woo Discount Rules, Abandoned Carts, Multistep Checkout, Checkout FIelds, Booster Tools, Booster Settings - none of those are standard.
     
      I'm guessing you're editing in either the Multistep Checkout or the Checkout FIelds

^^^To answer this comment above. Yes I am editing in the "Checkout Fields" section

--------------------------------------------------------------------------------------------------------------------------------------------------------------
And Yes after checking the field for user 177 from the Users tab it appears the URL was missing. Our other team member had made a change to the script that populates that "order_url_string" so actually no URLs are coming over at the moment although this would not explain why I was getting the URL non-population inconsistencies over the weekend with the Filter so there may actually be a deeper issue with the coding that pulls the URL. I am waiting on him to get back to fix it as I do not know how our Azure backend works yet. He is actually going to show me that too so I will be able to work on and/or troubleshoot those scripts as well. But yes everything you have said has been spot on. Getting that action working was my main task and you helped me get it going and also taught me how to troubleshoot it. It makes sense now when analyzing the way you have shown me by dumping the variables and forcing the script to pull from a specific user. Once he gets the script that populates the field with the URLs working then I can test it out again but it seems to be working from ALL browsers and platforms when forcing it to go with 176 so that should conclude that the script we created is working very well.

Once he gets back and reactivates the working script that pulls the URLs I will do my testing and report back. 



Excellent - Isn't development wonderful - you fix 1 bug and find 5 more :)
lol yes I am seeing that can be the case. All is mostly working now that he reverted back to the original script/flow, it is now posting to the field and he is showing me how to check the Azure "Logic Apps" flow chart and error messages/bugs. I had one fail and after reviewing it I see that one of our third party databases does not like an address that has more than 30 characters so now we can work on getting that particular problem fixed.

It is working in Chrome, Firefox and mobile firefox on iPhone and on multiple browsers on Android.

I am a Network Admin on my way to full Network Engineer and I do not know much about development however it is a requirement for me to learn python for my CCNP.  I never have really got into programming but this has been gratifying going through it and getting results. It definitely has me more interested in development.

Your information has been great, it resolved my immediate problem and also gave me a broader understanding of the environment.

The last tasks I have is to create a "Credit Card Successfully Saved" message for after the payment info is submitted via the iFrame. Then after that I need to have the final "Place Order" button not allow it to go through unless the payment info was inputted and sent to the payment processor. I am going to make a separate question for each of those tasks and I hope you will have the time to participate in those as well.
Sweet :)

Development can at times (a LOT of the time) be very frustrating and a thankless tasks - but ... if you get your head in the right space, it can also be very rewarding.

Good luck with the rest of your project - I'll see if I can help on your other questions.