NotFoundHttpException at new route Laravel 4 - php

i see there are similar questions but dont find any clue of me problem.
I created a basic users system, to manage groups, permissions, users, etc. The basic routes like create, edit, delete, index are working.
Now im trying to add one more function to UserController, to manage the users groups in a simple view.
Route::group(array('prefix' => 'admin'), function()
{
Route::resource('groups', 'GroupController');
Route::resource('users', 'UserController');
});
The function in controller:
public function groups($id)
{
$user = Sentry::findUserByID($id);
$groups = $user->getGroups();
return View::make('users.show')
->with('groups', $groups);
}
And the users/groups.blade.php:
#extends('layouts.admin')
#section('content')
<header id="page-title">
<h1>User Groups</h1>
</header>
<!-- if there are creation errors, they will show here -->
{{ HTML::ul($errors->all()) }}
{{ Form::open(array('url' => 'admin/users/save_groups')) }}
<div class="form-group">
</div>
{{ Form::submit('Create!', array('class' => 'btn btn-primary')) }}
{{ Form::button('Cancel', array('class' => 'btn btn-danger')) }}
{{ Form::close() }}
#stop
I go to url "mysite/admin/users/2/groups", and im getting the NotFoundHttpException, i try many ways to make it works and dont know what is happening.
I assume it will works like "mysite/admin/users/2/edit", but if i test the show function, it only is "mysite/admin/users/2", dont need the show action to know is that function, maybe i missed something.

You have declared a route for "GroupsController". As per the documentation, this will only handle actions as defined in the table: "Actions Handled By Resource Controller"
Just by adding one more action it won't simply be extended by Laravel.
You should instead type:
Route::get('users/{id}/groups', 'UserController#groups');

Related

php change certain rows value with a button

I have abstracts table in my database with the Abstract_Status_ID column, I am trying to create a button that changes every Status from '2' to '3'
I have tried to do this:-
My controller
public function publish($A_ID)
{
$abstracts = Project::find($A_ID);
$abstracts->Abstract_Status_ID= 3;
$abstracts->save();
return redirect('/AdvertisedProjects')->with ('success', 'Abstracts Published' );
}
my route
Route::put( '/projects', 'AbstractsController#publish');
Route::post( '/projects', 'AbstractsController#publish');
my view (projects)
Tried with the csrf token and without as eloquent docs says any post/put will be restricted without it.
#if (count ($abstracts)> 0)
#foreach ($abstracts as $abstract)
#if($abstract->Abstract_Status_ID == 2)
{!! Form::open(['action' => ['AbstractsController#publish' , $abstract->A_ID], 'method' => 'post' ]) !!}
{{ csrf_field() }}
{{Form::hidden('_method', 'PUT') }}
{{Form::Submit('Submit Changes',['class' => 'btn btn-primary'])}}
{!! Form::close() !!}
#endif
#endforeach
The error I am getting when clicking the button
(1/1) ErrorException
Missing argument 1 for App\Http\Controllers\AbstractsController::publish()
Also, the code above will show more than one button, any suggestions to make one button change all of them ?
A: If you want to have a button for each ABSTRACTS just change your route to :
Route::put( '/projects/{A_ID}', 'AbstractsController#publish');
B: If you want to have only one button that change all , you can echo their ID in hidden input then send form
so your view would be:
#if (count ($abstracts)> 0)
{!! Form::open(['action' => ['AbstractsController#publish'], 'method' => 'post' ]) !!}
{{ csrf_field() }}
{{Form::hidden('_method', 'PUT') }}
#foreach ($abstracts as $abstract)
#if($abstract->Abstract_Status_ID == 2)
{{Form::hidden('abstract_ids[]', $abstract->A_ID) }}
#endif
#endforeach
{{Form::Submit('Submit Changes',['class' => 'btn btn-primary'])}}
{!! Form::close() !!}
And Your Controller :
public function publish()
{
foreach(request('abstract_ids') as $A_ID){
$abstracts = Project::find($A_ID);
$abstracts->Abstract_Status_ID= 3;
$abstracts->save();
}
return redirect('/AdvertisedProjects')->with ('success', 'Abstracts Published' );
}
You are using form method="POST". I think it should be method="PUT".
The main problem in your code is the definition of your routes, You are passing an argument ($A_ID) to the controllers publish method,
But in your routes, you did never mention that you are passing any argument through your route. So for passing the argument, you can use {$A_ID} in your route URL.
One thing you should always remember is that you should always give your route a name and call it by using its name and route() Laravel helper method.
The benefit of using route name is that if you decide to change the URL-Structure of your route later in the development process, you'll never have to change it everywhere in your application because you did not call it by its URL.
And route name is less error prone
In total, You should define your routes like this
Route::put('projects/{A_ID}/update', 'AbstractsController#publish')->name('projects.update');
Route::post('projects/{A_ID}/post', 'AbstractsController#publish')->name('projects.store');
Then in you blade files now you can call it like
{!! Form::open(['action' => route('projects.store', $abstract->A_ID), 'method' => 'post' ]) !!}
Hope this will clarify and resolve your problem.

