Laravel console command trait method not found - php

I have a Laravel project that has been deployed with Forge and had OPCache enabled using Forge. I noticed last week that when I pushed some changes, the changes that were in the views and in the controllers were present on the server, but custom artisan commands that I run don't recognize updates.
Put another way, updates to the blades are showing on the screen. Updates that I have added to the controllers are changing the way information is passed to the blade files, but I have a custom artisan command that runs a series of methods in a trait. The actual file on the server shows the new method that I pushed, but when I run the artisan command in the CLI, it says that the method cannot be found.
I have stopped, restarted, and reloaded OPCache countless times. I have restarted Nginx. I have disabled OPCache and restarted PHP. It is still saying that the method is not found. Does anyone have any ideas?
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Traits\FTPImportsTrait;
class CheckFTPImports extends Command
{
use FTPImportsTrait;
protected $signature = 'checkForImports';
protected $description = 'Check for imports...';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$this->checkBankImports();
}
}
-----------
<?php
namespace App\Traits;
trait FTPImportsTrait;
{
public function checkBankImports()
{
dd('YOU ARE NOT CRAZY');
}
}
$ php artisan checkForImports
$ method checkBankImports does not exist.
UPDATE:
It has to be some sort of configuration issue on the server. I just deployed the project to a fresh DO droplet and the command works as expected.

It only happened in the production environment for me.
Running:
php artisan clear-compiled
deleted the cached version and solved my issue.
Thanks a ton to #num8er.

Related

Laravel Horizon running but no route (local)

I'm trying to add Horizon to my latest laravel app but when i visit my url with the horizon path (https://my-app.com/horizon) I get a 404, php artisan routes:list doesn't contain any routes to horizon. I have ran php artisan route:clear and no joy either.
I followed the official docs (https://laravel.com/docs/9.x/horizon) So i did the following commands:
composer require laravel/horizon
php artisan horizon:install
and edited the config to use redis. I'm using a local environment at the moment so the gate would not be needed (right?) I am also using spatie/permissions so with a permission of access horizon i edited the HorizonServiceProvider.php file as follows:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Laravel\Horizon\Horizon;
use Laravel\Horizon\HorizonApplicationServiceProvider;
class HorizonServiceProvider extends HorizonApplicationServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
parent::boot();
}
/**
* Register the Horizon gate.
*
* This gate determines who can access Horizon in non-local environments.
*
* #return void
*/
protected function gate()
{
Gate::define('viewHorizon', function ($user) {
return $user->can( 'access horizon' );
});
}
}
This should allow the user if they have the access horizon permission and refuse otherwise (but I'm on local so will run anyway?)
I'm using laravel 9.23 with php8.1 and have redis enabled. I also see that horizon is running php artisan horizonand then php artisan horizon:status says Horizon is running.
Have I missed something? So Horizon is running redis is enabled and set to use the queue, no horizon route in my route list and if i visit the url i obviously get a 404 error.
After power down for the weekend and startup this morning Horizon is now working!

Kernel does not exist in laravel

I have already developed project in laravel and i'm setting up it in my local computer but after running php artisan serve i'm getting this error
PHP Fatal error: Uncaught ReflectionException: Class App\Console\Kernel does not exist in C:\xampp\htdocs\translate\vendor\laravel\framework\src\Illuminate\Container\Container.php:788
I don't know what is wrong but I have tried everything that I have found on internet
composer update
composer dump-autoload
composer self-update
php artisan config:clear
php artisan cache:clear
none of that command worked for me
You must run composer install for installing the new dependencies.
Since you mentioned that you have issues with your other artisan commands delete everything inside the bootstrap->cache folder, except of the .gitignore file of course, manually and then run php artisan optimize
That way your "corrupted" cache will be recreated and reconfigured.
First thing you must do is to make sure your artisan commands are working right, so do the caching fix i suggest first. Then you can run the composer commands you mentioned also in your question.
Check you have this file in app/Console folder
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
/*$schedule->command('users:update')->everyMinute();
$schedule->command('servers:update')->everyMinute();*/
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}

Laravel on App Engine Standard: The /srv/bootstrap/cache directory must be present and writable

