Today I face a strange problem (as I face this first time so it is a strange problem for me). After saving the content of a model I just write the following line of code return route('organization'); so that it will redirect to the naming route organization after saving the content.
Once the content of the organization model saves it just print the URL of the page http//xyz.laravel/organization rather than printing the content of the page itself!
When I manually type and hit the dashboard URL it surprisingly prints the dashboard URL rather than loading the dashboard content! like the below image:
Everything was working fine before I tried to store the content of that model. Once the content is stored the application starts strange behavior. Here is the code of that model:
public function store(Request $request)
{
$validated = $request->validate([
'organization_name' => 'required|unique:organizations|max:255',
'abn_number' => 'required',
'address_one' => 'required|max:100',
'state' => 'required',
'post_code' => 'required'
]);
// check organization exist or not
$org = Organization::where('organization_name', $request->organization_name)->get();
if( count( $org ) > 0 ) {
//
} else {
$organization = new Organization();
$organization->organization_name = $request->organization_name;
$organization->abn_number = $request->abn_number;
$organization->address_one = $request->address_one;
$organization->address_two = $request->address_two;
$organization->state = $request->state;
$organization->post_code = $request->post_code;
$organization->created_by = Auth::user()->id;
$organization->created_at = Carbon::now();
$organization->save();
return route('organization');
}
}
Can anyone tell me what's actually happen and how can I fix this issue?
return route('organization'); will generate the URL link to the route and print it
You can use
return redirect()->route('organization);
You can get more info from https://laravel.com/docs/8.x/redirects
This is because you are not redirecting to that route but you are returning route url as a string, to redirect a user to a named route you can use global redirect() helper as below
return redirect()->route('organization'); instead of return route('organization');
for more see
documentation
Related
I have want to submit a form with post request where the method in the controller will redirect to a view.
Controller:
//Create quotation
public function quotation(Request $request){
$validated = $request->validate([
'parcel_weight' => 'required',
'parcel_size' => 'required',
'postcode_pickup' => 'required|postal_code:MY|exists:postcodes,postcode',
'postcode_delivery' => 'required|postal_code:MY|exists:postcodes,postcode'
]);
//logic to compute the quotation rate for each courier based on the inputs
//dd($request->all());
return redirect()->route('quotation.show');
}
//Show quotation
public function showQuotation(){
return view('orders.quotation');
}
web.php:
//Create new order
Route::get('/dashboard/orders','Dashboard\OrderController#index')->name('order.index');
//Generate quotation
Route::post('/dashboard/orders','Dashboard\OrderController#quotation')->name('order.quotation');
//Quotation page
Route::get('/dashboard/orders/quotation','Dashboard\OrderController#showQuotation')->name('quotation.show');
This code works fine but in order to hit the route('quotation.show'), data must be submitted from the form. If I just copy the URI and paste into the browser .../dashboard/orders/quotation then I will still be able to view the page without any input submitted. How do I prevent this?
Edit:
Using with() does not seem to work.
//Create quotation
public function quotation(Request $request){
$validated = $request->validate([
'parcel_weight' => 'required',
'parcel_size' => 'required',
'postcode_pickup' => 'required|postal_code:MY|exists:postcodes,postcode',
'postcode_delivery' => 'required|postal_code:MY|exists:postcodes,postcode'
]);
//logic to compute the quotation rate for each courier based on the inputs
//dd($request->all());
return redirect()->route('quotation.show')->with(['form','form']);
}
//Show quotation
public function showQuotation(){
if(request()->has('form')){
dd('Data has been submitted');
}else{
dd('NO DATA');
}
}
If you want to prevent direct navigation to a GET request (via entering a URL in your browser's URL bar, for example), then you'll need to add some back-end logic to prevent that. A quick solution is to include a session variable on the redirect(). This will include it in the session once, where you can then check it and act accordingly.
In the handler for your POST method:
return redirect()->route('quotation.show')->with(['submitted' => true]);
Then, in the handler for your GET method:
if (session()->has('submitted')) {
return view(...);
} else {
abort(403); // Unauthorized
// or
return redirect('/'); // Return home, etc
}
Sidenote: dd('Access') and dd('No Access') is good for debugging to see if your approach is working.
Edit: ->with() performs a "Flash", meaning submitted will be available for a single request only. If you need this to persist in the session longer (i.e. to facilitate refreshing the page), adjust the code:
session()->put('submitted', true);
return redirect()->route('quotation.show');
You'll now be able to refresh the page after being redirected, but you will also be able to navigate away, then manually back and still see your results. It's a give and take solution.
I have the following two settings page routes one for normal settings and the other for secured and admin related settings which uses the same middleware "password.confirm"
Route::get('/admin/settings',WebsiteInfoController::class,'edit'])->name('settings')->middleware('password.confirm');
Route::get('/settings',[WebsiteInfoController::class, edit'])->name('user.settings')->middleware('password.confirm');
This middleware redirects me to a second page where I have to enter password and then only i can get access to my intended page.
In my middleware I have the following function. I want to make an additional check if the user is intending to access the admin related settings
public function store(Request $request)
{
$this->validate($request, [
'secret_password' => ['sometimes','required'],
'password' => ['required','password:web'],
]);
if(redirect()->intended()->getTargetUrl()==route('settings')){
$secret_password =WebsiteInfo::first()->secret_password;
if (!Hash::check($request->secret_password, $secret_password)) {
throw ValidationException::withMessages([
'secret_password' => __('auth.password'),
]);
}
}
$request->session()->put('auth.password_confirmed_at', time());
return redirect()->intended(RouteServiceProvider::HOME);
});
});
}
Everything works fine in this method but the intended URL is lost when all the check is performed and I am redirected to homepage instead of settings page. I also tried to save the URL in a variable and use it later in the redirect command like
$path=redirect()->intended()->getTargetUrl();
if($path==route('settings')){
$secret_password =WebsiteInfo::first()->secret_password;
if (!Hash::check($request->secret_password, $secret_password)) {
throw ValidationException::withMessages([
'secret_password' => __('auth.password'),
]);
}
}
$request->session()->put('auth.password_confirmed_at', time());
return redirect()->intended($path);
This method works fine but it also loses the URL if the second validation fails and the user is redirected back to the confirm password page. Now when I try to perform the validation second time it again loses the intended URL and redirects me back to home page.
i also tried the check with $request method.
if($request->route()->named('settings')){
$secret_password =WebsiteInfo::first()->secret_password;
if (!Hash::check($request->secret_password, $secret_password)) {
throw ValidationException::withMessages([
'secret_password' => __('auth.password'),
]);
}
}
This method however, is not able to detect the route in middleware and the validation check is not at all performed.
So, My question is how do i check for the intended URL and perform validation check without losing the intended URL even after multiple failed validation attempts?
Your method is all fine. You just used the wrong method to extract the target website URL. It is true that redirect()->intended()->getTargetUrl() gives you the target page URL but it also removes the target website URL from the session so when you finish performing the checks and want to redirect to the intended page there is no intended page URL found in the session and you get redirected to the default fall back URL. This is what the redirect function does
public function intended($default = '/', $status = 302, $headers = [], $secure = null) {
$path = $this->session->pull('url.intended', $default);
return $this->to($path, $status, $headers, $secure);
}
Here, the $request->route()->named('settings) method does not work since you are not directly interacting with your initial view but instead through a middleware view which does not send the intended page request.
Use the following code and I guess you will be all fine with your validation attempts. It will work even after multiple failed login attempts.
public function store(Request $request) {
$this->validate($request, [
'secret_password' => ['sometimes','required'],
'password' => ['required','password:web'],
]);
$path=session()->get('url.intended', RouteServiceProvider::HOME);
if($path==route('settings')) {
$secret_password =WebsiteInfo::first()->secret_password;
if (!Hash::check($request->secret_password, $secret_password)) {
throw ValidationException::withMessages([
'secret_password' => __('auth.password'),
]);
}
}
$request->session()->put('auth.password_confirmed_at', time());
return redirect()->intended($path);
}
I have a route that creates several database entries. After the creation I'd like to forward to a route that fetches those entries and displays them.
This is the route for fetching/displaying:
/**
* #Route("/admin/app", name="appTourOverview")
*/
public function appTourOverviewAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
/* Get Network for User */
$network = $this->getUser()->getNetwork();
$tours = $em->getRepository('AppBundle:Tour')->toursTodayByNetwork($network);
return $this->render(':app:index.html.twig', array(
'tour' => $tours,
'imagePath' => Constants::IMAGE_PATH_DEV,
'imagePathGreen' => Constants::IMAGE_PATH_DEV_GREEN,
'imagePathYear' => Constants::IMAGE_PATH_DEV_YEAR,
));
}
and this is how I redirected from the "database route":
return $this->redirectToRoute('appTourOverview', array(), 301); but this gets cached and the database entries are never created...
I tried:
I copied everything from the "display route" and let it return the database stuff immediately.
/* Get Network for User */
$network = $this->getUser()->getNetwork()->getId();
$tours = $em->getRepository('AppBundle:Tour')->toursTodayByNetwork($network);
return $this->render(':checker:index.html.twig', array(
'tour' => $tours,
'imagePath' => Constants::IMAGE_PATH_DEV,
'imagePathGreen' => Constants::IMAGE_PATH_DEV_GREEN,
'imagePathYear' => Constants::IMAGE_PATH_DEV_YEAR,
));
instead of the redirect. Unfortunately this only works after a refresh? ($tours is empty the first time)
Any ideas?
the 301 redirect means he page was moved permanently and this information will be cached in your browser now. Please change that parameter to 302 or just remove (this is not necessary). Then, unfortunately you need to remove your browser's cache and the it should work.
302 means the redirect is temporary and browser won't cache it;
I have a taskController controller in my laravel application.Inside my resource folder i have have three pages under resource/views/taksController/
1.index.blade
2.store.blade
3.create.blade..
in my create.blade i have a form which on submit will go through a validation and if succeeded i want it to be redirected to store.blade ,otherwise it will redirect to create.blade again to fill up the form again.But here in my program ,on success it doesn't redirect me to store.blade file, rather it redirect me to index.blade.Why is this happening?How i can solve this?
i am using laravel 5.2
In my route.php i added the controller like
Route::resource('taskController','taskController');
in taskController the validation logic inside controller is like the following:
public function index()
{
//
return View::make('taskController.index');
}
public function create()
{
//
return View::make('taskController.create');
}
public function store(Request $request)
{
$rules = array(
'email' => 'required|email', // required and must be unique in the ducks table
'comment' => 'required',
'agree' => 'required|accepted' // required and has to match the password field
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
// get the error messages from the validator
$messages = $validator->messages();
echo 'bal';
// redirect our user back to the form with the errors from the validator
return Redirect::route('taskController.create');
}else{
return Redirect::route('taskController.store');
}
}
The URL used for the index route and the store route are the same. The difference is the HTTP verb that is used on that URL. GET requests to the URL will take you to the index, whereas POST requests to the URL will take you to the store.
In your store() method, when you return Redirect::route('taskController.store');, the route() method converts the parameter to the URL, and then makes a GET request to it. This is why you are redirected to index.
Generally, your store, update, and destroy routes don't have views associated with them. They are meant to perform an action and then redirect to the route that contains the view.
For example, the general workflow for creating a new resource is:
create route shows create view which has the form,
form POSTs to store route,
store route attempts to create new resource,
if validation fails, store route redirects back to create route with errors,
if resource is created successfully, store route redirects to the show route, with the id of the newly created resource.
The workflow for editing a resource is similar:
edit route shows edit view which has the form,
form PUTs to update route,
update route attempts to edit the resource,
if validation fails, update route redirects back to edit route with errors,
if resource is modified successfully, update route redirects to the show route, with the id of the modified resource.
i think you should have this:
public function index(){
return view('taksController.index');
}
public function create(){
return view('taksController.create');
}
public function store(Request $request)
{
//
$rules = array(
'email' => 'required|email', // required and must be unique in the ducks table
'comment' => 'required',
'agree' => 'required|accepted' // required and has to match the password field
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
// get the error messages from the validator
$messages = $validator->messages();
//echo 'bal';
// redirect our user back to the form with the errors from the validator
return Redirect::route('taskController.create');
}else{
return view('taksController.store');// redirects me to index.blade instead of store.blade
}
}
This is my first time using Yii2 so i am confused on how it works. I have this card page in my views/people/card.php .However i can only access the page through web/people/card. Why?
I am able to link the button in card.php to _card.php (without changing the url) using controller but how do i link my button in _card.php to _data.php?
My controller
public function actionCard()
{
$dataProvider = new ActiveDataProvider([
'query' => People::find(),
]);
$model = '';
if (Yii::$app->request->post() && isset($_POST['card'])) {
if(isset($_POST['selection'])){
$model = People::find()->select('id, name, ic')->where(['id' => $_POST['selection']])->all();
$content = $this->renderPartial('_card',['model'=>$model]);
$selection = implode(',', $_POST['selection']);
}
return $this->render('_design', [
'dataProvider' => $dataProvider,
'model' => $model,
]);
}
First You can only access the page through web/people/card. because this is the route managed by yii (is one of the possibile routing way you can see more in this guide
Second how do you link button in _card.php to _data.php? (in another controller)
also for this you can do using the routing rules above. In this case you should add the controller name to the route(controller/view) eg:
$content = $this->renderPartial('data/_data',['model'=>$model]);
but remember is not a good practice to use view from different controller.