gecche / laravel-multidomain

A Laravel extension for using a laravel application on a multi domain setting
MIT License
847 stars 105 forks source link

Feature wish: artisan --all-domains option #14

Open Scaenicus opened 4 years ago

Scaenicus commented 4 years ago

Maybe I haven't read the documentation enough, but is there a way to do some artisan task for all domains? Something like:

php artisan --all-domains cache:clear
php artisan --all-domains config:clear
php artisan --all-domains migrate --seed

If not I will probably develop a bash script which evaluates php artisan domain:list to repeat tasks for each domain.

gecche commented 4 years ago

Hi,

to my knowledge (and due to the same reasons pointed out here ) there is no a safe and general way to use artisan for a command operating on all the domains. Maybe I'm wrong but I spent a lot of time on this topic.

I understand very well that it would be a useful addition, but the only way I know to do this is via a bash script. Indeed, in my head, it is a planned feature to add a quite general bash script for calling artisan on all domains or on a subset of them. I'm not very expert of shell scripting but If you have done such a script and you want to contribute, you are welcome!

Cheers,

Giacomo

Scaenicus commented 4 years ago

Thank you Giacomo! Good. I will develop and upload my bash-solution when finished. With kind regards, Philipp

Epizefiri commented 3 years ago

HI @Scaenicus, do you have any news about that script?

SadeghPM commented 3 years ago

Since this is technically impossible with laravel command, I coded this script to run through shell.

Usage

#!/usr/bin/env php
<?php

$config = require __DIR__ . "/config/domain.php";
$domains = array_keys($config['domains']);

echo "\033[32m Run one command against all domains.\033[39m" . PHP_EOL;

if ($argv[1] ?? null) {
    unset($argv[0]);
    $command = implode(' ', $argv);
    echo "Your command is $command" . PHP_EOL;
    $input = confirm('How run command? a:All s:selective c:Cancel ');
    if ($input === 'c') exit(0);
    foreach ($domains as $index => $domain) {
        if ($input === 'a' or (confirm("\033[96m Run against $domain ? Y/N \033[39m ") === 'y')) {
            echo "\033[32m php artisan $command --domain=$domain \033[39m " . PHP_EOL;
            echo shell_exec("yes | php artisan $command --domain=$domain");
        }
        echo PHP_EOL;
    }
} else {
    echo "\033[31m No command found! usage: php tenant {command}" . PHP_EOL;
}

function confirm($question)
{
    echo $question . PHP_EOL;
    return strtolower(rtrim(fgets(STDIN)));
}
Epizefiri commented 3 years ago

@SadeghPM thanks, you made my day!

gecche commented 3 years ago

Thank you very much @SadeghPM and sorry for my delay... I will check it and include it in next version of the package (very soon)

Thanks again

Giacomo

Scaenicus commented 3 years ago

HI @Scaenicus, do you have any news about that script?

I'm sorry for not responding. Was a hard year and we never finished a general-purpose script in a sharable quality like @SadeghPM (thank you too!)

gecche commented 3 years ago

Hi @SadeghPM, I was including your script in my package: I think it is very good, thank you! :) Only one question: I've done some tests and it seems that if an artisan command asks something to the user before to run, the script ignores it. Is it so?

Cheers

Giacomo

SadeghPM commented 3 years ago

Hi @gecche Yeh, PHP has no native way of doing an interactive prompt for user.

Qanah commented 3 years ago

@SadeghPM i make some changes on your script

put still i need a way to run it from the master project to the subproject so I can clear the cache on run time

Usage

Place the script in projects root with name tenant
Run the script file like: php tenant config:clear
The script cycle through all domains and run command.
I could add this to package if @gecche wants.
#!/usr/bin/env php
<?php

$config = require __DIR__ . "/config/domain.php";

$domains = array_keys($config['domains']);

if ($argv[1] ?? null) {

    $command = $argv[1] ?? '';

    unset($argv[0]);
    unset($argv[1]);

    if (!$command || !commandExists($command)) {
        echo "invalid command!";
        echo PHP_EOL;
        exit(0);
    }

    foreach ($domains as $index => $domain) {

        $argv['domain'] = "--domain=$domain";

        $args = trim(implode(' ', $argv));

        echo "php artisan $command $args";
        echo PHP_EOL;
        echo shell_exec("php artisan $command $args");
    }
}

function commandExists($name): bool
{
    $output = shell_exec("php artisan list");

    $commands = [];
    foreach (explode(PHP_EOL, $output) as $line) {
        $command = explode(' ', trim($line))[0] ?? '';

        if($command && strrpos($command, "-") === false && !in_array($command, ['Laravel', 'Usage:', 'command', 'Options:', 'Available'])) {
            $commands[] = $command;
        }
    }

    return in_array($name, $commands);
}
MrCanan commented 6 months ago

Hi, Very good idea and works