exit function if error - cakephp - php

I have a function to check if a credit card is valid or not. If it is then continue to enter the details from the form into the database. But if it is not then display the message that is passed.
The problem is that if there is an issue with the credit card the message is passed but the rather then exiting the function so that it does not try to continue and add the data from the form, it adds the data.
I am not sure how to stop. The following code was written for me, seems to create a new dispatch and try to go back to the previous function confirm.
function confirm() {
//This view contains the form, when user submits they go to checkout view
if (isset($data)){$this->data = $data;}
$this->set('redirect_to', 'checkout');
}
function checkout(){
if(!empty($this->data['User']['card_number'])){
$check_card = $this->BillingValidation->validate_card($this->data['User']['card_number']);
if($check_card['valid']!=false){
// card is valid !
} else {
$msg[0][] = $check_card['error'];
$flashmsg = implode('<br />',$msg[0]).implode('<br />',$msg[1]);
$this->Session->setFlash(__($flashmsg,
true),'default', array('class' => 'flash-message-success'));
//if credit card is invalid go back to confirm view
$this->autoRender = false;
$d = new Dispatcher();
$d->dispatch(array("controller" => "res", "action" => "confirm"),array("data" => $this->data));
}
}
//if credit card ok then continues to process form
}

I used exit() and that seemed to work

Related

How to know if model has changed after submit a form in Laravel 5.5?

I have a view with a form where the user can change his name. After submit the form, I need to know if the name has changed or not.
At this momment, the code result allways in false (no changes), but the database table is updated correctly.
My User model has:
protected static function hasChanged()
{
self::updating(function($user){
if($user->isDirty())
{
return true;
}else
{
return false;
}
});
}
My ProfileController received the data in form.
public function updateProfile(Request $request)
{
$usuario = new User;
User::find(Auth::user()->id)->update($request->all());
$message = User::hasChanged() ? "Data changed" : "No data changed";
return redirect('home')->with('success', $message);
}
In $message allways get "No data changed", in spite of user has changed the data in the form.
I don't know if this is the best way to do it.
Thanks for help me.
The way that you have the hasChanged() method set up, this is actually not doing what you want it to do. Currently in your code, the hasChanged() method is registering an event handler for when the object is updating every time it is called. That means that hasChanged() doesn't actually return anything at all but it is adding a lot of unneeded overhead to your code in the long run.
What you'll want to do is split your call up into a couple of parts. When you call:
->update($request->all());
That is putting the values from the request into the object and then saving it all in one go. What you want to do is put the values into the object, then check to see if anything changed and then save it to the DB.
That will look something more like this:
$user = User::find(Auth::user()->id);
$user->fill($request->all());
$message = $user->isDirty() ? "Data changed" : "No data changed";
$user->save();
return redirect('home')->with('success', $message);

MethodNotAllowedHttpException generated using return back()->withInput() in Laravel 5.4