Passing String between views - Laravel 5.1

I want to create a two buttons buyer and seller in the home page, and on click of these buttons, I want the guest to get directed register page with a ~hidden input~ placed in the form depending on the value of the button pressed.
I am using Laravel 5.1
For what I am trying to achieve, do I need to register a new route and a new function?
First, do I need to use a {!! link_to !!} or {!! Form submit !!}. I thought form submit would work:
{!! Form::open(array('url' => '/auth/register', 'profession' => 'seller')) !!}
{!! Form::submit('Seller', array('class' => 'btn btn-warning')) !!}
{!! Form::close() !!}
My routes are:
Route::get('auth/register', 'Auth\AuthController#getRegister');
Route::post('auth/register', 'Auth\AuthController#postRegister');
auth/register and AuthController is the one that comes with Laravel default. I also didn't register a new public function. Is this the reason? Do I need to send the data from view to controller and then other view (view->controller->view). I am really confused on this one.
This is how it seems in the view-source:
<form method="POST" action="http://app.com/auth/register" accept-charset="UTF-8" profession="seller"><input name="_token" type="hidden" value="Cw4Het1A1M6020oQL45Cy2Q0ct46TSe6ba2g4r4C">
<input class="btn btn-warning" type="submit" value="Seller">
</form>
Edit:
I think I can't send variables between views. So do I need to register a completely new route and a controller, and two methods in it? I am really confused on this stage.
Check out my answer to your previous similar question for details on the implementation:
Laravel Passing Data From One View to Another View
To answer the questions you are posing
You can use two forms one for buyer and one for seller
{!! Form::open(['route' => ['type_path']]) !!}
{!! Form::hidden('type', 'buyer') !!}
{!! Form::submit('Buyer', array('class' => 'btn btn-warning')) !!}
{!! Form::close() !!
{!! Form::open(['route' => ['type_path']]) !!}
{!! Form::hidden('type', 'seller') !!}
{!! Form::submit('Seller', array('class' => 'btn btn-warning')) !!}
{!! Form::close() !!
on your landing page and then have both of this forms direct to a same named route (in this case 'type_path')
Then in your routes.php file you would reference only one controller and one method and handle the logic in that method. Again see the link to my answer to see a full implementation of this for the example of writer and reader.
Essentially as you say, you'd be sending as the hidden inputs from the view to the controller to the second view.
You could register a new route like:
Route::get('auth/{TYPE}/register', 'Auth\AuthController#getRegisterType')
Your home page would have something like this:
seller
Your controller method would be something like this:
public function getRegisterType($type)
{
Session::put('registerType', $type);
return redirect('/auth/register');
}
Then you can access you set session variable from the controller methods getRegister & postRegister
Have you two buttons direct to the register page with a query string parameter:
Buyer
Seller
And then just check for the query string parameter in your register.blade.php view:
{!! Form::hidden('account_type', Request::query('type')) !!}
If you need to validate one of the two is present, then you could create a middleware class you apply to the login route only:
public function handle($request, Closure $next)
{
if (! in_array($request->query('type'), ['buyer', 'seller'])) {
// Error
}
return $next($request);
}

Laravel 4 - NotFoundHttpException only on one custom route

I must be missing something really simple but I can't seem to find it. So I have my Resource defined in my routes.php but I need an additional route for an advanced search page with filters and stuff, my show/update/edit/create... pages are working perfectly but my search page isn't.
So in routes I have:
Route::resource('hostesses', 'HostessesController');
Route::get('/hostesses/search', 'HostessesController#search');
And I have a search form on my main page like this:
{{ Form::open(array('route' => 'hostesses.search', 'class' => 'navbar-form navbar-right')) }}
<div class="form-group">
{{ Form::text('search_term', '', array('class' => 'form-control')) }}
</div>
{{ Form::submit('Submit', array("class"=>'btn btn-default')) }}
{{ Form::close() }}
And when I use the search form I get the NotFoundHttpException
In my controller I have:
public function search()
{
return View::make('hostesses.search');
}
And I have created the template on views/hostesses/search.blade.php with a simple hello world message to check that it works, but I keep getting the exception!
Change the order of your routes and 'define' the named route of hostesses.search which is in your form
Route::any('/hostesses/search', array(['as' => 'hostesses.search', 'uses' => 'HostessesController#search');
Route::resource('hostesses', 'HostessesController');
Because what is happening is the resource for /hostesses/$id is capturing the search id, and returning an error that id of search does not exist
Also - change your route to Route::any(). This means it will respond to "get" and "post" requests.
However I would recommend splitting your route to be getSearch() and postSearch() functions and do this:
Route::get('/hostesses/search', array(['as' => 'hostesses.getsearch', 'uses' => 'HostessesController#getSearch');
Route::post('/hostesses/search', array(['as' => 'hostesses.postsearch', 'uses' => 'HostessesController#postSearch');
Route::resource('hostesses', 'HostessesController');
public function getSearch()
{
return View::make('hostesses.search');
}
public function postSearch()
{
// Do validation on form
// Get search results and display
}
And update your form
{{ Form::open(array('route' => 'hostesses.postsearch', 'class' => 'navbar-form navbar-right')) }}
You need to define a POST route:
Route::post('/hostesses/postSearch',array('as'=>'hostesses.search','uses' => 'HostessesController#postSearch'));
Then in your controller
public function postSearch()
{
var_dump(Input::get('search_term'));
}

Laravel4: delete a comment

I have a simple blog with Post resource and Comment nested resource.
Until now I can see all the comments belonging to a post and create a new comment for a post.
I want to give the possibility to delete a specific comment, but somehow I am making some mistakes.
This is the view comments.index with all the comments:
#extends('master')
#section('blog')
#foreach($comments as $comment)
<div class="span11 well">
<ul>
<li><strong>Body: </strong> {{ $comment->body }} </li>
<li><strong>Author: </strong> {{ $comment->author }}</li>
</ul>
{{ Form::open(array('method' => 'DELETE', 'route' => array('posts.comments.destroy', $post_id), $comment->id)) }}
{{ Form::submit('Delete', array('class' => 'btn btn-danger')) }}
{{ Form::close() }}
</div>
#endforeach
{{ link_to_route('posts.index', 'Back to Post index') }}
This is the error i get running the index: Parameter "comments" for route "posts.comments.destroy" must match "[^/]++" ("" given) to generate a corresponding URL.
This is the Index method inside CommentsController:
public function index($post_id)
{
$comments = Post::find($post_id)->comments;
return View::make('comments.index', compact('comments'))->with('post_id', $post_id);
}
And this is the Destroy method inside CommentsController:
public function destroy($post_id, $comment_id)
{
$comment = $this->comment->find($comment_id)->delete();
return Redirect::route('posts.comments.index', $post_id);
}
Someone can tell me please where I am making the mistake?
This the routes:
Route::resource('posts', 'PostsController');
Route::resource('posts.comments', 'CommentsController');
You have put a regexp tester on your route, to check your comments parameter.
This error message says that parameter that you give to Laravel isn't good.
If your parameter is only a decimal id, use \d+ regexp instead.
Without your routes.php file - I cant be sure, but I think this might be the problem.
Change
{{ Form::open(array('method' => 'DELETE', 'route' => array('post.comments.destroy', $post_id), $comment->id)) }
to
{{ Form::open(array('method' => 'DELETE', 'route' => array('post.comments.destroy', array ($post_id, $comment->id))) }
If this does not work - please post your routes.php file.
Edit: You have defined your route as a "resource". This means your destroy route is defined with only one variable. You dont actually need the $post included, so just define this:
{{ Form::open(array('method' => 'DELETE', 'route' => array('posts.comments.destroy', $comment->id))) }}
and change your destroy method to this - there is no need for the $post to delete a $comment:
public function destroy($comment_id)
{
$comment = $this->comment->find($comment_id)->delete();
return Redirect::back();
}

laravel form post issue

I am building a practice app with the Laravel framework I built a form in one of the views which is set to post to the same view itself but when I hit submit the form is posted however I do not get the desired output, I see the original view again.
Here is my view index.blade.php
#extends('master')
#section('container')
<div class="wrapper">
{{ Form::open(array('url' => '/', 'method' => 'post')) }}
{{ Form::text('url') }}
{{ Form::text('valid') }}
{{ Form::submit('shorten') }}
{{ Form::close() }}
</div><!-- /wrapper -->
#stop
and my routes.php
Route::get('/', function()
{
return View::make('index');
});
Route::post('/', function()
{
return 'successfull';
});
What I've tried so far
I tried changing the post to a different view and it worked.
However I want the form to post to the same view itself.
Instead of returning a string I tried to return make a view still it
didn't work.
What am I doing wrong?
addendum
I see that when the form is making the post request I am getting a 301 MOVED PERMANENTLY HEADER
{{ Form::open(array('url' => ' ', 'method' => 'post')) }}
Passing a space as the url has worked for me.
I think this post: Form submits as GET Laravel 4 is related to your problem. I think the problem as I undersood it is caused by end a form url with a / . I found this when having problems to using post to a ./ url in my form. There is also a bug at github that seems like it is related https://github.com/laravel/framework/issues/1804.
I know this is an old question but I found this thread having the same problem so hopefully someone else is helped by my answer.
You need to make sure that your form's method does NOT end in a / for it to be routed correctly. For example if you have the following route:
Route::post('form/process', function()
{
# code here ...
});
Then you need to have the following form definition:
<form action="/form/process" method="POST">
I hope that helps.
I have same problem with OSx + MAMP, initially I've resolved with Raul's solution:
{{ Form::open(array('url' => ' ', 'method' => 'post')) }}
but after consultation with my friend we have concluded that my problem was due to the fact
my lavarel project is avaliable by long local path, as:
http://localhost/custom/custom2/...
in this location the post/get method on root path ("/") not working correctly.
Lavarel to working correctly must be avaliable by "vhost", in this case the problem get/post method on root location "/" not exist.
My friend advised me to use http://www.vagrantup.com/
BYE
There is some helpfull information in the Laravel Docs. Check these out:
Resource Controllers (or RESTful Controllers)
Forms & HTML
Opening A Form
Routing
Named Routes
I recommend you read the Resource Controllers documentation as it makes form handling a lot easier.
Well, you just return the view, so nothing change. You should bind your route to a controller to do some logic and add data to your view, like this:
index.blade.php
#extends('master')
#section('container')
<div class="wrapper">
#if (isset($message))
<p>{{$message}}</p>
#endif
{{ Form::open(array('url' => '/', 'method' => 'post')) }}
{{ Form::text('url') }}
{{ Form::text('valid') }}
{{ Form::submit('shorten') }}
{{ Form::close() }}
</div><!-- /wrapper -->
#stop
Your routes
Routes::any('/', 'home#index');
You controller HomeController.php
public function index()
{
$data = array();
$url = Input::get('url');
if ($url)
$data['message'] = "foo";
return View::make('index', $data);
}
You can also modify your current routes without using a controller like this (use the new view file)
Route::get('/', function()
{
return View::make('index');
});
Route::post('/', function()
{
return View::make('index')->with('message', 'Foo');
});
The problem is with defualt slashed in Apache from 2.0.51 and heigher:
http://httpd.apache.org/docs/2.2/mod/mod_dir.html#directoryslash
The best solution if you do not want to change Apache config is to make the post in a different path:
GOOD:
Route::get('/',
['as' => 'wizard', 'uses' => 'WizardController#create']);
Route::post('wizard-post',
['as' => 'wizard_store', 'uses' => 'WizardController#store']);
NOT GOOD:
Route::get('/',
['as' => 'wizard', 'uses' => 'WizardController#create']);
Route::post('/',
['as' => 'wizard_store', 'uses' => 'WizardController#store']);

Categories