I created an api which is delivered with package development composer. in Laravel 7 it was possible to add the route model binding with:
Route::group(['namespace' => 'Acme\Package\app\Http\Controllers\Api'], function () {
// fomer possibility:
Route::apiResource('api/comments/', 'CommentController')->middleware('bindings');});
In Laravel 8 that's not possible anymore. I've tried almost everything the last days, but either the route-model-binding is not working, or the class can't be found:
Target class [bindings] does not exist.
I really hope someone can post an answer to the problem, or a hint or anything useful.
many thanks in advance
EDIT:
Thanks for the answers, including the middleware in the Route::group like mentioned:
Route::group(['namespace' => 'Acme\Package\app\Http\Controllers\Api', 'middleware' => 'Illuminate\Routing\Middleware\SubstituteBindings']
did it.
In Laravel 8 the alias for this middleware has been removed. You can either use it by its full class name
Illuminate\Routing\Middleware\SubstituteBindings
or add the alias back in to your app/Http/Kernels.php in $routeMiddleware as follows:
protected $routeMiddleware = [
'auth' => Authenticate::class,
'bindings' => Illuminate\Routing\Middleware\SubstituteBindings,
/*...*/
You have to be careful if you are relying on values in someones application to exist. I could use a different name/alias for that middleware if I wanted to in my HTTP Kernel. You should be using the FQCN for that middleware that comes from the framework when referencing it like that.
In a default Laravel 8 install there is no middleware named/aliased as 'bindings'. It is referenced by its FQCN, Illuminate\Routing\Middleware\SubstituteBindings, which is how you should probably be referencing it from a package.
You can provide a config file for someone to alter these things if you would like. Then you can use your configuration to know which middleware to reference.
Cashier Paddle Version: 1.0#beta
Laravel Version: 7.0
PHP Version: 7.2.5
I am using cashier-paddle for one of my laravel 7 projects. I'm trying to apply a "one off" charge (Simple Charge) against a customer. I've followed the official documentation to integrate the package in my project but I am getting this issue "Simple Charge The checkout id must be a valid checkout id". Here are the steps that I have already completed.
Installed the official laravel cashier-paddle package using composer
require laravel/cashier-paddle
Published necessary migrations and added the necessary API Keys on my
env file
Added the #paddlejs in may master layout blade file and updated the
VerifyCsrfToken middleware so it except routes paddle/*
Added the Billable trait to the User model Configured the webhook
route and controller
// Route example
Route::post('paddle/webhook','WebhookController#handleWebhook')->name('cashier.webhook')
// WebhookController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Laravel\Paddle\Http\Controllers\WebhookController as CashierController;
class WebhookController extends CashierController
{
public function handleWebhook(Request $request)
{
logger('I can reach here!');
}
public function handlePaymentSucceeded($payload)
{
}
}
Generated the paylink variable using my controller.
// paylink variable from controller
$payLink = auth()->user()->charge(12.99, 'Test Product Title');
Finally used the variable on the paddle-button Blade component
// Blade file
<x-paddle-button :url="$payLink" class="px-8 py-4">
Buy
</x-paddle-button>
Note: The simple charge is not working but the charge for a specific product is working fine. For example this one auth()->user()->chargeProduct(619859) is working fine.
These are the steps that I have already followed to integrate the paddle simple chare on my laravel application. Hope that information may help you. Let me know if I am doing anything wrong or missed any steps. I will be really very thankful if anyone can help me to solve the issue. Thanks in advance.
Thanks for visiting the question. After doing some research I've fixed the issue. Everything was fine. Just need to specify the webhook URL in the charge method. I think it was not mentioned in laravel documentation. I'm posting the answer so anyone can get a solution in the future.
// paylink variable from controller
$payLink = auth()->user()->charge($total, 'Product Title', [
'webhook_url' => 'webhook URL here',
]);
I have been using Eloquent as a standalone package in Slim Framework 2 successfully.
But now that I want to make use of Illuminate\Support\Facades\DB since I need to show some statistics by getting the info from 2 tables and using a Left Join and a Counter from the database like this:
use Illuminate\Support\Facades\DB;
$projectsbyarea = DB::table('projects AS p')
->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
->leftJoin('areas AS a','p.area_id','=','a.id')
->where('p.status','in_process')
->where('a.area','<>','NULL')
->orderBy('p.area_id');
I get the following error:
Type: RuntimeException
Message: A facade root has not been set.
File: ...\vendor\illuminate\support\Facades\Facade.php
Line: 206
How can I solve it?
So far I have found out, in this link that I need to create a new app container and then bind it to the Facade. But I haven't found out how to make it work.
This is how I started the rest of my Eloquent and working fine:
use Illuminate\Database\Capsule\Manager as Capsule;
$capsule = new Capsule();
$capsule->addConnection([
'my' => $app->config->get('settings'),
/* more settings ...*/
]);
/*booting Eloquent*/
$capsule->bootEloquent();
How do I fix this?
Fixed
As #user5972059 said, I had to add $capsule->setAsGlobal();//This is important to make work the DB (Capsule) just above $capsule->bootEloquent();
Then, the query is executed like this:
use Illuminate\Database\Capsule\Manager as Capsule;
$projectsbyarea = Capsule::table('projects AS p')
->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
->leftJoin('areas AS a','p.area_id','=','a.id')
->where('p.status','in_process')
->where('a.area','<>','NULL')
->orderBy('p.area_id')
->get();
You have to change your code to:
$Capsule = new Capsule;
$Capsule->addConnection(config::get('database'));
$Capsule->setAsGlobal(); //this is important
$Capsule->bootEloquent();
And at the beginning of your class file you have to import:
use Illuminate\Database\Capsule\Manager as DB;
I have just solved this problem by uncommenting $app->withFacades(); in bootstrap/app.php
Had the same issue with laravel 8. I replaced
use PHPUnit\Framework\TestCase;
with:
use Tests\TestCase;
Try uncommenting in app.php $app->withFacades();
Do not forget to call parent::setUp(); before.
fails
public function setUp(): void {
Config::set('something', true);
}
works
public function setUp(): void {
parent::setUp();
Config::set('something', true);
}
One random problem using phpUnit tests for laravel is that the laravel facades have not been initialized when testing.
Instead of using the standard PHPUnit TestCase class
class MyTestClass extends PHPUnit\Framework\TestCase
one can use
class UserTest extends Illuminate\Foundation\Testing\TestCase
and this problem is solved.
I got this error after running:
$ php artisan config:cache
The solution for me was to delete the /bootstrap/cache/config.php file. I'm running Laravel 5.5.
The seems to arise in multiple situation, and not just about facades.
I received the following message while running tests using PHPUnit v.9.5.4, PHP v.8.0.3 and Lumen v. 8.2.2:
PHP Fatal error: Uncaught RuntimeException: A facade root has not
been set. in path_to_project/vendor/illuminate/support/Facades/Facade.php:258
And that happened although I had apparently already configured my app.php to enable facades ($app->withFacades();), still I received this error message whenever I tried to run tests using Illuminate\Support\Facades\DB. Unfortunately, none of the other answers helped me.
This error was actually been thrown due to my configs in phpunit.xml, which didn't point to my app.php file, where I actually enabled facades.
I just had to change
<phpunit (...OTHER_PARAMS_HERE) bootstrap="vendor/autoload.php">
to
<phpunit (...OTHER_PARAMS_HERE) bootstrap="bootstrap/app.php">
Hope it helps.
wrong way
public function register()
{
$this->app->bind('Activity', function($app)
{
new Activity;
});
}
right way 👍
public function register()
{
$this->app->bind('Activity', function($app)
{
return new Activity;
});
}
---------------------------------- don't forget return
Upgrade version for php, I encountered this error while calling the interface.
$ php artisan config:cache
Deleting the /bootstrap/cache/config.php file is a very effective way.
In my project, I managed to fix this issue by using Laravel Dependency Injection when instantiating the object. Previously I had it like this:
$class = new MyClass(
new Client(),
env('client_id', 'test'),
Config::get('myapp.client_secret')
);
The same error message happened when I used Laravel env() and Config().
I introduced the Client and env in the AppServiceProvider like this:
$this->app->bind(
MyClass::class,
function () {
return new MyClass(
new Client(),
env('client_id', 'test')),
Config::get('myapp.client_secret')
);
}
and then instantiated the class like this:
$class = app(MyClass::class);
See more from https://laravel.com/docs/5.8/container .
In my case, for a while a ran a PHP project in PHP version 8, and that time I used some PHP 8 features like param definition and method's multiple return type declarations supported by only PHP 8 and above. When I downgraded from PHP 8 to PHP 7.4 I faced this issue. After removing the return types and param hinting the problems are gone.
Tested on Laravel 8.78
tests/bootstrap.php
<?php
use Illuminate\Foundation\Bootstrap\RegisterFacades;
use Illuminate\Foundation\Bootstrap\LoadConfiguration;
require_once __DIR__ . '/../vendor/autoload.php';
$app = require_once __DIR__ . '/../bootstrap/app.php';
(new LoadConfiguration())->bootstrap($app);// <------- Required for next line
(new RegisterFacades())->bootstrap($app);// <------- Add this line
Here is yet another instance of this error, happened to me after upgrading Laravel 8 to 9.
I had feature tests with a #dataProvider to supply data to those tests. Some of the data supplied by the data provider methods came from an application service. It was being initialised like this:
/**
* #dataProvider myDataProvider
*/
public function testSomeStuff(...)
{
...
}
public function myDataProvider()
{
$myService = app(Service::class); // This is trouble
return [
['test1_data' => $myService::SOME_CONSTANT],
[...],
...
];
}
This worked under Laravel 8, but not in Laravel 9. All other solutions listed in this SO thread were checked and were correctly set up.
The problem is that the application is not being inititialised until after the data provider method is run. It was presumably initialised before this stage in the Laravel 8 install. So app(Service::class) was failing due to it using facades internally.
One workaround could be to force the application to initialise earlier, in the data provider function: $this->createApplication(). I would not recommend this due to potential side effects of the test parts running in the wrong order, though it does appear to work when I tried it.
Best solution is to avoid accessing any part of the application functionality in the data provider methods. In my case it was easy to replace $myService::SOME_CONSTANT with MyService::SOME_CONSTANT after making sure those constants were public.
Hopefully this will help somebody suddenly hitting this problem running feature tests after a Laravel 9 upgrade.
If you recently upgrade Laravel on Homestead & VirtualBox environment or do not find any reason that causing please be sure your Vagrant is up to date.
Referance
I had Taylor lock this thread. The past several replies have restated the solution, which is to Upgrade to Virtualbox 6.x, the thread is locked to prevent other issues that are not related from being dogpiled on here.
#melvin's answer above works correctly.
In case someone is wondering about it, the mistake people do is to choose Yes when VSCode asks them if they are making a Unit Test. Remember, Unit Tests should really be unit tests, independent of other application features (models, factories, routes; basically anything that would require the Laravel app to be fired up). In most scenarios, people really actually want to make Feature Tests and therefore should answer No to the above question. A feature test inherits from Tests\TestCase class (which takes care of firing up Laravel app before running the test) unlike unit tests that inherit from the class PHPUnit\Framework\TestCase which use just PHPUnit and are therefore much faster.
credit with thanks to #Aken Roberts's answer here.
From Laravel Documentation: Generally, most of your tests should be feature tests. These types of tests provide the most confidence that your system as a whole is functioning as intended.
I have two (but let's image more) micro-services (API) which need to be aware of authenticated user. Ideally I would simple like to resume their sessions.
All micro-services are using same storage for sessions: redis.
All API calls will have Cookie header, so all services will be able to resume sessions based on that cookie. I have successfully implemented this via PHP $_SESSIONs.
Now the question: how would you go about implementing this with Laravel/Lumen?
Last update on 5th of March 2021
(This answer was getting a lot of attention from Laravel community so I thought of updating it.)
Laravel has officially stopped supporting sessions & views in laravel/lumen framework from version 5.2 and on wards.
But laravel still have a component illuminate/session which can be installed in lumen/framework and we can play around with this.
Step - 1
install illuminate/session using
composer require illuminate/session
Step - 2
Now goto bootstrap/app.php and add this middleware
$app->middleware([
\Illuminate\Session\Middleware\StartSession::class,
]);
Purpose of adding the above middleware is to start session on every request and save session before serving response.
Step - 3
Now add config/session.php, since it is not present in Lumen by default. You can take session.php from Laravel official repo.
Step - 4
Create framework session storage directory by
mkdir -p storage/framework/sessions
Thanks to DayDream
Step - 5
In bootstrap/app.php add bindings for \Illuminate\Session\SessionManager
$app->singleton(Illuminate\Session\SessionManager::class, function () use ($app) {
return $app->loadComponent('session', Illuminate\Session\SessionServiceProvider::class, 'session');
});
$app->singleton('session.store', function () use ($app) {
return $app->loadComponent('session', Illuminate\Session\SessionServiceProvider::class, 'session.store');
});
Thanks to #xxRockOnxx for finding loadComponent method.
It takes 3 arguments,
first one is config file name. (file should be present in config/ directory)
second is ServiceProvider FQN
third is return of this method.
loadComponent just calls the $app->register and inject $app while building the ServiceProvider
How to Use
// Save Session
$router->get('/', function (\Illuminate\Http\Request $request) {
$request->session()->put('name', 'Lumen-Session');
return response()->json([
'session.name' => $request->session()->get('name')
]);
});
// Test session
$router->get('/session', function (\Illuminate\Http\Request $request) {
return response()->json([
'session.name' => $request->session()->get('name'),
]);
});
I've also added example over github supporting from lumen framework v5.6 to all the way to current version v8.0.
https://github.com/rummykhan/lumen-session-example
It is important to that you also use $request->session(), otherwise it will not work.
I tried the solution mentioned above, however, it's also required to create a folder storage/framework/sessions if using the default settings.
The accepted answer is outdated.
I answered and explained a bit how to properly do it in my answer on this question
I also posted what is the problem on my question at Laracasts
To quote:
the solution that is found in the link you gave is that, first it tells you to manually register the SessionManager to prevent the unresolvable depedency parameter #0 $app then also register the existing SessionServiceProvider which also binds another instance SessionManager.
Problem with that is, some components use the other instance and other parts use the new one which causes my auth attempt session not being save despite actually being put inside.
I just upgraded from Laravel 5.2 to 5.3. I am using Laravel-DataTables package for several tables in my application.
After upgrade when I run artisan serve I'm receiving:
[BadMethodCallException]
Method controller does not exist.
I've tracked the issue down to this piece of code in my routes.php (now web.php)
Route::controller('datatables', 'ProfileController', [
'anyOrders' => 'datatables.dataOrders',
'anyProperties' => 'datatables.dataProperties',
]);
This is the suggested way to route the queries for DataTables Documentation.
Was the Route::controller() deprecated, and what is the alternative to for these routes?
The explicit routes will be:
Route::get('/datatables/orders', array('middleware' => 'auth', 'uses' => 'ProfileController#anyOrders'))->name('datatables.dataOrders');
Route::get('/datatables/properties', array('middleware' => 'auth', 'uses' => 'ProfileController#anyProperties'))->name('datatables.dataProperties');
I had the same issue as you, and none of the alternatives (explicit declaration or publishing) was good enough. There were also some alternatives which required changing too much code.
This is why I wrote a class called AdvancedRoute, which serves as a drop in replacement.
It can be used by simply replacing Route::controller with AdvancedRoute::controller like this:
AdvancedRoute::controller('users','UserController');
Full information how to install and use find at the GitHub repo at:
https://github.com/lesichkovm/laravel-advanced-route
Hope you find this useful.
https://laravel.com/docs/5.3/upgrade#upgrade-5.3.0
The following features are deprecated in 5.2 and will be removed in the 5.3 release in June 2016:
Implicit controller routes using Route::controller have been deprecated. Please use explicit route registration in your routes file. This will likely be extracted into a package.
You can use resource().
Route::resource('users','UserController');
Note: the "get" prefix is not needed. getIndex() = index()