Laravel: How to add signature option to migrate:rollback command? - laravel

I have multiple databases and the migrations for each database are stored in a different folder. Hence, I want to override the migrate:rollback command and add an option for a folder instead of specifying the path every time.
So instead of running the following command:
php artisan migrate:rollback --path=/database/migrations/{{folder}}
I want to run:
php artisan migrate:rollback {{folder}}
How can I achieve this?

protected $signature = 'test {folder}';
protected $description = 'Testing Purpose';
public function handle()
{
$this->ask('Enter Folder Name?');
$folder = $this->argument('folder');
$command = "migrate:rollback --path=/database/migrations/{$folder}";
Artisan::call($command);
}

Related

Laravel: how to simplify artisan commands?

I want to simplify the following artisan commands because I have several databases and the migrations for each database are stored in a separate folder.
php artisan make:migration {{name}} --path=/database/migrations/{{folder}}
php artisan migrate:rollback --path=/database/migrations/{{folder}}
to
php artisan make:migration {{name}} {{folder}}
php artisan migrate:rollback {{folder}}
Is this possible and if so how can I implement it?
Since this is not an option in the Laravel commands, a way to implement this yourself is by writing you own commands that call other artisan commands.
To do so, in your terminal write, for example, php artisan make:command MigrateWithPath to create a new command at app/Console/Commands/MigrateWithPath.php. Then, you can call the vanilla implementation Laravel provides at (vendor\laravel\framework\src) \Illuminate\Database\Console\Migrations\MigrateMakeCommand but then in a way that you specify.
Be sure though that the name of your new command needs to be different from the Laravel one, to prevent recursions. Therefore, I have prefixed the name with app: to be like app:make:migration, but feel free to use something else.
Take a look at the following suggestion:
class MigrateWithPath extends BaseCommand
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'app:make:migration {name : The name of the migration}
{folder? : The location where the migration file should be created}';
/**
* Execute the console command.
*
* #return int
*/
public function handle()
{
$this->call('make:migration', [
'name' => $this->argument('name'),
'--path' => '/database/migrations/' . $this->argument('folder'),
]);
return 0;
}
Then do the same for the rollback command.

How to run task scheduler locally on Laravel 7?

I want to learn how to use task scheduler in Laravel 7
According to the documentation, I created a task that should send out a test message to the mail on Mondays at 16:00. Judging by the documentation for local development, there is no need to add a cron entry. I just run the command php artisan schedule:work get this error Command "schedule:work" is not defined. Where am I making a mistake?
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
$test = 'test';
$email = Emails::where('id', 1)->first();
Mail::to($email)->send(new TestMail($test));
})->mondays()->at('16:00');
}
After I tried to add the line * * * * * cd /public_html/my_project && php artisan schedule:run >> /dev/null 2>&1 but got the following message bash: README_CI.md: command not found
you can try this
protected function schedule(Schedule $schedule)
{
$schedule->command('demo:cron')
->everyMinute();
}
you have cd /your/path. better do php /public_html/my_project/artisan schedule:run as cd'ing in cronjob does not work unless you have a bash script instead of inline.
as for schedule:work, that commmand should exist, does artisan (without arguments produce a list of options including schedule:work?

Custom Laravel Artisan Make Controller command

I want to put my controller generated by the artisan command to a custom directory. I made own command
php artisan make:command ApiControllerMake
and extended it
class ApiControllerMake extends ControllerMakeCommand
then I removed everything from there and overridden method
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace.'\Http\AppAPI\Controllers';
}
It's working OK.
Then I overridden
protected $signature = 'make:api-controller';
and after run
php artisan make:api-controller MyNewController
I got error
No arguments expected for "make:api-controller" command, got "MyNewController".
What is the problem?
Take a look at the ControllerMakeCommand, they use
protected $name = 'make:controller';
You probably have this:
protected $signature = 'make:api-controller';
So in your new class, replace $signature with $name.

Why does php artisan migrate fresh --seed is not working properly

Hi developers i have question regarding on php artisan migrate:refresh --seed VS php artisan db:seed I just wanted to ask because I have problem on php artisan migrate:refresh --seed, however when I use the php artisan db::seed it works properly
Now the data that I Created on my seeder is not seeding to the tables. I don't know why where the problem came from
Seeding: VehicleModelsSeeder
Seeded: VehicleModelsSeeder (0 seconds)
Here is my vehicle model seeder class
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use App\Vehicle;
use App\VehicleModel;
class VehicleModelsSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
//
$vehicles = Vehicle::all();
foreach($vehicles as $vehicles_data) {
VehicleModel::forceCreate([
'name' => Str::random(5),
'vehicle_id' => $vehicles_data->id
]);
}
}
}
By default, the db:seed command runs the Database\Seeders\DatabaseSeeder class.
There is two solutions:
1. You need to call your additional seeder(s) in the default seeder's run method.
database/seeders/DatabaseSeeder.php
public function run()
{
$this->call([
VehicleModelsSeeder::class
]);
}
Then:
php artisan migrate:refresh --seed
2. You can specify which seeder you want to run with the --class flag, but in this case you need to run the refresh and the migrate commands separately:
php artisan migrate:refresh
php artisan db:seed --class:VehicleModelsSeeder
More info: Laravel database seeding documentation

