I am creating a backend page that i want to use to manage employee data (with laravel 5.8). I Added a link on a sidemenu blade that points to the employee overview page.
Link:
<li class="nav-item">
<a href="{{ action('Profiles\Controllers\EmployeeController#index') }}"
class="nav-link {{ Request::is('admin') ? 'active' : null }}">
<i class="fas fa-user"></i> Employees
</a>
</li>
I also made a controller to fetch the data that i want to display, currently with dd() in the function.
class EmployeeController extends Controller
{
public $model = CustomerLogin::class;
protected $views = 'WebshopCustomers::customerslogins ';
static $routes = ['index', 'create', 'store', 'edit', 'update', 'destroy'];
protected $datatableSelect = 'customer_logins';
protected $datatableRelations = ['roles', 'permissions'];
protected $datatableTrashed = true;
protected $datatableRawColumns = ['email', 'deleted_at'];
public function baseBreadcrumbs()
{
return [
['name' => 'Gebruikersbeheer']
];
}
public function index()
{
dd('test_index');
}
}
After a reloaded the page shows the following error:
ErrorException (E_ERROR):
Action App\Modules\Profiles\Controllers\EmployeeController#index not defined.
(View: C:\xampp\htdocs\shopname\app\Modules\Backend\Views\partials\sidebar-default.blade.php)
Route:
I googled this error and read advice to check if the route to the function existed (it didnt) so i added that.
Route::get('/', 'EmployeeController#index')->name('employeeprofiles.index');
Changing the value of $namespace to null in the RouteServiceProvider was also mentioned, setting it to null did not change the current behavior of my code.
How can i correct this, what other things can i check?
in Laravel 5.8 in the RouteServiceProvider the namespace for routes was pointed to:
App/Http/Controllers
in the new Laravel I think they removed it.
Now for your problem, you should check where is the namespace from RouteServiceProvider pointing too, and then adding extra 'directories' on it; e.g
Route::get('/',
'App\Modules\Profiles\Controllers#index')->name('employeeprofiles.index');
Related
Longtime googler, first time asker here. Hi, folks.
I am debugging and updating my app after updating it from Laravel 5.1.10 to 5.6
and this bug is proving hard to google.
Exploring my error message “Trying to get property of non-object” I think what is happening is that the nested relationship path that used to work just fine to give me the object, is now instead giving me an array of its attributes.
More code below, but here is the snippet from my view:
#section('content')
<h2>
<?php // Header: project number and title ?>
#if ($bookingDefault->project->courseNumber)
{{ $bookingDefault->project->courseNumber }}:
#endif
This results in error:
Trying to get property 'courseNumber' of non-object
It’s not returning a null; the data is there and it works perfectly fine if I access the project as an array thus:
#section('content')
<h2>
<?php // Header: project number and title ?>
#if ($bookingDefault->project['courseNumber'])
{{ $bookingDefault->project['courseNumber'] }}:
#endif
So I know that the relationships are defined okay because it is finding the project. It’s just not giving a proper object to the view anymore.
I could change a large number of views to access attributes as an array instead, but that is a lot of code to comb through and change, and doesn’t give me access to the object’s methods. I would rather fix why I am getting an array instead of the object I was getting before.
CODE THAT MAY BE RELEVANT:
from app/Http/Kernel.php (partial) - I checked that SubstituteBindings::class is there.
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
from routes/web.php (partial) - all my old Route::model and Route::bind are still there. I wasn’t sure if I was supposed to take them out or put them somewhere else but fiddling with it didn’t change anything. I tried moving them to RouteServiceProvider’s boot() function but that didn’t change anything so I put them back into web.php.
Route::model('bookingdefaults', 'BookingDefault');
Route::model('bookings', 'Booking');
Route::model('people', 'User');
Route::model('projects', 'Project');
Route::bind('bookingdefaults', function($value, $route) {return App\BookingDefault::where('id', $value)->first();});
Route::bind('bookings', function($value, $route) {return App\Booking::where('id', $value)->first();});
Route::bind('people', function($value, $route) {return App\User::where('id', $value)->first();});
Route::bind('projects', function($value, $route) {return App\Project::where('id', $value)->first();});
In the models - again, not the complete code which is long:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class BookingDefault extends Model
{
protected $guarded = [];
// RELATIONSHIPS
// always belongs to a certain project
public function project()
{
return $this->belongsTo('App\Project');
}
// always happens a certain place
public function location()
{
return $this->belongsTo('App\Location');
}
// many bookings could be made from this default
public function bookings()
{
return $this->hasMany('App\Booking');
}
// each booking default will suggest several roles that might be filled in a booking
public function bookingDefaultRoleAssignments()
{
return $this->hasMany('App\BookingDefaultRoleAssignment');
}
// somtimes it is defining a default of a certain type, but if this is a
// customized default then it may not belong to a bookingType
public function bookingType()
{
return $this->belongsTo('App\BookingType');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Mail;
use App\Booking;
class Project extends Model
{
protected $guarded = [];
// RELATIONSHIPS
public function bookings()
{
return $this->hasMany('App\Booking');
}
// a project can have defaults for several types of booking
public function bookingDefaults()
{
return $this->hasMany('App\BookingDefault');
}
// there will be many assignments of users to this project in various roles
public function projectRoleAssignments()
{
return $this->hasMany('App\ProjectRoleAssignment');
}
public function projectType()
{
return $this->belongsTo('App\ProjectType');
}
}
from BookingDefaultsController.php (partial - actual controller is over 1000 lines)
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Database\Eloquent\Collection;
use App\User;
use App\Booking;
use App\BookingDefault;
use App\BookingDefaultRoleAssignment;
use App\BookingRoleAssignment;
use App\BookingRole;
use App\BookingType;
use App\Location;
use App\Project;
use App\Qualification;
use Illuminate\Support\Facades\DB;
use Input;
use Redirect;
use Mail;
class BookingDefaultsController extends Controller
{
/**
* Show the form for editing the specified resource.
*/
public function edit(BookingDefault $bookingDefault)
{
// We'll need all the options for form dropdowns
$locations = Location::where('status', 'active')->orderby('location_name')->get();
$bookingTypes = BookingType::all();
$bookingRoles = BookingRole::all();
$qualifications = Qualification::all();
return view('bookingdefaults.edit',
compact('bookingDefault', 'locations', 'bookingTypes', 'bookingRoles', 'qualifications'));
}
}
And finally the view, from /resources/views/bookingdefaults/edit.blade.php
#extends('layout')
#section('title')
Staffstuff Edit Booking Default
#stop
#section('php')
{{ $user = Auth::user() }}
#stop
#section('navtag')
<div id="projpage">
#stop
#section('javascript')
#stop
#section('content')
<h2>
<?php // Header: project number and title ?>
#if ($bookingDefault->project->courseNumber)
{{ $bookingDefault->project->courseNumber }}:
#endif
#if ($bookingDefault->project->shortTitle) {{ $bookingDefault->project->shortTitle }}
#elseif ($bookingDefault->project->title) {{ $bookingDefault->project->title }}
#endif
<br />Booking Default:
</h2>
<?php // Form to edit the basic booking info, time, place ?>
{!! Form::model($bookingDefault, ['method' => 'PATCH', 'route' => ['bookingdefaults.update', $bookingDefault->id]]) !!}
{!! Form::hidden('id', $bookingDefault->id) !!}
{!! Form::hidden('project_id', $bookingDefault->project_id) !!}
#include('/partials/bookingdefaultform', ['submit_text' => 'Update Default'])
<div class="form-group">
{!! Form::label('update_existing', 'Update existing bookings (see below): ') !!}
{!! Form::checkbox('update_existing', 'value', TRUE) !!}
<br />Note that NOT updating existing bookings will decouple them from this default and they will need to be updated individually.
</div>
{!! Form::close() !!}
<p>
DONE EDITING
</p>
#stop
The exact error:
ErrorException (E_ERROR)
Trying to get property 'courseNumber' of non-object (View: /Users/redacted/Sites/testproject032418/resources/views/bookingdefaults/edit.blade.php)
This should work:
In your RouteServiceProvider (might also work in routes) change from plural to singular and add the full namespace to the 2nd argument:
Route::model('bookingdefault', App\BookingDefault::class);
// or: Route::model('bookingdefault', 'App\BookingDefault');
The rest is fine.
You'll probably need to do this for other models as well.
Edit
This is exactly what I tried on my testing project. GrandChild is just some random model I had set up:
RouteServiceProvider:
public function boot()
{
parent::boot();
Route::model('grandchild', \App\GrandChild::class);
}
Routes:
Route::resource('grandchildren', 'GrandChildController');
GrandChildController:
public function show(GrandChild $canBeWhatever)
{
return $canBeWhatever;
}
And it works:
I'm learning laravel, working with 3 files, Welcome.blade.php / route.php / tryaction.php and it's a controller.
I made three links that fetched from database table => hug, greet and slap
when I click any link it gives me an error that actions is not defined.
my Welcome.blade.php:
<ul>
#foreach ($actions as $action)
<li>{{$action->name}}</li>
#endforeach
</ul>
my route.php:
<?php
Route::get('/', [
'uses' => 'tryaction#getHome',
]);
//to deal with get requests
Route::get('/{action}/{name?}', [
'uses' => 'tryaction#doget',
'as' => 'benice'
]);
my tryaction.php controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\actionstable;
class tryaction extends Controller
{
public function doget($action, $name = null){
return view('actions.'.$action,['name'=>$name]);
}
public function getHome(){
$actions = actionstable::all();
return view('welcome',['actions'=>$actions]);
}
}
when I replace the href route in welcome.blade.php with # instead of {{ route('benice', ['action' => $action->name]) }} the error stops from showing on
the data are fetched correctly and the data is shown on the page .. the problem in the route and it's that the actions is not defined, here is the error page:
This is code snippet from my view file.
#foreach($infolist as $info)
{{$info->prisw}} / {{$info->secsw}}
#endforeach
Here is my route which I defined inside route file
Route::get('switchinfo','SwitchinfoController');
I want to pass two values inside href tag to above route and retrieve them in controller. Can someone provide code to do this thing?
Since you are trying to pass two parameters to your controller,
You controller could look like this:
<?php namespace App\Http\Controllers;
class SwitchinfoController extends Controller{
public function switchInfo($prisw, $secsw){
//do stuffs here with $prisw and $secsw
}
}
Your router could look like this
$router->get('/switchinfo/{prisw}/{secsw}',[
'uses' => 'SwitchinfoController#switchInfo',
'as' => 'switch'
]);
Then in your Blade
#foreach($infolist as $info)
Link
#endforeach
Name your route:
Route::get('switchinfo/{parameter}', [
'as'=> 'test',
'uses'=>'SwitchinfoController#function'
]);
Pass an array with the parameters you want
<a href="{{route('test', ['parameter' => 1])}}">
{{$info->prisw}} / {{$info->secsw}}
</a>
and in controller function use
function ($parameter) {
// do stuff
}
Or if don't want to bind parameter to url and want just $_GET parameter like url/?parameter=1
You may use it like this
Route::get('switchinfo', [
'as'=> 'test',
'uses'=>'SwitchinfoController#function'
]);
function (){
Input::get('parameter');
}
Docs
You can simply pass parameter in your url like
#foreach($infolist as $info)
<a href="{{ url('switchinfo/'.$info->prisw.'/'.$info->secsw.'/') }}">
{{$info->prisw}} / {{$info->secsw}}
</a>
#endforeach
and route
Route::get('switchinfo/{prisw}/{secsw}', 'SwitchinfoController#functionname');
and function in controller
public functionname($prisw, $secsw){
// your code here
}
I am trying to display the currently logged in username, as a link to the user info, in my main navigation. I can get the name to display, so I am pulling the info from the db, and passing it to the view OK. But, when I try to make it a link, I get the method not defined error.
Here is how I pass the user info to the navigation (as the var $userInfo):
public function index()
{
$Clients = \Auth::user()->clients()->get();
$userInfo = \Auth::user();
return view('clients.index', compact('Clients', 'userInfo'));
}
Here is the relevant bit from my navigation:
<ul class="nav navbar-nav">
<li>{!! link_to_action('AuthController#show', $userInfo->username, [$userInfo->id]) !!}</li>
</ul>
The method from my controller:
protected function show($id)
{
$userInfo = User::findOrFail($id);
return view('users.show', compact('userInfo'));
}
And, the route definition:
// User Display routes
Route::get('auth/{id}', 'Auth\AuthController#show');
Here is the error I get:
Action App\Http\Controllers\AuthController#show not defined.
Can anyone tell me what I am missing?
First, you need to make your AuthController::show() method public:
public function show($id)
{
$userInfo = User::findOrFail($id);
return view('users.show', compact('userInfo'));
}
Second, as your controllere is in App\Http\Controllers\Auth namespace, you need to use the **Auth** prefix in the view:
<ul class="nav navbar-nav">
<li>{!! link_to_action('Auth\AuthController#show', $userInfo->username, [$userInfo->id]) !!}</li>
</ul>
In Twig partial rendered by separate controller, I want to check if current main route equals to compared route, so I can mark list item as active.
How can I do that? Trying to get current route in BarController like:
$route = $request->get('_route');
returns null.
Uri is also not what I'm looking for, as calling below code in bar's twig:
app.request.uri
returns route similar to: localhost/_fragment?path=path_to_bar_route
Full example
Main Controller:
FooController extends Controller{
public function fooAction(){}
}
fooAction twig:
...some stuff...
{{ render(controller('FooBundle:Bar:bar')) }}
...some stuff...
Bar controller:
BarController extends Controller{
public function barAction(){}
}
barAction twig:
<ul>
<li class="{{ (item1route == currentroute) ? 'active' : ''}}">
Item 1
</li>
<li class="{{ (item2route == currentroute) ? 'active' : ''}}">
Item 2
</li>
<li class="{{ (item3route == currentroute) ? 'active' : ''}}">
Item 3
</li>
</ul>
pabgaran's solution should work. However, the original problem occurs probably because of the request_stack.
http://symfony.com/blog/new-in-symfony-2-4-the-request-stack
Since you are in a subrequest, you should be able to get top-level (master) Request and get _route. Something like this:
public function barAction(Request $request) {
$stack = $this->get('request_stack');
$masterRequest = $stack->getMasterRequest();
$currentRoute = $masterRequest->get('_route');
...
return $this->render('Template', array('current_route' => $currentRoute );
}
Haven't run this but it should work...
I think that the best solution in your case is past the current main route in the render:
{{ render(controller('FooBundle:Bar:bar', {'current_route' : app.request.uri})) }}
Next, return it in the response:
public function barAction(Request $request) {
...
return $this->render('Template', array('current_route' => $request->query->get('current_route'));
}
And in your template compares with the received value.
Otherwise, maybe is better to use a include instead a render, if you don't need extra logic for the partial.
in twig you can send request object from main controller to sub-controller as parameter:
{{ render(controller('FooBundle:Bar:bar', {'request' : app.request})) }}
in sub-controller:
BarController extends Controller{
public function barAction(Request $request){
// here you can use request object as regular
$country = $request->attributes->get('route_country');
}
}