Laravel 5's route helper doesn't work on fresh install - php

I am following a tutorial sayings that Laravel has a helper that permits to write the routes like that :
<?php
get('/', function () {
return view('welcome');
});
Instead of :
<?php
Route::get('/', function () {
return view('welcome');
});
(The "Route::" prefix is missing in the first one).
Since what i've looked the documentation (where I've found nothing really related but the providers involved), I correctly have in my providers :
'providers' => [
/*
* Laravel Framework Service Providers...
*/
(...)
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
(...)
/*
* Application Service Providers...
*/
(...)
App\Providers\RouteServiceProvider::class,
(...)
],
And the tutorial says that it has to work in a fresh install.

The router helper functions were removed in December. You can see the changes here:
https://github.com/laravel/framework/commit/62cbae78ba2d40944892c5a16f2d2463087bce23
In the upgrade guide, you can see what is deprecated and removed.
The get, post, and other route helper functions have been removed. You may use the Route facade instead.
Source: https://laravel.com/docs/5.2/upgrade

Related

Laravel Spatie Laravel-Navigation Route Error

I'm trying to make the Spatie Laravel-Navitation plugins to work on my project in Laravel 9.1.0
Spatie Laravel Navigation
So far I did :
Install the plugin with composer
add the plugin to the config/app.php provider
App\Providers\NavigationProvider::class,
Add the alias in the config/app.php aliases
'Navigation' => Spatie\Navigation\NavigationServiceProvider::class,
From what I understand I create a new provider
php artisan make:provider NavigationProvider
Inside the provider I add to the top
use Spatie\Navigation\Navigation;
Inside the handle function I add this
app(Navigation::class)
->add('dashboard', route('dashboard'));
I have the following error since:
Route [dashboard] not defined.
In my routes/web.php I have the following route.
Route::get('/', function () {
return view('pages.dashboard');
})->name('dashboard');
Any Idea what I miss.
Any tips also on how I will use this in the blade after making the route portion work.
Thank you for your help.
I maybe found the issue but I'm not sure it's the most elegant way to do this.
In my controller boot function I did this :
$this->app->booted(function () {
app(Navigation::class)
->add('dashboard', route('dashboard'));
});
view()->composer('*',function($view) {
$view->with('navigation', app(Navigation::class)->tree() );
$view->with('breadcrumbs', app(Navigation::class)->breadcrumbs() );
});

Laravel Feature Tests always return 404