Artisan command for clearing all session data in Laravel

What is the artisan command for clearing all session data in Laravel, I'm looking for something like:
$ php artisan session:clear
But apparently it does not exist. How would I clear it from command line?
I tried using
$ php artisan tinker
...
\Session::flush();
But it flushes session of only one user, I want to flush all sessions for all users. How can I do it?
I tried this:
artisan cache:clear
But it does not clear session, again.
If you are using file based sessions, you can use the following linux command to clean the sessions folder out:
rm -f storage/framework/sessions/*
UPDATE: This question seems to be asked quite often and many people are still actively commenting on it.
In practice, it is a horrible idea to flush sessions using the
php artisan key:generate
It may wreak all kinds of havoc. The best way to do it is to clear whichever system you are using.
The Lazy Programmers guide to flushing all sessions:
php artisan key:generate
Will make all sessions invalid because a new application key is specified
The not so Lazy approach
php artisan make:command FlushSessions
and then insert
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use DB;
class flushSessions extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'session:flush';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Flush all user sessions';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
DB::table('sessions')->truncate();
}
}
and then
php artisan session:flush
The problem is that PHP's SessionHandlerInterface does not force session drivers to provide any kind of destroyAll() method. Thus, it has to be implemented manually for each driver.
Taking ideas from different answers, I came up with this solution:
Create command
php artisan make:command FlushSessions
Create class in app/Console/Commands/FlushSessions.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class FlushSessions extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'session:flush';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Flush all user sessions';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$driver = config('session.driver');
$method_name = 'clean' . ucfirst($driver);
if ( method_exists($this, $method_name) ) {
try {
$this->$method_name();
$this->info('Session data cleaned.');
} catch (\Exception $e) {
$this->error($e->getMessage());
}
} else {
$this->error("Sorry, I don't know how to clean the sessions of the driver '{$driver}'.");
}
}
protected function cleanFile () {
$directory = config('session.files');
$ignoreFiles = ['.gitignore', '.', '..'];
$files = scandir($directory);
foreach ( $files as $file ) {
if( !in_array($file,$ignoreFiles) ) {
unlink($directory . '/' . $file);
}
}
}
protected function cleanDatabase () {
$table = config('session.table');
DB::table($table)->truncate();
}
}
Run command
php artisan session:flush
Implementations for other drivers are welcome!
An easy way to get rid of all sessions is to change the name of the session cookie. This can be easily done by changing the 'cookie' => '...' line in config/session.php file.
This works independently of the session storage you use and also won't touch any other data except the session data (and thus seems preferable over the renewing the app key solution to me, where you would loose any encrypted data stored in the app).
If you want completely remove session from whatever driver you use.
Use this piece of code
\Session::getHandler()->gc(0); // Destroy all sessions which exist more 0 minutes
Sometimes the most helpful answer is at the end
This thread is quite much old. But I would like to share my implementation of removing all sesssions for file based driver.
$directory = 'storage/framework/sessions';
$ignoreFiles = ['.gitignore', '.', '..'];
$files = scandir($directory);
foreach ($files as $file) {
if(!in_array($file,$ignoreFiles)) unlink($directory . '/' . $file);
}
Why I have not used linux command 'rm'?
Because PHP is one of the prerequisites for Laravel and Linux is not. Using this Linux command will make our project implementable on Linux environment only.
That's why it is good to use PHP in Laravel.
I know this is an old thread, but what worked for me is just remove the cookies.
In Chrome, go to your develop console, go to the tab "Application". Find "Cookies" in the sidebar and click on the little arrow in front of it. Go to your domainname and click on the icon next to the filter field to clear the cookies for your domain. Refresh page, and all session data is new and the old ones are removed.
My solution
Laravel
// SESSION_DRIVER=file
$files = File::allFiles(storage_path('framework/sessions/'));
foreach($files as $file){
File::delete(storage_path('framework/sessions/'.$file->getFilename()));
}
//OR
//SESSION_DRIVER=redis
Artisan::call('cache:clear'); // == php artisan cache:clear
If you use database session , just delete all data on that table.
In my case it is 'sessions' table.
If you are using the database for session driver, then empty the sessions table. Regenerating the key will cause a lot of problems if you are using single login on many subdomains. Emptying the session table helps reduce the useless data in the session table. You can delete cookies on everyone's browswer.

Resources