Laravel 5.1 - Return to edit page - php

i'm writing a resource controller, and i have a problem with edit method.
i inserted a validator form, and if there is a error return to edit page with messages, but RETURN doesnt work good!
public function update(Request $request, $id)
{
$rules = [
'title' => 'required',
'content' => 'required',
'image' => 'required',
];
$messages = [
'title.required' => 'Campo titolo richiesto',
'content.required' => 'Contenuto richiesto',
'image.required' => 'Campo immagine richiesto',
];
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()){
return redirect('admin/article/edit' , $id)->withErrors($validator);
}else {
$s = new Article;
$visible = (isset($_POST['visible']) == '1' ? '1' : '0');
$data = array(
'title' => $request->get('title'),
'slug' => $request->get('title'),
'content' => $request->get('content'),
'image' => $request->get('image'),
'user_id' => $request->get('user_id'),
'category_id' => $request->get('category_id'),
'visible' => $visible,
);
$s->where('id', '=', $id)->update($data);
return redirect('admin/article')->with('message', 'Articolo aggiornato con successo!');
}
}
It return to:
admin/article/edit/5
NOT to
admin/article/5/edit
How can i fix this issue? thank you for your help!
PS: $id work well, return my id edited

Here is the redirect helper. As you can see below, it takes status as its' second parameter.
function redirect($to = null, $status = 302, $headers = [], $secure = null)
What you do with passing the $id as the second parameter is actually setting the $status.
You need to pass the $to parameter as the full path like below.
return redirect('admin/article/' . $id . '/edit')->withErrors($validator);
I guess that you want to generate the url with route, which can be implemented like below.
return redirect(route('admin.article.edit', compact($id)))->withErrors($validator);

So you're saying the redirect on failure doesn't redirect to the right URL? Have you tried doing return redirect('admin/article/' . $id . '/edit')->withErrors($validator);?
I haven't tested this approach, but perhaps return redirect()->back()->withErrors($validator); could also work.

One way to do this, as others have suggested, is like following:
return redirect("admin/article/{$id}/edit")->withErrors($validator);
Or if you've a "Route Name" defined, like this..
return redirect()->route('route.name',[$id])->withErrors($validator);
it all depends on how you prefer, I prefer the later one, looks clean to me.