I've been struggling with the Google App Engine Standard environment for a day now.
The error is as follows:
PHP Notice: Exception: The /srv/bootstrap/cache directory must be
present and writable. in
/srv/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php:168
I know that the /tmp folder is the only writable folder for the App Engine Standard environment. Therefore, my app.yaml have the following additional env_variables:
APP_STORAGE: "/tmp"
VIEW_COMPILED_PATH: "/tmp"
...my bootstrap/app.php contains this line:
$app->useStoragePath(env('APP_STORAGE', base_path() . '/tmp'));
...and my composer.json has these scripts to account for the change in configuration:
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump"
],
"post-install-cmd": [
"composer dump-autoload",
"php artisan config:clear",
"php artisan cache:clear",
"php artisan view:clear",
"php artisan cache:clear",
"php artisan regenerate:schoolCSS"
]
These are my drivers configured in app.yaml:
SESSION_DRIVER: database
BROADCAST_DRIVER: log
CACHE_DRIVER: database
QUEUE_DRIVER: sync
For some reason, I just can't seem to find a way to make the /tmp folder the folder where the cached views and config are put. Actually, I suspect that the ...:clear commands aren't even properly ran at all.
My application is just a blank white page now, regardless of the path. That's fair, as due to the unwritable cache, the views cannot be rendered and stored there.
The above configurations should match the tutorials for installing Laraval on Google App Engine Standard, such as this one: https://cloud.google.com/community/tutorials/run-laravel-on-appengine-standard.
In the cloud console, I've checked whether the /tmp folder exists, which is the case.
Anyways, all help is dearly appreciated. If you need more code snippets, just ask. I'll be happy to provide them.
I found a simple solution for this problem. The directory where the Laravel application lives on Google App Engine Standard is read-only. So you have to write the cache files to /tmp.
You can change the paths by simple adding this environment variables to your app.yaml
APP_SERVICES_CACHE: /tmp/services.php
APP_PACKAGES_CACHE: /tmp/packages.php
APP_CONFIG_CACHE: /tmp/config.php
APP_ROUTES_CACHE: /tmp/routes.php
Your app.yaml and bootstrap/app.php look good.
But there is one more thing that you need to do:
If you're on Laravel 6 or above, remove facade/ignition dependency:
composer remove --dev facade/ignition
OR
If you're on Laravel 5 or older, remove beyondcode/laravel-dump-server instead:
composer remove --dev beyondcode/laravel-dump-server
This is what the community doc that you mentioned has to say about this:
This is a fix for an error which happens as a result of Laravel's caching in bootstrap/cache/services.php.
Community tutorial on setting up Laravel in App Engine Standard Environment.
Before deploying try:
php artisan route:clear
php artisan view:clear
php artisan config:clear
php artisan cache:clear
php artisan optimize:clear
For me it was optimize:clear
Could this be related to the fact that in Illuminate\Foundation\Application.php the paths are resolved from $this->bootstrapPath() (which returns an absolute path) when executed normally but seem to be taken as is from the APP_CONFIG_CACHE variable and others when running tests ?
/**
* Get the path to the configuration cache file.
*
* #return string
*/
public function getCachedConfigPath()
{
return Env::get('APP_CONFIG_CACHE', $this->bootstrapPath().'/cache/config.php');
}
Replacing it like this seems to do the job on my side.
/**
* Get the path to the cached services.php file.
*
* #return string
*/
public function getCachedServicesPath()
{
return $this->basePath(Env::get('APP_SERVICES_CACHE', 'bootstrap/cache/services.php'));
}
/**
* Get the path to the cached packages.php file.
*
* #return string
*/
public function getCachedPackagesPath()
{
return $this->basePath(Env::get('APP_PACKAGES_CACHE', 'bootstrap/cache/packages.php'));
}
/**
* Get the path to the configuration cache file.
*
* #return string
*/
public function getCachedConfigPath()
{
return $this->basePath(Env::get('APP_CONFIG_CACHE', 'bootstrap/cache/config.php'));
}
/**
* Get the path to the routes cache file.
*
* #return string
*/
public function getCachedRoutesPath()
{
return $this->basePath(Env::get('APP_ROUTES_CACHE', 'bootstrap/cache/routes.php'));
}
/**
* Get the path to the events cache file.
*
* #return string
*/
public function getCachedEventsPath()
{
return $this->basePath(Env::get('APP_EVENTS_CACHE', 'bootstrap/cache/events.php'));
}
Then
give permission
sudo chmod -R 775 bootstrap/cache/
Run the bellow command
php artisan config:cache

Ignore a custom Laravel Artisan command on production

