mautic / app /bundles /InstallBundle /Controller /InstallController.php
chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
<?php
namespace Mautic\InstallBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
use Mautic\CoreBundle\Configurator\Configurator;
use Mautic\CoreBundle\Controller\CommonController;
use Mautic\CoreBundle\Factory\MauticFactory;
use Mautic\CoreBundle\Factory\ModelFactory;
use Mautic\CoreBundle\Helper\CoreParametersHelper;
use Mautic\CoreBundle\Helper\PathsHelper;
use Mautic\CoreBundle\Helper\UserHelper;
use Mautic\CoreBundle\Loader\ParameterLoader;
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
use Mautic\CoreBundle\Service\FlashBag;
use Mautic\CoreBundle\Translation\Translator;
use Mautic\InstallBundle\Install\InstallService;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
class InstallController extends CommonController
{
public function __construct(
private Configurator $configurator,
private InstallService $installer,
ManagerRegistry $doctrine,
MauticFactory $factory,
ModelFactory $modelFactory,
UserHelper $userHelper,
CoreParametersHelper $coreParametersHelper,
EventDispatcherInterface $dispatcher,
Translator $translator,
FlashBag $flashBag,
RequestStack $requestStack,
CorePermissions $security
) {
parent::__construct($doctrine, $factory, $modelFactory, $userHelper, $coreParametersHelper, $dispatcher, $translator, $flashBag, $requestStack, $security);
}
/**
* Controller action for install steps.
*
* @param int $index The step number to process
*
* @return JsonResponse|Response
*
* @throws \Doctrine\DBAL\Exception
*/
public function stepAction(Request $request, EntityManagerInterface $entityManager, PathsHelper $pathsHelper, float $index = 0)
{
// We're going to assume a bit here; if the config file exists already and DB info is provided, assume the app
// is installed and redirect
if ($this->installer->checkIfInstalled()) {
return $this->redirectToRoute('mautic_dashboard_index');
}
if ($index - floor($index) > 0) {
$subIndex = (int) (round($index - floor($index), 1) * 10);
$index = floor($index);
}
$index = (int) $index;
$params = $this->configurator->getParameters();
$session = $request->getSession();
$completedSteps = $session->get('mautic.installer.completedsteps', []);
// Check to ensure the installer is in the right place
if ((empty($params) || empty($params['db_driver'])) && $index > 1) {
$session->set('mautic.installer.completedsteps', [0]);
return $this->redirectToRoute('mautic_installer_step', ['index' => 1]);
}
/** @var \Mautic\CoreBundle\Configurator\Step\StepInterface $step */
$step = $this->configurator->getStep($index)[0];
$action = $this->generateUrl('mautic_installer_step', ['index' => $index]);
$form = $this->createForm($step->getFormType(), $step, ['action' => $action]);
$tmpl = $request->isXmlHttpRequest() ? $request->get('tmpl', 'index') : 'index';
// Note if this step is complete
$complete = false;
if ('POST' === $request->getMethod()) {
$form->handleRequest($request);
if ($form->isValid()) {
// Post-step processing
$formData = $form->getData();
switch ($index) {
case InstallService::CHECK_STEP:
$complete = true;
break;
case InstallService::DOCTRINE_STEP:
// password field does not retain configured defaults
if (empty($formData->password) && !empty($params['db_password'])) {
$formData->password = $params['db_password'];
}
$dbParams = (array) $formData;
$messages = $this->installer->createDatabaseStep($step, $dbParams);
if (!empty($messages)) {
$this->handleInstallerErrors($form, $messages);
break;
}
/**
* We need to clear the ORM metadata cache before creating the schema. If the user provided a database
* table prefix in the UI installer, cached table names don't have the prefix yet (e.g. oauth2_clients).
* After clearing the metadata cache, Doctrine automatically recreates it with the correct prefixes (e.g.
* mau_oauth2_clients), if applicable.
*/
$entityManager->getConfiguration()->getMetadataCache()->clear();
// Refresh to install schema with new connection information in the container
return $this->redirectToRoute('mautic_installer_step', ['index' => 1.1]);
case InstallService::USER_STEP:
$adminParam = (array) $formData;
$messages = $this->installer->createAdminUserStep($adminParam);
if (!empty($messages)) {
$this->handleInstallerErrors($form, $messages);
break;
}
// Store the data to repopulate the form
unset($formData->password);
$session->set('mautic.installer.user', $formData);
$complete = true;
break;
}
}
} elseif (!empty($subIndex)) {
switch ($index) {
case InstallService::DOCTRINE_STEP:
$dbParams = (array) $step;
switch ($subIndex) {
case 1:
$messages = $this->installer->createSchemaStep($dbParams);
if (!empty($messages)) {
$this->handleInstallerErrors($form, $messages);
return $this->redirectToRoute('mautic_installer_step', ['index' => 1]);
}
return $this->redirectToRoute('mautic_installer_step', ['index' => 1.2]);
case 2:
$messages = $this->installer->createFixturesStep();
if (!empty($messages)) {
$this->handleInstallerErrors($form, $messages);
return $this->redirectToRoute('mautic_installer_step', ['index' => 1]);
}
$complete = true;
break;
}
break;
}
}
if ($complete) {
$completedSteps[] = $index;
$session->set('mautic.installer.completedsteps', $completedSteps);
++$index;
if ($index < $this->configurator->getStepCount()) {
// On to the next step
return $this->redirectToRoute('mautic_installer_step', ['index' => (int) $index]);
} else {
$siteUrl = $request->getSchemeAndHttpHost().$request->getBaseUrl();
$messages = $this->installer->createFinalConfigStep($siteUrl);
if (!empty($messages)) {
$this->handleInstallerErrors($form, $messages);
}
return $this->postActionRedirect(
[
'viewParameters' => [
'welcome_url' => $this->generateUrl('mautic_dashboard_index'),
'parameters' => $this->configurator->render(),
'version' => MAUTIC_VERSION,
'tmpl' => $tmpl,
],
'returnUrl' => $this->generateUrl('mautic_installer_final'),
'contentTemplate' => '@MauticInstall/Install/final.html.twig',
'forwardController' => false,
]
);
}
} else {
// Redirect back to last step if the user advanced ahead via the URL
$last = (int) end($completedSteps) + 1;
if ($index && $index > $last) {
return $this->redirectToRoute('mautic_installer_step', ['index' => $last]);
}
}
return $this->delegateView(
[
'viewParameters' => [
'form' => $form->createView(),
'index' => $index,
'count' => $this->configurator->getStepCount(),
'version' => MAUTIC_VERSION,
'tmpl' => $tmpl,
'majors' => $this->configurator->getRequirements(),
'minors' => $this->configurator->getOptionalSettings(),
'appRoot' => $this->coreParametersHelper->get('mautic.application_dir').'/app',
'cacheDir' => $this->coreParametersHelper->get('kernel.cache_dir'),
'logDir' => $this->coreParametersHelper->get('kernel.logs_dir'),
'configFile' => ParameterLoader::getLocalConfigFile($pathsHelper->getSystemPath('root').'/app'),
'completedSteps' => $completedSteps,
],
'contentTemplate' => $step->getTemplate(),
'passthroughVars' => [
'route' => $this->generateUrl('mautic_installer_step', ['index' => $index]),
],
]
);
}
/**
* Controller action for the final step.
*
* @return JsonResponse|Response
*
* @throws \Exception
*/
public function finalAction(Request $request, PathsHelper $pathsHelper): \Symfony\Component\HttpFoundation\RedirectResponse|Response
{
$session = $request->getSession();
// We're going to assume a bit here; if the config file exists already and DB info is provided, assume the app is installed and redirect
if ($this->installer->checkIfInstalled()) {
if (!$session->has('mautic.installer.completedsteps')) {
// Arrived here by directly browsing to URL so redirect to the dashboard
return $this->redirectToRoute('mautic_dashboard_index');
}
} else {
// Shouldn't have made it to this step without having a successful install
return $this->redirectToRoute('mautic_installer_home');
}
// Remove installer session variables
$session->remove('mautic.installer.completedsteps');
$session->remove('mautic.installer.user');
$this->installer->finalMigrationStep();
$welcomeUrl = $this->generateUrl('mautic_dashboard_index');
$tmpl = $request->isXmlHttpRequest() ? $request->get('tmpl', 'index') : 'index';
return $this->delegateView(
[
'viewParameters' => [
'welcome_url' => $welcomeUrl,
'parameters' => $this->configurator->render(),
'config_path' => ParameterLoader::getLocalConfigFile($pathsHelper->getSystemPath('root').'/app'),
'is_writable' => $this->configurator->isFileWritable(),
'version' => MAUTIC_VERSION,
'tmpl' => $tmpl,
],
'contentTemplate' => '@MauticInstall/Install/final.html.twig',
'passthroughVars' => [
'activeLink' => '#mautic_installer_index',
'mauticContent' => 'installer',
'route' => $this->generateUrl('mautic_installer_final'),
],
]
);
}
/**
* Handle installer errors.
*/
private function handleInstallerErrors(Form $form, array $messages): void
{
foreach ($messages as $type => $message) {
match ($type) {
'warning', 'error', 'notice' => $this->addFlashMessage($message, [], $type),
default => $form[$type]->addError(new FormError($message)),
};
}
}
}