I've searched the forums and have seen many similar issues but none that seem to address my concern. I believe this is different because:
Form validation is not being used at this point
The form method does not seem to be related (just 1 post action)
The routes are not wrapped in web middleware
Here's what the application is supposed to be doing:
A user (with or without Authentication) views a public page with form (display_event)
The user selects a specific ticket for ordering and is directed to a 2nd form (register_step1)
The user then fills out demographic info for as many tickets as are being ordered
The processing step, if the email address used is of a valid user (in DB) should return to the form in step 2 & 3, populate the fields and flash a message. Otherwise it would perform the save() actions required. (register_step2)
The relevant routes from web.php are here:
Route::get('/events/{event}', 'EventController#show')->name('display_event');
Route::post('/register/{event}', 'RegistrationController#showRegForm')->name('register_step1');
Route::post('/register/{event}/create', 'RegistrationController#store')->name('register_step2');
The relevant portions of the RegistrationController.php are here:
public function showRegForm (Request $request, $id) {
// Registering for an event from /event/{id}
$ticket = Ticket::find(request()->input('ticketID'));
$quantity = request()->input('quantity');
$discount_code = request()->input('discount_code');
$event = Event::find($ticket->eventID);
return view('v1.public_pages.register', compact('ticket', 'event', 'quantity', 'discount_code'));
}
And:
public function store (Request $request) {
$event = Event::find(request()->input('eventID'));
if(Auth::check()) {
$this->currentPerson = Person::find(auth()->user()->id);
}
// set up a bunch of easy-reference variables from request()->input()
$email = Email::where('emailADDR', $checkEmail)->first();
if(!Auth::check() && $email === null) {
// Not logged in and email is not in database; must create
$person = new Person;
// add person demographics from form
} elseif(!Auth::check() && $email !== null) {
// Not logged in and email is in the database;
// Should force a login -- return to form with input saved.
flash("You have an account that we've created for you.
Please attempt to login and we'll send you a password to your email address.", 'warning');
return back()->withInput();
} elseif(Auth::check() && ($email->personID == $this->currentPerson->personID)) {
// the email entered belongs to the person logged in; ergo in DB
$person = $this->currentPerson;
// add person demographics from form
} elseif(Auth::check() && ($email->personID != $this->currentPerson->personID)) {
// someone logged in is registering for someone else in the DB
$person = Person::find($email->personID);
// add person demographics from form
} else {
// someone logged in is registering for someone else NOT in the DB
$person = new Person;
// add person demographics from form
}
// do more stuff...
$reg = new Registration; (set up a registration record)
}
I took the advice indicated in #apokryfos's comment and changed the form parsing-then-display script from a POST to a get.
redirect()->back() is, apparently, always a method=get and that was the cause of the MethodNotAllowedHttpException. In my ~2 weeks using Laravel, I hadn't yet come across that fact.

Redirect and POST at the same time

I have a form and I don't do client-side validation other than required attribute. I'm doing the validation on the server side.
lyrics/add.php
<form action="../scripts/lyrics/submit_lyrics.php" id="lyricsForm" method="post" autocomplete="off" enctype="multipart/form-data">
Form data is processed in a seperate php file. Retrieving and validating the form data in the following way:
scripts/lyrics/submit_lyrics.php
$form_data = new FormData(["artist", "album", "song", "year", "track_no", "lyrics"], "sssiis");
$form_data->validate();
What the validate method does is
public function validate() {
$valid = $this->check_form_data($fields);
$fields = implode(",", $fields);
if (!$valid) {
header("location: ".BASE."lyrics/add?status=error&problem=input&specifics=$fields");
exit;
}
}
check the form data and redirect the page (scripts/lyrics/submit_lyrics.php) to the form page (lyrics/add.php) with the information on validation (if it failed). Then I output an error message indicating that there's something wrong with the input using GET method.
I'm curious if I can do this using POST. I would need to modify this line
header("location: ".BASE."lyrics/add?status=error&problem=input&specifics=$fields");
make it redirect the page to BASE."lyrics/add" and also send the validation information using POST to that page. So I'd still be able output the validation error, but using POST instead of GET.
Is this possible?
No, this is not possible because you are rewriting the request. The browser will always send a "GET" request in response to a redirect request, unless it receives a 307 request in which it will repeat the request using the same method and parameters. See this related question on Programmers.
The workaround is to redirect to a new page with an embedded form that you generate, and have javascript POST that form for the user. It's an extra request but it's the only way to have the client make a second POST.
Using u_mulder's suggesion (storing values in a session), I've solved the problem in the following way:
scripts/lyrics/submit_lyrics.php
public function validate() {
$valid = $this->check_form_data($fields); // check if input fields are valid
$fields = implode(";", $fields); // invalid input fields
if (!$valid) { // not all fields are valid, so we return
session_start(); // start session
if (!isset($_SESSION["problem"])) { // making sure session variable doesn't exist
$_SESSION["problem"] = "input"; // error type: input, file_upload, db_insert, etc.
$_SESSION["specifics"] = $fields; // artist, album, etc. (for input)
}
header("location: ".BASE."lyrics/add?status=error"); // redirect to form page
exit;
}
}
lyrics/add.php
if (isset($_GET["status"])) {
$status = $_GET["status"];
switch ($status) {
case "error":
session_start();
if (isset($_SESSION["problem"])) {
$problem = $_SESSION["problem"];
$specifics = explode(";", $_SESSION["specifics"]);
$error_message = "There was an error.";
switch ($problem) {
case "input":
$error_message = "Invalid input on the following fields:";
break;
// other cases ...
}
session_destroy();
output("Error!", $error_message, $specifics);
} else {
// if the user reloads the page, session data is lost
// but we're still in the error page "lyrics/add?status=error" and have no error to show
// we either show an appropriate message or redirect to "lyrics/add"
session_destroy();
// output("Error!", "You're in the form validation error page, but there aren't any errors. Did you reload the page?");
// header("location: ".BASE."lyrics/add");
// exit;
}
break;
case "success":
// form submitted successfully
break;
}
} else {
// show form
}

email contact form - can reach success page manually even if form wasn't submitted - how to stop

Here's my setup for an email contact form:
www.example.com/includes/contact_form.php
www.example.com/includes/contact_submit.php
www.example.com/contact/
/contact/ includes contact_form.php, and the form points to contact_submit.php to run.
When contact_submit.php successfully sends the mail, it does a redirect back to /contact/ but includes a $_GET variable.
header('Location: /contact/index.php?success=yup');
Then in contact_form.php I have:
if (isset($_GET['success'])) { echo 'Your message has been received etc'; exit(); }
Everything works fine. I made it this way so that the form couldn't be F5/refresh resubmitted, and it is successful in that.
However, anyone can access the success page at any time by manually entering the url, even if they don't submit the form. Is there any way around that?
Ofcourse.
Use sessions for that:
class ResponseLog {
private function __construct(){}
public static function hasMessages(){
return (isset($_SESSION['response']['messages']) && !empty($_SESSION['response']['messages'])) ? true : false;
}
public static function setResponse(array $response){
$_SESSION['response'] = $response;
}
public static function getLastResponse(){
$response = isset($_SESSION['response'])) ? $_SESSION['response'] : null;
#unset($_SESSION['response']);
return $response;
}
}
And use it like this:
if(isset($_POST['form'])){
//validation and all to proccess request goes here
if(!$valid){
$response = array('request' => $_POST,'messages' => array('Incorrect email','Please enter forename'),'url' => '/my/form/where/it/happen/');
}
else {
$response = array('messages' => array('Success'),'url' => '/my/form/where/it/happen/');
}
ResponseLog::setResponse($response);
//redirect to contact form
}
In success page or fail:
if(ResponseLog::hasMessages()){
$response = ResponseLog::getLastResponse();
foreach($response['messages'] as $message){
echo $message;
}
}
With this you can store everything user does and can work with data as you need.
I hope this help :)
Warn: I wrote it from mind, so it's untested code and it can be implemented better it's just for view how to work with user session and responses.
PS: But is a lot of ways how to do it, for example see flash messages in some framework and you will be see how it works with sessions etc.
You can use the referrer page if you want, and throw an error or redirect if it is not the form page, but it is not so good. You can also check whether the fields and form name have been posted.
$_SERVER['HTTP_REFERER']