I've written a custom Artisan command (let's call it MyDusk.php) that expands/abstracts some of the functionality of the core Dusk command.
This custom command extends Laravel\Dusk\Console\DuskCommand from within the Dusk package.
The problem is, on production the Dusk package is not installed (it's under require-dev in composer.json)
So when composer is generating its autoload files on production, it errors out when it gets to MyDusk.php because it can't find Laravel\Dusk\Console\DuskCommand.
PHP Fatal error: Class 'Laravel\Dusk\Console\DuskCommand' not found in app/Console/Commands/Dusk.php on line 10
In Dusk.php line 10:
Class 'Laravel\Dusk\Console\DuskCommand' not found
I tried moving the Dusk package to require so it would be available on production (not ideal, I know), but there's a line in the core Dusk service provider that throws an exception when it's run on production preventing this:
# From: vendor/laravel/dusk/src/DuskServiceProvider.php
if ($this->app->environment('production')) {
throw new Exception('It is unsafe to run Dusk in production.');
}
I'm trying to think of the most elegant solution to allow for my custom Dusk command to be part of the application and accessible locally, without throwing errors on production.
One idea: Write my Dusk command as its own package, that's also only in require-dev.
Any other ideas?
I just took a look at the API, you could do this:
You could move your command to App\Console\Commmands\Local\DuskCommand.php.
By default, if you check the commands() method in the Kernel, it's only going to load commands found in App\Console\Commands. This will not include the sub-directories.
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
This is the default commands() method. You could switch this implementation to the one below:
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$paths = [
__DIR__ . '/Commands'
];
if(app()->environment('local')) {
$paths[] = __DIR__ . '/Commands/Local';
}
$this->load($paths);
require base_path('routes/console.php');
}
So, in local, we are also going to load commands based in App\Console\Commands\Local.
Admittedly, I didn't give this a try myself, but I am assuming that it should work.
Edit: I gave it a try and it seems to be working just fine. I thought, I'd try to explain it a bit more. Basically, after doing a composer dump-autoload, Laravel is listening to this event and doing two things:
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"#php artisan package:discover --ansi"
]
The second one is trying to run the Auto-Package Discovery command and this is where it will fail. The Artisan executable actually boots the application with the Console Kernel.
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);
While resolving the Kernel, it will also try to boot up the Commands that it needs so that they are available to Artisan, and this is where it fails.
However, like I mentioned above, if you only boot the Commands you need in production, this issue won't happen.
Accepted answer seems not to work in Laravel 6. This worked for me:
Create your command with php artisan make:command YourCommand and move it to app/Console/Local.
Change its namespace to App\Console\Local.
Then, in app/Console/Kernel.php:
protected function commands()
{
$paths = [
__DIR__ . '/Commands'
];
if(app()->environment('local')) {
$paths[] = __DIR__ . '/Local';
}
$this->load($paths);
require base_path('routes/console.php');
}
Enjoy ;)

PhpStorm - Some warnings on Laravel facades

I make right usage of Laravel's facades and PhpStorm gives me warnings, why is that?
And on image I pointed "x" for some...types of data? In functions I use, why do I have these? How to remove them?
Using facades with Laravel
Luke Waite is right:
You're not using facades. You've imported the classes, and on the
first, Categories, the IDE is telling you that the get method is not a
static method.
Just import the facade instead (if it exist).
See the documentation on Facades to learn more on how to use the available facades and how to define your own.
A facade class should look like this:
use Illuminate\Support\Facades\Facade;
class Cache extends Facade
{
/**
* Get the registered name of the component.
*
* #return string
*/
protected static function getFacadeAccessor()
{
return 'cache';
}
}
Where the 'cache' string is the name of a service container binding and defined in a service provider, something like this:
use App\Cache\MyCache;
use Illuminate\Support\ServiceProvider;
class CacheServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* #return void
*/
public function register()
{
$this->app->singleton('cache', function ($app) {
return new MyCache();
});
}
}
Fixing the warnings with Facades
That being said, I was tired of the warnings and the missing auto-completion and highlighting with facades so I also searched to find a way to fix these.
I came upon laravel-ide-helper which adds Laravel CLI commands that generates php files that only serves to be parsed by your IDE.
Install
Require this package with composer using the following command:
composer require barryvdh/laravel-ide-helper
After updating composer, add the service provider to the providers
array in config/app.php
Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class, To
install this package on only development systems, add the --dev flag
to your composer command:
composer require --dev barryvdh/laravel-ide-helper
In Laravel, instead of adding the service provider in the
config/app.php file, you can add the following code to your
app/Providers/AppServiceProvider.php file, within the register()
method:
public function register()
{
if ($this->app->environment() !== 'production') {
$this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
}
// ...
}
This will allow your application to load the Laravel IDE Helper on
non-production enviroments.
Automatic phpDoc generation for Laravel Facades
You can now re-generate the docs yourself (for future updates)
php artisan ide-helper:generate
Note: bootstrap/compiled.php has to be cleared first, so run php artisan clear-compiled before generating (and php artisan
optimize after).
You can configure your composer.json to do this after each commit:
"scripts":{
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan ide-helper:generate",
"php artisan ide-helper:meta",
"php artisan optimize"
]
},
The .phpstorm.meta.php and _ide_helper.php files will be generated and should be added to your .gitignore as you don't want to commit these.

Categories