Easiest solution:
Laravel 5.1 has a back() helper, that returns to the previous page:
return back()->withErrors($validator);
More thorough explanation:
If you want to be more verbose, a generally more robust way to redirect to a route is to first define it as a named route in your routes.php:
Route::get('admin/article/{article_id}/edit', ['as' => 'articles.edit', 'uses' => 'ArticlesController#edit']);
Route::bind('article_id', function($id, $route) {
return App\Article::whereId($id)->findOrFail();
}
If you are using Route::resource instead, then this is already done automatically for you. To find the name of the route, run the command-line php artisan route:list. Then, in your controller method, you call it like this:
return redirect()->route('articles.edit', ['article_id' => $id])->withErrors($validator);
Using that kind of call, Laravel will automatically build the correct URL for you. This is more robust because if you ever want to change that URL to something else or change what controller method it calls, you only need to change it in one place, the routes.php, and not everywhere in your code (as long as every reference to that route in your code is referring to it by name).

Here you have
return redirect('admin/article/edit' , $id)->withErrors($validator);
means the link/route is admin/article/edit/$id(5 or 2 or ...)
better check
return redirect('admin/article/' . $id . '/edit')->withErrors($validator);

The redirect go to the passed url:
return redirect('admin/article/' . $id . '/edit'); #admin/article/id/edit
return redirect('admin/article/edit', $id); #admin/article/edit/5
And you can use methods to get this url:
return redirect(action('Controller#update', compact($id)));

Related

How to remove parameter from a URL in laravel 5.2

How can I remove the parameters from a URL after processing in my controller? Like this one:
mydomain/mypage?filter%5Bstatus_id%5D
to
mydomain/mypage
I want to remove the parameters after the ? then I want to use the new URL in my view file. Is this possible in laravel 5.2? I have been trying to use other approaches but unfortunately they are not working well as expected. I also want to include my data in my view file. The existing functionality is like this:
public function processData(IndexRequest $request){
//process data and other checkings
return view('admin.index')
->with([
'data' => $data,
'person' => $persons,
]);
}
I want it to be like:
public function processData(IndexRequest $request){
//process data and other checkings
// when checking the full url is
// mydomain/mypage?filter%5Bstatus_id%5D
// then I want to remove the parameters after the question mark which can be done by doing
// request()->url()
// And now I want to change the currently used url using the request()->url() data
return view('admin.index')
->with([
'data' => $data,
'person' => $persons,
]);
}
I'm stuck here for days already. Any inputs are appreciated.
You can use request()->url(), it will return the URL without the parameters
public function processData(IndexRequest $request){
$url_with_parameters = $request()->url();
$url= explode("?", $url_with_parameters );
//avoid redirect loop
if (isset($url[1])){
return URL::to($url[0]);
}
else{
return view('admin.index')
->with(['data' => $data,
'person' =>$persons,]);
}
}
add new url to your routes and assuming it will point to SomeController#SomeMethod, the SomeMethod should be something like :
public function SomeMethod(){
// get $data and $persons
return view('admin.index')
->with(['data' => $data,
'person' =>$persons,]);
}
I hope this helps

Redirect Loop in Laravel 5

I'm doin the backend of a website while learning Laravel. I have these router below:
Route::get('/update/survivor/flag', 'SurvivorsController#flagSurvivor');
Route::get('/submit/log/flag', 'LogsController#submitFlag');
And in the flagSurvivor function i have:
public function flagSurvivor(Request $request){
$this->validate($request,[
'idFlagged' => 'required',
'idFlagger' => 'required'
]);
//Get the ids
$id = $request->input('idFlagged');
$flaggerid = $request->input('idFlagger');
//Get the flagger name
$survivors = Survivor::all();;
$flaggerSurvivor = $survivors->find($flaggerid);
//Flag a survivor
$survivors = Survivor::all();;
$flaggedSurvivor = $survivors->find($id);
$flaggedSurvivor->flags = $flaggedSurvivor->flags+1;
//Save updates
$flaggedSurvivor->save();
//Redirect
return redirect('submit/log/flag')
->with('nameFlagged', $flaggedSurvivor->name)
->with('idFlagged', $id)
->with('nameFlagger', $flaggerSurvivor->name)
->with('idFlagger' , $flaggerid);
}
which works perfectly except for the redirect part. After inserting the change into the DB it should send data to the submitFlag function, except that it doesn't. It just keeps looping with itself until it crashes from too many redirects. The log submit page also works just fine:
public function submitFlag(Request $request){
$this->validate($request,[
'nameFlagged' => 'required',
'nameFlagger' => 'required',
'idFlagger' => 'required',
'idFlagged' => 'required'
]);
$flaggerid = $request->input('idFlagger');
$flaggedid = $request->input('idFlagged');
$flaggername = $request->input('nameFlagger');
$flaggedname = $request->input('nameFlagged');
//Create a new log
$flag = new Log;
$flag->log = "The survivor $flaggername($flaggerid) reported that the survivor $flaggedname($flaggedid) is contaminated";
//Save log
$flag->save();
echo "Success";
}
if i go to
localhost/submit/log/flag?idFlagger=1&idFlagged=2&nameFlagger=Matheus&nameFlagged=Tauan
It echoes "Success" and inserts the log into the DB. But i just don't get it why it doesn't work by sending the parameters in the flagSurvivor function. I assume I'm doing the withs in the redirects wrong, or maybe something in the routes I have no idea. Any help is appreciated!
Turns out that using
return redirect('submit/log/flag?nameFlagged='.$flaggedSurvivor->name.'&idFlagged='.$id.'&nameFlagger='.$flaggerSurvivor->name.'&idFlagger='.$flaggerid);
Instead of the 'with's that I was using works properly.
Change your redirect to an action and the with's to an associative array:
//Redirect
return redirect()->action('LogsController#submitFlag', [
'nameFlagged' => $flaggedSurvivor->name,
'idFlagged' => $id,
'nameFlagger' => $flaggerSurvivor->name,
'idFlagger' => $flaggerid
]);
Redirecting to a controller action

rules() function in Laravel Request doesn't create unique slugs

I'm trying to make simple unique slugs. The slugs are saved correctly in database, so the function is working. I have problems with making them unique.
I have this rule in TagCreateRequest.php
public function rules()
{
$rules = [
'tag' => 'required|min:3',
'tag_slug' => 'required|alpha_dash|unique:tag,tag_slug,'
];
$rule = 'unique:tag';
$segments = $this->segments();
$id = intval(end($segments));
if ($id != 0) {
$rule .= ',tag_slug,' . $id;
}
$rules['tag_slug'][] = $rule;
return $rules;
}
and this in my store function in the controller
public function store(TagCreateRequest $request)
{
$tag = new Tag();
foreach (array_keys($this->fields) as $field) {
$tag->$field = $request->get($field);
}
$tag->save();
return redirect()->route('tags');
}
The error is about trying to add duplicate value
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'unique slug' for key 'tags_tag_unique'
Can someone help me to fix this issue?
You can access the id field magically. ID must be the same route parameter used in your route.
If you use id parameter like as Route::put('post/{id}/update') then you can magically access the id parameter inside your form request. Otherwise, if you call the parameter of {post} Route::put('post/{post}/update'), in your form request you must be call $this->post instead of $this->id, ok?
Please try it:
public function rules()
{
$rules = [
'tag' => 'required|min:3'
];
$slugRule = 'required|alpha_dash|unique:tag_slug';
if (! empty($this->id)) {
$slugRule = 'required|alpha_dash|unique:tag_slug,'.$this->id;
}
$rules['tag_slug'] = $slugRule;
return $rules;
}
This FormRequest will work fine on the store() and update() methods if you inject him in both methods.
See it:
// Your store route
Route::post('/post/store', ['as' => 'post.store', 'uses' => 'YourController#store']);
// YourController store method
public function store(NameSpaced\FormRequest $request)
{
// ...
}
// Your update route
Route::post('/post/{id}/update', ['as' => 'post.update', 'uses' => 'YourController#store']);
// YourController update method
public function update(NameSpaced\FormRequest $request)
{
// ...
}
$rules = [
'tag' => 'required|min:3',
'tag_slug' => 'required|alpha_dash|unique:[table name],[column name]'
];
Try this the first is table name and the second is column name that you wanted to unique, write without adding square braces. or you just pass table name like this,
$rules = [
'tag' => 'required|min:3',
'tag_slug' => 'required|alpha_dash|unique:[table name]'
];
laravel auto checks for the column.
I hope it helps.
I would suggest that you automatically generate a new slug whenever you are creating a tag. I got myself in same issues that you have listed here, so i decided on automatically generating whenever i am creating a new item. I used laravel-sluggable. It automatically generates unique slugs.
As per your question, i have defined a unique slug rule in one of my demo apps like this:
public function rules()
{
return [
'name' => 'required|string|max:255',
'slug' => 'required|string|max:255|unique:categories,slug,'.$this->segment(3),
];
}
Please note that $this->segment(3) refers to the id of the model being updated in the backend pages, it can be different in your application.

laravel 4.1 storing URL parameter, is it possible?

I'm still a student and still new with these frameworks
so I have two controllers in my routes:
Route::resource('homeworks', 'HomeworkController');
Route::resource('submithomeworks', 'SubmithomeworkController');
in views/Homework/show.blade.php, I have:
href="{{ URL::action('submithomeworks.create', $homeworks->id) }}"
so the URL will go from
http://localhost:8000/homeworks/1
to
http://localhost:8000/submithomeworks/create?1
so is there a way I can just store $homework->id which is just 1 in this situation to the submithomeworks table?
I tried this on the SubmithomeworksController
public function store()
{
$rules = array(
'homework_id' => 'required',
'homework_body' => 'required'
);
$submithomework = new Submithomework;
$submithomework->homework_id = Input::get('homework_id');
$submithomework->homework_body = Input::get('homework_body');
$submithomework->student_id = Auth::user()->id;
$submithomework->save();
Session::flash('message', 'Homework successfully added.');
return Redirect::to('homeworks');
}
but what do I do after that in the view? it won't store the homework_id says its still NULL
If you need to access a route parameter you can use the Route facade. For example:
Route::input('id');
You can check the Laravel Docs.

Laravel 4: Unique(database) not validating

I am creating a basic CMS to teach myself the fundamentals of Laravel and PHP.
I have a 'pages' table and I am storing a url_title. I want this URL title to be unique for obvious reasons. However, whatever I do to validate it, fails. It just saves anyway. I'm sure it is something simple. Can you spot what is wrong with this code?
I am also using Former in the view, that doesn't validate either. I have tried hard-coding a value as the last option in the unique method and it fails also.
http://anahkiasen.github.io/former/
http://laravel.com/docs/validation#rule-unique
States: unique:table,column,except,idColumn
Here is my Controller:
public function store()
{
$validation = Pages::validate(Input::all());
if($validation->fails()) {
Former::withErrors($validation);
return View::make('myview');
} else {
Pages::create(array(
'title' => Input::get('title'),
'url_title' => Input::get('url_title'),
'status' => Input::get('status'),
'body' => Input::get('body'),
'seo_title' => Input::get('seo_title'),
'seo_description' => Input::get('seo_description')
));
//check which submit was clicked on
if(Input::get('save')) {
return Redirect::route('admin_pages')->with('message', 'Woo-hoo! page was created successfully!')->with('message_status', 'success');
}
elseif(Input::get('continue')) {
$id = $page->id;
return Redirect::route('admin_pages_edit', $id)->with('message', 'Woo-hoo! page was created successfully!')->with('message_status', 'success');
}
}
}
Here is my model:
class Pages extends Eloquent {
protected $guarded = array('id');
public static $rules = array(
'id' => 'unique:pages,url_title,{{$id}}'
);
public static function validate($data) {
return Validator::make($data, static::$rules);
}
}
I have tried the following:
public static $rules = array(
// 'id'=> 'unique:pages,url_title,{{$id}}'
// 'id'=> 'unique:pages,url_title,$id'
// 'id'=> 'unique:pages,url_title,:id'
// 'id'=> 'unique:pages,url_title,'. {{$id}}
// 'id'=> 'unique:pages,url_title,'. $id
);
Any ideas? I spoke to the guy who created Former. He can't make head nor tail about it either. He suggested tracking it back to find our what query Laravel uses to check the uniqueness and try running that directly in my DB to see what happens. I can't find the query to do this. Does anyone know where to track it down?
Many thanks
Your rule should be:
public static $rules = array(
'url_title' => 'unique:pages,url_title,{{$id}}'
);
As I guessed from your code Input::get('url_title')
You have to use the field name used in the form.
Thanks peeps. I have been using the Laravel unique solutions and it hasn't been working well. I found this package which solves the issue brilliantly.
https://github.com/cviebrock/eloquent-sluggable#eloquent
Definitely worth a look.
Thanks for your feedback.

Categories