Codeigniter - add method URL & Redirect issue

I have a method in CI which basically adds a user to a table - if any form validation occurs it reloads the view - if successful it reloads the view to show that the user was added successfully. As seen below:
public function loadPeopleView(){
//loads unit page view
$this->load->model('people_model');
$people['people'] = $this->people_model->getPeople();
$this->load->view("header");
$this->load->view("people page/people_view", $people);
$this->load->view("footer");
}
public function addPerson(){
$this->form_validation->set_rules('personName', 'personName', 'required|min_length[6]|max_length[150]|trim|xss_clean');
$this->form_validation->set_rules('personPet', 'personPet', 'required|trim|min_length[3]|max_length[30]|xss_clean');
if($this->form_validation->run()){
$this->load->model('');
$this->people_model->addPerson();
$this->loadPeopleView();
} else{
//if validation fails - returns the peopl view this display error messages
$this->loadPeopleView();
}
}
my issue is when someone adds a person the browser remains on:
localhost/peoplecontroller/addperson
if the user keeps refreshing the page - loads of people will continue to be added in - is there anyway I can put the page back to:
localhost/peoplecontroller/
without having to use a redirect as I still want any error messages from the form validation to appear
I am only giving you an example please arrange according save and return functionality
public function addPerson(){
$this->load->model('people_model'); // load model
// validation
$this->form_validation->set_rules('personName', 'personName', 'required|min_length[6]|max_length[150]|trim|xss_clean');
$this->form_validation->set_rules('personPet', 'personPet', 'required|trim|min_length[3]|max_length[30]|xss_clean');
// check validation not clear
if ($this->form_validation->run() == FALSE) {
//if validation fails - returns the peopl view this display error messages
// also set error dat back
// setting up send back values to view
$this->data['personName'] = $this->input->post('personName');
$this->data['personPet'] = $this->input->post('personPet');
// get this->data values as a variable in view like $personName
// load view
$this->load->view("header");
$this->load->view("people page/people_view", $this->data);
$this->load->view("footer");
}
else{ // after validation success
// do your saving db stuff and set success message in session flash and redirect to
$this->people_model->addPerson();
// get and show message flash in your view
$this->session->set_flashdata('message', 'Please check card details and try again');
redirect('results', 'refresh');
}
}

Categories