I'm struggling to make my Feature Tests run with Laravel. I ran out of options. This is the error I get (with withoutExceptionHandling to show the URL):
• Tests\Feature\ClientTest > example
Symfony\Component\HttpKernel\Exception\NotFoundHttpException
GET http://localhost/sunny-camping/welcome
at vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:416
412▕ * #return \Symfony\Component\HttpFoundation\Response
413▕ */
414▕ protected function renderException($request, Throwable $e)
415▕ {
➜ 416▕ return $this->app[ExceptionHandler::class]->render($request, $e);
417▕ }
418▕
419▕ /**
420▕ * Get the application's route middleware groups.
+1 vendor frames
2 tests/Feature/ClientTest.php:19
Illuminate\Foundation\Testing\TestCase::get()
Obviously if I click the URL everything works fine, but the test gives me 404... The page itself is default welcome page from Laravel. Now for the files:
ClientTest.php
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class ClientTest extends TestCase
{
/**
* A basic feature test example.
*
* #return void
*/
public function test_example()
{
$this->withoutExceptionHandling();
$response = $this->get('/welcome');
$response->assertStatus(200);
}
}
web.php
<?php
use App\Http\Controllers\Admin\ClientController;
use App\Http\Controllers\AdminController;
use App\Http\Controllers\HomeController;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/{year?}', [HomeController::class, 'home'])->where('year', '[0-9]+')->name('home');
Route::prefix('/admin')->group(function () {
Route::prefix('/clients')->group(function () {
Route::get('/add-client', [ClientController::class, 'addClient']);
Route::get('/edit/{id}', [ClientController::class, 'edit'])->name('admin.clients.edit');
Route::put('/add', [ClientController::class, 'add']);
Route::patch('/update/{id}', [ClientController::class, 'update']);
Route::delete('/delete/{id}', [ClientController::class, 'delete']);
Route::get('/paginated-json', [ClientController::class, 'paginatedJson']);
Route::get('/find-json/{id}', [ClientController::class, 'findJson']);
});
Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard');
Route::get('/clients', [AdminController::class, 'clients'])->name('admin.clients');
Route::get('/bills', [AdminController::class, 'bills']);
Route::redirect('/', 'admin/dashboard');
});
Route::get('/welcome', function () {
return view('welcome');
});
I'm running everything from Windows Subsystem Linux, using Apache and MariaDB.
So far I tried multiple things:
php artisan serve (no clue why but it helped some people, not me though)
Different URIs
Making .env.testing file with APP_URL set to the same as .env file
Adding APP_URL to phpunit.xml file <server name="APP_URL" value="http://localhost/sunny-camping"/>
Pasting full URLs as the URI
Copying URIs from php artisan routes:list
Using `route('myroutename')' instead of URI
All of this to no avail. I keep getting 404 and I have no clue how to fix this. I went through multiple queries and over 2 pages of Google and found no solution...
Any ideas are appreciated.
Turns out, tests act in a (to me) very weird way. They use a different APP_URL than everything else.
So to fix this, you either have to set you APP_URL to just http://localhost in your .env.testing file, or add <server name="APP_URL" value="http://localhost"/> to your phpunit.xml file, given similar file structure. (Unfortunately I don't understand this enough to be able to tell how this will behave if your project is in deeper folders or non-local server)

Laravel - Package can't recognise Auth functions?

I made a package which is counting the visitors on a webpage. Currently I have a single route, controller and view which don't do very much other than display a simple string. I have a separate Laravel application where this package is specifically build for. In this separate application I have a layout file called backend.
layouts/layouts/backend.blade.php.
My package view is extending this template like so: (backend.blade.php does not exists in the package but in the separate laravel application of-course)
#extends('layouts.layouts.backend')
#section('content')
<div class="container-fluid pt-5 ">
<div class="row">
<div class="col-md-6">
<h3>{{ __('Visitors') }}</h3>
</div>
</div>
</div>
#endsection
The package successfully extends this layout but it can't find functions such as Auth::user()->token and it will say
Trying to get property 'token' of non-object (View: /Users/rainierlaan/Sites/rainierlaan/resources/views/layouts/layouts/backend.blade.php)
Why does this happen?
This is my packages service provider
public function register()
{
// Controllers
$this->app->make('Rainieren\Visitors\Http\Controllers\VisitorController');
// Views
$this->loadViewsFrom(__DIR__.'/resources/views', 'visitors');
$this->publishes([
__DIR__.'/resources/views' => resource_path('views/visitors'),
]);
// Migrations
$this->loadMigrationsFrom(__DIR__.'/database/migrations');
}
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
include __DIR__ . '/routes/routes.php';
}
When I do vendor:publish the view successfully publishes to the right folder but somehow can't recognise functions such as Auth::user()->token or Auth::user()->unreadNotifications->count())
This is my package route:
<?php
Route::get('dashboard/visitors', '\Rainieren\Visitors\Http\Controllers\VisitorController#index')->name('visitors');
And this is the controller
public function index()
{
return view('visitors::index');
}
I would need a little bit more debugging information but my first assumption is the missing AuthenticateSession or Authenticate middleware.
Laravel defines a default middleware group web for your routes inside routes/web.php and this group uses the AuthenticateSession middleware. This is how a new installation looks like:
Route::group([
'middleware' => 'web', <<< this is the magic part
'namespace' => $this->namespace,
], function ($router) {
require base_path('routes/web.php');
});
Here we see that the middleware group web is used.
In your custom module / service provider this is not the case. Your Route::get() definition is added to the Router but not inside this group. Therefore all necessary internals to authenticate the user are not performed.
In this scenario I would try to use ->middleware('auth') or ->middleware('web') which will use the main-projects group middleware.
Route::get('dashboard/visitors', '\Rainieren\Visitors\Http\Controllers\VisitorController#index')
->name('visitors')
->middleware('web');
Here is a different idea:
If you say you're always authenticated. Then you could try to move all web middlewares into the global middlewares within your Kernel (protected $middleware = []).
I did not tested this but I can imagine that this could work as well.
I have seen in all of my active packages that they don't use Auth class at all in the views.
Their workaround is using this in the controller and pass it to the view:
$user = auth()->user();
return view('folder.view' ,['user'=>$user]);
And then in the view:
{{$user->token}} <!-- OR --!> {{$user->unreadNotifications->count()}}
Obviously as #N69S has stated only if a user is authenticated this is going to work.
Hope this works!!
EDIT:(Sorry didn't understand well the first time)
The error is in your service provider class yo have to do all the logic on the boot function, not in the register, because if you do in the register function, you load all before the laravel framework (To say something)
https://laravel.com/docs/5.7/providers#the-register-method
Your serviceprovider should end like this:
public function register()
{
//Nothing
}
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
// Controllers
$this->app->make('Rainieren\Visitors\Http\Controllers\VisitorController');
// Views
$this->loadViewsFrom(__DIR__.'/resources/views', 'visitors');
$this->publishes([
__DIR__.'/resources/views' => resource_path('views/visitors'),
]);
// Migrations
$this->loadMigrationsFrom(__DIR__.'/database/migrations');
include __DIR__ . '/routes/routes.php';
}
Hope this finally works!

Laravel 5.4 - How to override route defined in a package?

I have created a package in Laravel 5.4 that sets up a basic backoffice. This package contains several routes that are using controllers from within the package. What I want to be able to do is to override the package defined routes in my application in order to plug custom controllers. For example, if I have a route
Route::get('login', [
'as' => 'admin.login',
'uses' => 'Auth\LoginController#showLoginForm'
]);
defined in my package that will use the Vendor\Package\Controllers\Auth\LoginController I want to defined a route for my application that will override that one and use the App\Controllers\Auth\LoginController.
Doing the obvious approach of defining the route in app routes files fails for the app routes files are run before the package routes file, so the package definition will prevail.
Is there any way to accomplish something of this kind?
I also tried to get the particular route in the RouteServiceProvider and use the method uses to set the controller that should be used to resolve it, like this
public function boot()
{
parent::boot();
Route::get('admin.login')->uses('App\Http\Controllers\Admin\Auth\LoginController#showLoginForm');
}
but this also fails to accomplish what is pretended.
Any clues on what I am doing wrong?
In config/app.php in the providers array put the service provider of the package before App\Providers\RouteServiceProvider::class, and then in your web.php routes you'll be able to override it with your custom route.
EDIT
For Laravel package auto discovery you can disable the package being auto discovered in your composer.json like this:
"extra": {
"laravel": {
"dont-discover": [
"barryvdh/laravel-debugbar"
]
}
},
In this example the barryvdh/laravel-debugbar package won't be autodiscovered, which means you would have to manually include its service provider in the config array and then you'll be able to rearrange your custom provider in the desired order.
Another option -- which doesn't have to muck with the order of service providers -- is to add a binding for the controller.
So e.g. in AppServiceProvider,
$this->app->bind(
\Vendor\Package\Controllers\Auth\LoginController::class,
App\Controllers\Auth\LoginController::class
);
You'll have to match controller method names, but you're doing that already in your example.
(Caveat on this answer: I haven't tested it in Laravel 5.4, but I just did this in Laravel 6.0 using the $bindings property which was added in Laravel 5.6. That said, this should be correct 5.4 syntax for doing the same thing).
Edit: For Laravel 6+ you can instead add the binding to the bindings array in AppServiceProvider:
public $bindings = [
\Vendor\Package\Controllers\Auth\LoginController::class =>
App\Controllers\Auth\LoginController::class,
// other bindings
]

Laravel 5.1 - How to dynamically prefix all registered routes

TL;DR: How to prefix all -already registered- Laravel routes?
Details:
- A large Laravel 5.1 application with third-party packages, each
register it's own routes.
- For some multilingual support, all routes have to be prefixed, without modifying these third-party packages.
- As you know in Laravel 5.1 the router service is being bound very early
before even custom service providers being called, so if router rebound the
application will have a detached router.
- So how could we prefix all currently registered routes?
- If no straight forward solution, in other words: how to replace the default \Illuminate\Routing\Router\Router::prefix() which seems to be a possible solution..
I know I'm bit late but in Laravel 5.4 we can achieve something like this:
Step 1 Create your package and create service provider in it.
Step 2 Register your package service provider in laravel config app.
Step 3 Now create a separate routes service provider which will contain following
namespace MyPackage\Providers;
use App\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Route;
class MyPackageRouteServiceProvider extends RouteServiceProvider
{
protected $namespace='MyPackage\Controllers';
public function boot()
{
parent::boot();
}
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
}
protected function mapApiRoutes()
{
Route::prefix('Mypackage\api')
->middleware('api')
->namespace($this->namespace)
->group(__DIR__ . '\..\Routes\api.php');
}
protected function mapWebRoutes()
{
Route::prefix('Mypackage')
->middleware('web')
->namespace($this->namespace)
->group(__DIR__ . '\..\Routes\web.php');
}
}
Note: I'm considering there is Routes Folder and contain web.php and api.php file. According to your question you want to load it dynamically you can have a constructor function and pass the package name, prefix and namespace as per your ease.
Step 4 Now the final step is registering the service provider you can call something like this in your package service provider:
public function boot()
{
$this->app->register('Mypackage\Providers\MyPackageRouteServiceProvider');
}
Hope this help others. Cheers
The best option for multilingual support without breaking the third-party packages is to remove the locale slug from the REQUEST_URI in the public/index.php .
$pattern = '/^\/(en|fr)\//';
$uri = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL);
if (preg_match($pattern, $uri, $matches)) {
$uri = preg_replace($pattern, '/', $uri);
$_SERVER['REQUEST_URI'] = $uri;
define('LOCALE', $matches[1]);
}
There is a Laravel package Linguist what does exactly that and helps with URL and html anchor tag generation for multilingual enironment.
https://github.com/keevitaja/linguist
You have posted no code snippet of your attempt, but seems that you are looking for route groups, which allows you to prefix, use middlewares and other stuff easily for a bunch of defined routes.
If you still need to add logic to your routing class you may wish to extend it.

Categories