So I have a website that allows a user to enter a link and it then extracts information and places it into a list for them.
Now everything was working fine until yesterday when my web hosting partner done some upgrades. I know that mysql & php have been upgrading but am not sure what else.
First I had issues that I could not log into the DB (had to drop and recreate users).
Then an issue with PHP serialise for JSON (needed a code change).
Then a 412 invalid precondition error (needed a special rule set up by the hosting partner).
And now last of all a jquery script has stopped working. But I have no idea as to why. It worked before, but maybe that was luck (I am not so experienced in this).
Anyway, what happens is
User enters a link.
jquery calls a link which returns JSON.
The JSON is parsed and the web page updated with the results.
The user clicks on save and the data is entered into the DB.
using firebug and placing alerts in my javascript then I can see that Step 1, step 2 work fine. The JSON returned is valid (I have verfied it with JSONlint) but step 3 does not work. My script is below;
function getURLData(form)
{
var listid = $('input#listid').val();
var memberid = $('input#memberid').val();
var link = $('input#link').val();
var sendstr = "http://www.wishindex.com/ajax.php?link=\"" + link + "\"&listid=" + listid + "&memberid=" + memberid;
alert(sendstr);
$.getJSON(sendstr,function(result)
{
alert('inside');
if(result['Itemname'] != "")
{
alert('inside2');
$('#itemname').val(result['Itemname']);
$('#itemname').attr('readonly', 'true');
$('#desc').val(result['Description']);
$('#category').val(result['Category']);
$('#category').attr('readonly', 'true');
$('#price').val(result['Price']);
$('#price').attr('readonly', 'true');
$('#choosepicture').attr('onclick', 'window.open(\'http://www.wishindex.com/picture.php?link=' + result['Link'] + '\')');
if (result['PictureLink'] != "")
{
$('#picturelink').val(result['PictureLink']);
$('#picturelink').attr('readonly', 'true');
}
else
$('#choosepicture').removeAttr('disabled');
$('#automatic').attr('value', 'true');
$('#currency').val(result['Currency']);
$('#currency').attr('readonly', 'true');
}
else
{
$('#automatic').attr('value', 'false');
$('#manual').html('Please enter details manually');
$('#choosepicture').removeAttr('disabled');
$('#choosepicture').attr('onclick', 'window.open(\'http://www.wishindex.com/picture.php?link=' + result['Link'] + '\')');
}
});
}
If I enable the alerts then I see the link called is correct, the JSON is valid (via firebug and calling the link manually) and that the alert('inside') & alert('inside2') are executed so it is reaching this segment of the code, but my html elements are not updated!
As I said, before the upgrade it was fine, but maybe I have done something wrong, so any help would be appreciated as I have spent hours on this and can't find the issue.
My JSON response;
[{"ID":"","MemberID":"24","Listid":"41","Itemname":"LEGO Star Wars 9489: Endor Rebel Trooper and Imperial Trooper","Description":null,"NumberDesired":null,"NumberPurchased":null,"Category":{"0":"TOYS_AND_GAMES"},"Link":"\"http:\/\/www.amazon.co.uk\/LEGO-Star-Wars-9489-Imperial\/dp\/B005KISGAI\/ref=pd_rhf_gw_shvl1\"","PictureLink":{"0":"http:\/\/ecx.images-amazon.com\/images\/I\/51fQnt%2BlppL._SL160_.jpg"},"Price":"9.89","Currency":"\u00a3","Priority":null,"SuggestedPurchaser":null,"ActualPurchaser":null,"PurchaseStatus":null,"Productid":"B005KISGAI","Site":"amazon.co.uk","DateAdded":null,"DatePurchased":null,"Domain":null,"Temp":["LEGO-Star-Wars-9489-Imperial","dp","B005KISGAI","ref=pd_rhf_gw_shvl1\""],"Error":"","Warning":null}]
You can call this to get a JSON result example
http://www.wishindex.com/ajax.php?link=%22http://www.amazon.co.uk/LEGO-Star-Wars-9489-Imperial/dp/B005KISGAI/ref=pd_rhf_gw_shvl1%22&listid=41&memberid=24
A working demo (as requested) can be found here;
http://www.wishindex.com/test_newitem.php?listid=41
To test;
Enter a product link from amazon.co.uk such as
http://www.amazon.co.uk/LEGO-Star-Wars-9489-Imperial/dp/B005KISGAI/ref=pd_rhf_gw_shvl1
into the link field
Click on get details and the rest of the fields should be populated
automatically, but t hey are not.
Your json is an object inside an array. so you should only be able to access the data like that: result[0]['Itemname'] or do result = result[0] before you access it.
So it reaches 'inside2' because result['Itemname'] is undefined which is != ""
Related
I have a Stripe payment gateway with the credit card details to input.
It is working fine but there is one error message that I don't like but I am not advanced enough in PHP to fix this.
function stripeResponseHandler(status, response) {
if (response.error) {
// Enable the submit button
$('#payBtn').removeAttr("disabled");
// Display the errors on the form
$(".payment-status").html('<p>'+response.error.message+'</p>');
} else {
var form$ = $("#paymentFrm");
// Get token id
var token = response.id;
// Insert the token into the form
form$.append("<input type='hidden' name='stripeToken' value='" + token + "' />");
// Submit form to the server
form$.get(0).submit();
}
}
This is catching the errors and displaying response.error.message
These errors are great with the exception of if you write a bunch of numbers into the expiry instead of mm/yy.
the error returned is:
The 'exp_year' parameter should be an integer (instead, is
20undefined).
I don't know enough about this language but I want to catch this specific error and just say something like "The expiry date is incorrect, please enter as MM/YY"
I tried doing an if statement to read response.error.message but I didn't know how to format well. I tried also finding an error.code instead of message to use however the code invalid_number comes up but if I use this in an IF statement it refers to all invalid numbers of all fields (including card number) so my expiry statement is obviously incorrect in this situation!
That's actually JavaScript, not PHP. You probably have this code in a PHP file somewhere which you are rendering on the server, but this is JavaScript code which will run on the client.
It sounds like you are using Stripe.js v2 for your integration. This is discouraged as Stripe.js v2 is deprecated. Instead you should use Stripe Elements, which will handle all the validation you are after here for you.
The above link shows you how to create payments with PaymentIntents, the newest and most feature rich API from Stripe. If you however want to continue using the Charge API, you can see how to use it with Elements here: https://stripe.com/docs/payments/accept-a-payment-charges
I have a very simple web app created in Laravel 5.5:
There is a database with a list of coupon codes that have either not been redeemed or been redeemed. 0 is not redeemed and 1 is redeemed.
When someone enters a string into a HTML form input and submits it, Laravel goes to a route with that string as a variable.
The Controller code is as follows:
public function redeemCoupon ($coupon_code)
{
$coupon = Coupon::where('coupon_code', $coupon_code)->first();
if ($coupon === null) {
return view ('pages.no-coupon');
}
else if ($coupon->redeemed == 1) {
return view ('pages.used-coupon');
}
else {
$coupon->redeemed = 1;
$coupon->update();
return view('pages.redeemed-coupon', compact('coupon') );
}
}
Route:
Route::post('/redeem-coupon/{coupon_code}', 'CouponController#redeemCoupon');
You can try it out here:
http://178.62.4.225
Everything works fine when done normally, tested on the code "code01". When I enter it and it hasn't been redeemed, it says so, and redeeming it changes the column in the database from 0 to 1. If I try the process again it tells me it has already been redeemed.
The issue is when I'm on the page that tells me it's been redeemed:
http://178.62.4.225/redeem-coupon/code01
If I refresh it with CTRL + R, it just reloads and says it's already been redeemed. But if I paste the URL into a new tab or click into it and refresh by clicking enter, it gives " MethodNotAllowedHttpException" and the resulting debug screen, from what I can tell, offers nothing of use.
Help!
Changing
Route::post('/redeem-coupon/{coupon_code}', 'CouponController#redeemCoupon');
to
Route::any('/redeem-coupon/{coupon_code}', 'CouponController#redeemCoupon');
Did the trick
You are doing a GET request and define a post route change
Route::post('/redeem-coupon/{coupon_code}', 'CouponController#redeemCoupon');
to:
Route::get('/redeem-coupon/{coupon_code}', 'CouponController#redeemCoupon');
Is redeemed set as protected? Also displaying app_debug true displays all your DB connection info (user and pass)
More than likely to be due to the _method.
What page is _method = "POST" on?
I am attempting to pass some date values from angular into Laravel using a GET request. I dont believe these frameworks are related specifically to this problem however.
I pass the following value from a text input field to my API 1/4/2017 .It is exactly this value. I need to use a text field because of a Angular JS plugin I am using to pick the date.
In my PHP API I have the following.
$data = json_decode($requestData->data, false);
$date_object = new DateTime;
if($data->primary_reports_from_date == '1/4/2017') {
print_r('identical');
} else {
print_r('not identical');
}
die;
In Firefox and Chrome I get identical as my response, in IE I get not identical..
Edit: ,. after u_mulder's comment I did a var_dump()
I got "string(23) "1/4/2017" for $data->primary_reports_from_date
and "string(8) "1/4/2017" for 1/4/2017.
I have tried
print_r($data->primary_reports_from_date.' | 1/4/2017');die;
And I am getting "1/4/2017 | 1/4/2017" in my response
I have also tried
trim($data->primary_reports_from_date) and stripslashes($data->primary_reports_from_date) but no matter what I do when the data comes from IE I cannot seem to match it up.
Am I missing something obvious with GET requests and how the data might be affected?
The issue I have is I am trying to use DateTime::createFromFormat() but it wont work when the data comes from IE, it just returns blank.
This worked for me. I am unsure what hidden characters were there exactly but with this, in IE I also get identical as my result
if(preg_replace('/[^\PC\s]/u', '', $data->primary_reports_from_date) == '1/4/2017') {
print_r('identical');
} else {
print_r('not identical');
}
die;
Now I know that I am at risk here of asking a duplicate question, however I don't really know what to search for because I am a complete AJAX jQuery noob. Believe me, I have tried searching what I think is the obvious, with no luck so please go easy on me.
I have a php wordpress site which shows prices in GBP as default. At the top, is a select box with onchange="this.form.submit()" which allows the user to change the default currency that all prices are quoted in.
<form method="post" action="">
<select name="ChangeCurrency" onChange="this.form.submit()">
<option value="GBP">GBP</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
</select>
</form>
On the home page, are several, what I call "shortcode widgets", each one containing products and price tables. A dashboard if you like.
How it currently works (inefficient):
User changes select.
Form submitted
Homepage reloaded with updated prices in selected currency.
This is not good, because whenever somebody changes currency, the whole page is reloaded (this takes time, transfers approx 1mb without caching, not to mention unnecessary load on the server).
What I want (more efficient):
When the select box is changed, I wish to asynchronously post the form which changes the currency session variable.
Each "shortcode widget" is updated one by one without having to reload the entire page.
Is this something that jquery can do? where do I start?
Just in case it makes any difference so that you can see what I mean, here is the URL so that you can see what I am talking about... http://bit.ly/10ChZys
PART 2:
I have used jQuery and ajax to update the fixTable thanks to a mashup of answers below... I am using session variables to store the users choice, that way, if they return to the site, the option will be saved.
I am having problems with my code because the session variable stored within http://goldealers.co.uk/wp-content/plugins/gd/tables.php?currency=GBP&table=fixTable appears to have a different session_id to the user's session id because the option is no longer stored.
Is there a way of telling the server that they are one and the same session?
SOLUTION
I used Ribot's Solution to start with which worked and solved the initial problem, then extended with NomikOS's solution...
NOTE: this answer show some ideas about the php backend for the AJAX process. It is a complement for the other answers talking about the frontend process.
1.- a mockup to manage AJAX request in WP, just some ideas, ok?
add_action('init', 'process_ajax_callback');
function process_ajax_callback()
{
if ( ! $_REQUEST['go_ajax'])
{
return;
}
try
{
if (isset($_REQUEST['nonce_my_ajax']))
{
$nonce = $_REQUEST['nonce_my_ajax'];
if ( ! wp_verify_nonce($nonce = $_REQUEST['nonce_my_ajax'], 'nonce_my_ajax'))
{
throw new Exception("Nonce token invalid."); // security
}
}
}
catch (Exception $e)
{
$output['result'] = false;
$output['message'] = $e->getMessage();
echo json_encode($output);
exit;
}
$result = true;
$message = '';
switch ($_REQUEST['action'])
{
case 'update_price':
try
{
// update price
// price value comes in $_REQUEST['price']
}
catch (Exception $e)
{
$result = false;
$message = $e->getMessage();
}
break;
case 'other_actions':
break;
}
$output['result'] = $result ? true : false;
$output['message'] = $message;
echo json_encode($output);
exit;
}
2.- don't forget security
// nonce_my_ajax is passed to javascript like this:
wp_localize_script('my_js_admin', 'myJsVars', array(
'nonce_my_ajax' => wp_create_nonce('nonce_my_ajax')
));
3.- in general the needed in the frontend (to use with the backend mockup showed above) is something like:
$("select[name='ChangeCurrency']").live("change", function() {
var price = $(this).val();
$.post(
window.location.href,
{
go_ajax : 1, // parse ajax
action : 'update_price', // what to do
price : price, // vars to use in backend
nonce_my_ajax : myJsVars.nonce_my_ajax // security
},
function(output) {
if ( output.result == true )
// update widgets or whatever
// $("#my_div").html("we happy, yabadabadoo!");
// or do nothing (AJAX action was successful)
else
alert(output.message)
}, 'json');
});
4.- You can use $.get() or $.post() to send/process data to/in server but .load() is not good when you update DB because you can't manage returning messages of failures with the precision of a json response (for example: multiples validation error messages). Just use .load() to load HTML views.
UPDATE:
Set session_id() where can be executed both for normal requests and for ajax requests and at the early stage as possible. I hope you are using a class to wrap your plugin, if not now is the right moment to do it... example:
class my_plugin {
function __construct()
{
if ( ! session_id())
{
session_start();
}
add_action('init', array($this, 'process_ajax_callback'));
// ...
}
function process_ajax_callback()
{
// ...
}
}
UPDATE 2:
About nonce based security:
A security feature available in WordPress is a “nonce”. Generally, a
“nonce” is a token that can only be used once and are often used to
prevent unauthorised people from submitting data on behalf of another
person.
Ref: http://myatus.com/p/wordpress-caching-and-nonce-lifespan/
In this mockup nonce_my_ajax is just an example, indeed it should be more unique like nonce_{my_plugin_name}, or even better nonce_{my_plugin_name}_{what_action} where what_action represents updating user, or inserting new book, etc...
More info about it: WP Codex: WordPress Nonces, WPtuts+: Capabilities and Nonces.
Yes, jQuery can do it using ajax.
First of all, when using ajax, you don't have to post a form to get the data. Ajax in jQuery will load the text data of an url.
You may start by giving your select an id (here id="changeCurrency") and:
$("#changeCurrency").change(function(){
currency = $('#changeCurrency option:selected').val() // get the selected option's value
$("#some_div").load("someurl.php?currency=" + currency);
});
Now read up on jQuery and ajax for what kind of ajax call you need to do that suites your needs the best.
Drop the onchange and add an ID
<select name="ChangeCurrency" id="ChangeCurrency">...
On the page give all your prices a price in your base currency as well as outputting them
<span class="price" data-base="0.12">£0.12</span>
In your JS have a conversion table
// base currency is GBP
// each currency has 0: currency symbol, 1: conversion rate
var currency={"GBP":["£", 1], "USD":["$", 0.67]};
var usercurrency=currency['GBP'];
and bind an event to the change
$('#ChangeCurrency').on('change', function(){
// post to the server to update it
$.post(...);
// set locally on the page
usercurrency=currency[$(this).val()];
// and change all the values
$('.price').each(function(){
$(this).html(usercurrency[0] + (usercurrency[1] * $(this).data('base')).toFixed(2) );
});
}).trigger('change'); // trigger this to run on page load if you want.
I haven't checked any of this code
I have a PHP page that uses jQuery to let a user update a particular item without needing to refresh the page. It is an availability update where they can change their availability for an event to Yes, No, or Maybe. Each time they click on the link the appropriate jQuery function is called to send data to a separate PHP file (update_avail.php) and the appropriate data is returned.
Yes
Then when clicked the params are sent to a PHP file which returns back:
No
Then, if clicked again the PHP will return:
Maybe
It all works fine and I'm loving it.
BUT--
I also have a total count at the bottom of the page that is PHP code to count the total number of users that have selected Yes as their availability by simply using:
<?php count($event1_accepted); ?>
How can I make it so that if a user changes their availability it will also update the count without needing to refresh the page?
My thoughts so far are:
$var = 1;
while ($var > 0) {
count($day1_accepted);
$var = 0;
exit;
}
Then add a line to my 'update_avail.php' (which gets sent data from the jQuery function) to make $var = 1
Any help would be great. I would like to stress that my main strength is PHP, not jQuery, so a PHP solution would be preferred, but if necessary I can tackle some simple jQuery.
Thanks!
In the response from update_avail.php return a JSON object with both your replacement html and your new counter value.
Or to keep it simple, if they click "yes" incriment the counter, if they click No or maybe and their previous action wasn't No or Maybe decrease the counter.
Assuming your users are logged into the system I'd recommend having a status field in the user table, perhaps as an enum with "offline", "available", "busy", "unavailable" or something similar and use the query the number of available users whilst updating the users status.
If you were to do this you'd need to include in extend your methods containing session)start() and session_destroy() to change the availability of the user to available / offline respectively
The best way is the one suggested by Scuzzy with some improvements.
In your php, get the count from the database and return a JSON object like:
{ count: 123, html: 'Yes' }
In your page, in the ajax response you get the values and update the elements:
...
success: function(data) {
$("#linkPlaceholder").html(data.html);
$("#countPlaceholder").html(data.count);
}
...