Laravel GET route error MethodNotAllowedHttpException - php

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?

Related

Session sends user object weirdly

I'm working on Laravel 9 and I have notices something that I've never seen before.
Basically I'm trying to make a Login system with Laravel 9 and for the next step of logging users in, I added an input to check for the user mobile phone number:
<input type="text" name="userinput" class="form-control" id="phone">
And at the Controller:
$findUser = User::where('usr_mobile_phone',$request->userinput)->first();
if($findUser){
Session::put('userData',$findUser);
return redirect()->route('auth.login.next');
}else{
return redirect()->back()->withErrors('No results!');
}
So as you can see I have send the userData object information to the Session called userData.
And then for the next Controller method that repsonses to auth.login.next route, I added this:
public function loginNext()
{
$user = Session::get('userData');
if(Session::has('nextStep') && Session::get('nextStep') == 1){
return view('frontend.auth.next', compact('user'));
}else{
abort(404);
}
}
Now here, I tried inserting all the object of user to $user variable.
So that in the next.blade.php, I can check informations like this:
#if(!empty($user->usr_password_hash))
// Show button login with password
#endif
So it work nice and clean but there is only one problem:
If I stay at the same page and update the record of returned $user manually in the phpmyadmin and set the usr_password_hash to NULL
So the record will be looked like:
Now the button must not be appeared on the page because this password field is empty. However it is still showing!
So this means that session has sent the user object for only one time and this user object is not prototyping live of the user data from the DB.
However if I dd($user) at the Controller method, I can properly get the user information:
So what's going wrong here?
If you know how to solve this issue, please let me know...

How can I persist data for a redirect with CodeIgniter?

I'm attempting to validate a users login attempt and inform them that
Their username is wrong or
their password is wrong (because I personally hate with a blind fury when a website doesn't inform me WHICH it is but that's beside the point).
I've read a lot of SO posts on this issue but the ones I've found are years old and I'm dealing with CodeIgniter 3.0.1.
This is the code that I have in place. I'm using Eclipse PDT to as my IDE and I like it quite a bit (but that's getting off track) so I've been able to step through the execution and watch as it just fails completely.
IF (!$this->User->login( //Testing shows this works fine - the SWITCH statement gets executed as it should and the BADUSERNAME case is followed through.
addslashes(strtolower($this->input->post('username', TRUE))),
addslashes($this->input->post('password', TRUE)),
$this->getIP())){
SWITCH($this->User->ID){
CASE 'BADUSERNAME':
$this->session->set_flashdata('user_msg', 'Invalid Username');
BREAK;
CASE 'BADPASSWORD':
$this->session->set_flashdata('user_msg', 'Invalid Password');
BREAK;
CASE 'ALREADYLOGGEDIN':
$this->session->set_flashdata('user_msg', 'You are logged in elsewhere.');
BREAK;
DEFAULT:
$this->session->set_flashdata('user_msg', 'Something has gone terribly wrong. Please try logging in again.');
BREAK;
}
redirect(base_url());
}
Then a bit further down I load the header, body, and footer views - The body is where the error message should be displayed but it's not..
<div id="contentarea">
<div class="container">
<?PHP
ECHO $this->session->flashdata('show_validation') ? validation_errors() : '';
$error = $this->session->flashdata('user_msg'); //This is where it's supposed to get it...
IF ($error) //And this is where it's supposed to show it...
ECHO "<div class='error'>$error</div>";
?> //But the value is wiped so it only ever grabs NULL.
I've followed the path of execution after calling the redirect after setting the flash data and I've noticed that after the redirect finishes it's chain of execution, it calls exit;.
Then everything loads again from the index.php file, and when Session finally pops up... the value 'user_msg' is nowhere to be found.
So clearly I'm doing something wrong here - what am I doing wrong here? Will the flash_data only persist until that redirect is called? Even the session_data values (calling $this->session->value = 'some arbitrary user message' fails to persist).
How can I persist the message for the next time the body element is loaded so that it can tell the user "Hey, didn't find you" or "Hey, your password wasn't right"?
EDIT 1
So it turns out I do not need to redirect for what I am doing as POSTing (submitting the user name and password) handles that for me.
I'm going to leave the question here for anyone else who may need it answered though - perhaps the answer is simply that Flash data just doesn't survive a redirect?
Flashed data is only available for the next http request, if you reload the page a second time, data is gone.
To persist data in the session, you want to set the variable in the session.
Codeigniter
Adding Session Data
Let’s say a particular user logs into your site. Once authenticated, you could add their username and e-mail address to the session, making that data globally available to you without having to run a database query when you need it.
You can simply assign data to the $_SESSION array, as with any other variable. Or as a property of $this->session.
Alternatively, the old method of assigning it as “userdata” is also available. That however passing an array containing your new data to the set_userdata() method:
$this->session->set_userdata($array);
$this->session->set_userdata('username', 'username is wrong');
in the view
$this -> session ->userdata('username');
or
$this ->session -> username;
Reference Session Library Codeigniter.
hope this help.
All you have to do is use $this->session->keep_flashdata('user_msg') with $this->session->unset_userdata('user_msg')
here is the solution (view file)
<?php
$error = $this->session->flashdata('user_msg');
if (isset($error)) {
echo '<div class="error">' . $error . '</div>';
$this->session->unset_userdata('user_msg');
}
?>
After that in your controller construct function (In that controller where you redirecting)
public function __construct() {
parent::__construct();
//.....
$this->session->keep_flashdata('user_msg');
}
I had same problem and this works. do not forget to clear cache when try or try in different browser
You can use codeigniter's flashdata to display errors separately.
This is what I usually use.
Controller:
$errors = array();
foreach ($this->input->post() as $key => $value){
$errors[$key] = form_error($key);
};
$response['errors'] = array_filter($errors);
$this->session->set_flashdata($response['errors']);
redirect('your-page', 'refresh');
And the to display the errors use
<?php echo $this->session->flashdata('field_name'); ?>

