Spaces:
No application file
No application file
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)), | |
}; | |
} | |
} | |
} | |