chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
<?php
declare(strict_types=1);
namespace Mautic\InstallBundle\Command;
use Doctrine\Persistence\ManagerRegistry;
use Mautic\InstallBundle\Configurator\Step\CheckStep;
use Mautic\InstallBundle\Configurator\Step\DoctrineStep;
use Mautic\InstallBundle\Install\InstallService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
/**
* CLI Command to install Mautic.
*/
class InstallCommand extends Command
{
public const COMMAND = 'mautic:install';
public function __construct(
private InstallService $installer,
private ManagerRegistry $doctrineRegistry
) {
parent::__construct();
}
/**
* Note: in every option (addOption()), please leave the default value empty to prevent problems with values from local.php being overwritten.
*/
protected function configure()
{
$this
->setName(self::COMMAND)
->setHelp('This command allows you to trigger the install process. It will try to get configuration values both from the local config file and command line options/arguments, where the latter takes precedence.')
->addArgument(
'site_url',
InputArgument::REQUIRED,
'Site URL.',
null
)
->addArgument(
'step',
InputArgument::OPTIONAL,
'Install process start index. 0 for requirements check, 1 for database, 2 for admin, 3 for configuration, 4 for final step. Each successful step will trigger the next until completion.',
0
)
->addOption(
'--force',
'-f',
InputOption::VALUE_NONE,
'Do not ask confirmation if recommendations triggered.',
null
)
->addOption(
'--db_driver',
null,
InputOption::VALUE_REQUIRED,
'Database driver.',
null
)
->addOption(
'--db_host',
null,
InputOption::VALUE_REQUIRED,
'Database host.',
null
)
->addOption(
'--db_port',
null,
InputOption::VALUE_REQUIRED,
'Database port.',
null
)
->addOption(
'--db_name',
null,
InputOption::VALUE_REQUIRED,
'Database name.',
null
)
->addOption(
'--db_user',
null,
InputOption::VALUE_REQUIRED,
'Database user.',
null
)
->addOption(
'--db_password',
null,
InputOption::VALUE_REQUIRED,
'Database password.',
null
)
->addOption(
'--db_table_prefix',
null,
InputOption::VALUE_REQUIRED,
'Database tables prefix.',
null
)
->addOption(
'--db_backup_tables',
null,
InputOption::VALUE_REQUIRED,
'Backup database tables if they exist; otherwise drop them. (true|false)',
null
)
->addOption(
'--db_backup_prefix',
null,
InputOption::VALUE_REQUIRED,
'Database backup tables prefix.',
null
)
->addOption(
'--admin_firstname',
null,
InputOption::VALUE_REQUIRED,
'Admin first name.',
null
)
->addOption(
'--admin_lastname',
null,
InputOption::VALUE_REQUIRED,
'Admin last name.',
null
)
->addOption(
'--admin_username',
null,
InputOption::VALUE_REQUIRED,
'Admin username.',
null
)
->addOption(
'--admin_email',
null,
InputOption::VALUE_REQUIRED,
'Admin email.',
null
)
->addOption(
'--admin_password',
null,
InputOption::VALUE_REQUIRED,
'Admin user.',
null
);
parent::configure();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
// Check Mautic is not already installed
if ($this->installer->checkIfInstalled()) {
$output->writeln('Mautic already installed');
return Command::SUCCESS;
}
$output->writeln([
'Mautic Install',
'==============',
'',
]);
if (!defined('IS_PHPUNIT')) {
// Prevents querying of database tables that do not exist during the installation process
define('MAUTIC_INSTALLER', 1);
}
// Build objects to pass to the install service from local.php or command line options
$output->writeln('Parsing options and arguments...');
$options = $input->getOptions();
// Convert boolean options to actual booleans.
$options['db_backup_tables'] = (bool) filter_var($options['db_backup_tables'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
/**
* We need to have some default database parameters, as it could be the case that the
* user didn't set them both in local.php and the command line options.
*/
$dbParams = [
'driver' => 'pdo_mysql',
'host' => null,
'port' => null,
'name' => null,
'user' => null,
'password' => null,
'table_prefix' => null,
'backup_tables' => true,
'backup_prefix' => 'bak_',
];
$adminParam = [
'firstname' => 'Admin',
'lastname' => 'Mautic',
'username' => 'admin',
];
$allParams = $this->installer->localConfigParameters();
// Initialize DB and admin params from local.php
foreach ((array) $allParams as $opt => $value) {
if (str_starts_with($opt, 'db_')) {
$dbParams[substr($opt, 3)] = $value;
} elseif (str_starts_with($opt, 'admin_')) {
$adminParam[substr($opt, 6)] = $value;
}
}
// Initialize DB and admin params from cli options
foreach ($options as $opt => $value) {
if (isset($value)) {
if (str_starts_with($opt, 'db_')) {
$dbParams[substr($opt, 3)] = $value;
$allParams[$opt] = $value;
} elseif (str_starts_with($opt, 'admin_')) {
$adminParam[substr($opt, 6)] = $value;
}
}
}
if (!empty($allParams['site_url'])) {
$siteUrl = $allParams['site_url'];
} else {
$siteUrl = $input->getArgument('site_url');
$allParams['site_url'] = $siteUrl;
}
$step = (float) $input->getArgument('step');
switch ($step) {
default:
case InstallService::CHECK_STEP:
$output->writeln($step.' - Checking installation requirements...');
$messages = $this->stepAction($this->installer, ['site_url' => $siteUrl], $step);
if (!empty($messages)) {
if (isset($messages['requirements']) && !empty($messages['requirements'])) {
// Stop install if requirements not met
$output->writeln('Missing requirements:');
$this->handleInstallerErrors($output, $messages['requirements']);
$output->writeln('Install canceled');
return (int) -$step;
} elseif (isset($messages['optional']) && !empty($messages['optional'])) {
$output->writeln('Missing optional settings:');
$this->handleInstallerErrors($output, $messages['optional']);
if (empty($options['force'])) {
// Ask user to confirm install when optional settings missing
/** @var QuestionHelper $helper */
$helper = $this->getHelper('question');
$question = new ConfirmationQuestion('Continue with install anyway? [yes/no]', false);
if (!$helper->ask($input, $output, $question)) {
return (int) -$step;
}
}
}
}
$output->writeln('Ready to Install!');
// Keep on with next step
$step = InstallService::DOCTRINE_STEP;
// no break
case InstallService::DOCTRINE_STEP:
$output->writeln($step.' - Creating database...');
/**
* This is needed for installations with database prefixes to work correctly.
*/
$connectionWrapper = $this->doctrineRegistry->getConnection();
$connectionWrapper->initConnection($dbParams);
$messages = $this->stepAction($this->installer, $dbParams, $step);
if (!empty($messages)) {
$output->writeln('Errors in database configuration/installation:');
$this->handleInstallerErrors($output, $messages);
$output->writeln('Install canceled');
return (int) -$step;
}
$step = InstallService::DOCTRINE_STEP + .1;
$output->writeln($step.' - Creating schema...');
$messages = $this->stepAction($this->installer, $dbParams, $step);
if (!empty($messages)) {
$output->writeln('Errors in schema configuration/installation:');
$this->handleInstallerErrors($output, $messages);
$output->writeln('Install canceled');
return -InstallService::DOCTRINE_STEP;
}
$step = InstallService::DOCTRINE_STEP + .2;
$output->writeln($step.' - Loading fixtures...');
$messages = $this->stepAction($this->installer, $dbParams, $step);
if (!empty($messages)) {
$output->writeln('Errors in fixtures configuration/installation:');
$this->handleInstallerErrors($output, $messages);
$output->writeln('Install canceled');
return -InstallService::DOCTRINE_STEP;
}
// Keep on with next step
$step = InstallService::USER_STEP;
// no break
case InstallService::USER_STEP:
$output->writeln($step.' - Creating admin user...');
$messages = $this->stepAction($this->installer, $adminParam, $step);
if (!empty($messages)) {
$output->writeln('Errors in admin user configuration/installation:');
$this->handleInstallerErrors($output, $messages);
$output->writeln('Install canceled');
return (int) -$step;
}
// Keep on with next step
$step = InstallService::FINAL_STEP;
// no break
case InstallService::FINAL_STEP:
$output->writeln($step.' - Final steps...');
$messages = $this->stepAction($this->installer, $allParams, $step);
if (!empty($messages)) {
$output->writeln('Errors in final step:');
$this->handleInstallerErrors($output, $messages);
$output->writeln('Install canceled');
return (int) -$step;
}
}
$output->writeln([
'',
'================',
'Install complete',
'================',
]);
return Command::SUCCESS;
}
/**
* Controller action for install steps.
*
* @param InstallService $installer The install process
* @param array $params The install parameters
* @param float $index The step number to process
*
* @throws \Exception
*/
protected function stepAction(InstallService $installer, array $params, float $index = 0): array
{
if ($index - floor($index) > 0) {
$subIndex = (int) (round($index - floor($index), 1) * 10);
$index = floor($index);
}
$index = (int) $index;
$messages = [];
switch ($index) {
case InstallService::CHECK_STEP:
// Check installation requirements
$step = $installer->getStep($index);
if ($step instanceof CheckStep) {
// Set all step fields based on parameters
$step->site_url = $params['site_url'];
}
$messages['requirements'] = $installer->checkRequirements($step);
$messages['optional'] = $installer->checkOptionalSettings($step);
break;
case InstallService::DOCTRINE_STEP:
$step = $installer->getStep($index);
if ($step instanceof DoctrineStep) {
// Set all step fields based on parameters
foreach ($step as $key => $value) {
if (isset($params[$key])) {
$step->$key = $params[$key];
}
}
}
if (!isset($subIndex)) {
// Install database
$messages = $installer->createDatabaseStep($step, $params);
break;
}
switch ($subIndex) {
case 1:
// Install schema
$messages = $installer->createSchemaStep($params);
break;
case 2:
// Install fixtures
$messages = $installer->createFixturesStep();
break;
}
break;
case InstallService::USER_STEP:
// Create admin user
$messages = $installer->createAdminUserStep($params);
break;
case InstallService::FINAL_STEP:
// Save final configuration
$siteUrl = $params['site_url'];
$messages = $installer->createFinalConfigStep($siteUrl);
if (empty($messages)) {
$installer->finalMigrationStep();
}
break;
}
return $messages;
}
/**
* Handle install command errors.
*
* @param array<string,string> $messages
*/
private function handleInstallerErrors(OutputInterface $output, array $messages): void
{
foreach ($messages as $type => $message) {
$output->writeln(" - [$type] $message");
}
}
protected static $defaultDescription = 'Installs Mautic';
}