Symfony2 - app.user not synced with database

I have a page called lobby in which a user can accept a friend request. Accepting a friend request leads to this action :
public function acceptFriendRequestAction($requestId)
{
$user = $this->getUser();
// Here $user is modified and changes are saved in database
return $this->redirect('ACAppBundle:Lobby:index');
}
A template is rendered, using app.user to show friends and requests.
However, changes in the database are not taken into account. User object is the same as it was before acceptFriendRequestAction. When page is refreshed, app.user is synced with database.
Why do I need to refresh the page to see changes in the database ?
How to set app.user as updated user ?
When I use forward instead of redirect it works but I don't want to use this because forward doesn't change the URL.
I also noticed that sometimes a class named Proxies/.../User is used instead of User. Could that have something to do with my problem ?
Thank you for helping, I've been stuck on this for days...
You need add cascade options for your relations in Friendship class for $request field
More info http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations
So it seems that i've found the solution :
I replaced :
return $this->redirect('ACAppBundle:Lobby:index');
with
return $this->redirect($this->generateUrl('ac_app_lobby'));
Now after redirection, new friend is shown without needing to reload page.
I don't understand what's the difference between the two lines though. Can someone explain that?
You aren't updating the actual relationship when you are removing the friendship request. When you do the removeElement you are just removing it in memory until you set the sender or receiver to null.
You can do this by hand like..
$user->removePendingRequest($request);
$request->setSender(null);
// or $request->setReceiver(null);
Or you can add it to the add/remove to do it automatically like..
public function removeFriendship(FriendshipInterface $friendship)
{
if ($this->friendships->contains($friendships)) {
$this->friendships->removeElement($friendships);
$friendship->setSender(null);
// or $friendship->setReceiver(null);
}
}

Abort running WordPress function under certain conditions

I am trying to figure out how to abort a running WordPress function. When the user deletes a custom post type (in my case, a store), I want to check to see if there are any associated posts with that store. I am running a query and checking to see if there are returned results. If we return 1 or more results, I want to abort the delete and present the user with an error message stating that they must delete the associated post. I am using the action 'before_delete_post'. Here is what I'm going for:
if (count($results)==0){
//delete the data
} else {
//abort the delete.
}
Thanks in advance for the assistance.
if you are using before_delete_post you could have something like this:
function prevent_delete_custom_post() {
if (count($results)==0){
//delete the data
} else {
wp_redirect(admin_url('edit.php')); //here you can try to get the variables that you have in the url to redirect the user to the same place.
exit();
}
}
add_action('before_delete_post', 'prevent_delete_custom_post', 1);
Remember that 'before_delete_post' action is fired before post metadata is deleted.
http://codex.wordpress.org/Plugin_API/Action_Reference/before_delete_post
And 'delete_post' action is fired before and after a post (or page) is deleted from the database.
http://codex.wordpress.org/Plugin_API/Action_Reference/delete_post

Why is this jquery script not working?

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 != ""

Categories