Commit c53fc10d authored by Tino Goratsch's avatar Tino Goratsch

rework the structure of the installer once more

parent 76c375fe
Pipeline #93276024 passed with stages
in 3 minutes
......@@ -36,6 +36,8 @@ splits:
target: "git@gitlab.com:ACP3/module-gallery.git"
- prefix: "ACP3/Modules/ACP3/Guestbook"
target: "git@gitlab.com:ACP3/module-guestbook.git"
- prefix: "ACP3/Modules/ACP3/Installer"
target: "git@gitlab.com:ACP3/module-installer.git"
- prefix: "ACP3/Modules/ACP3/Menus"
target: "git@gitlab.com:ACP3/module-menus.git"
- prefix: "ACP3/Modules/ACP3/News"
......
......@@ -46,38 +46,22 @@ abstract class AbstractBootstrap implements BootstrapInterface
/**
* Set monolog as the default PHP error handler.
*/
public function setErrorHandler()
public function setErrorHandler(): void
{
$debug = $this->appMode === ApplicationMode::DEVELOPMENT;
$isProduction = $this->appMode === ApplicationMode::PRODUCTION;
ExceptionHandler::register($debug);
ExceptionHandler::register(!$isProduction);
$errorHandler = new ErrorHandler();
ErrorHandler::register($errorHandler);
}
/**
* {@inheritdoc}
*/
public function getContainer()
{
return $this->container;
}
/**
* @return ApplicationPath
*/
public function getAppPath()
{
return $this->appPath;
}
/**
* Checks, whether the database configuration file exists.
*
* @return bool
*/
protected function databaseConfigExists()
protected function databaseConfigExists(): bool
{
$path = $this->appPath->getAppDir() . 'config.yml';
......
......@@ -27,6 +27,8 @@ class Bootstrap extends AbstractBootstrap
/**
* {@inheritdoc}
*
* @throws \Throwable
*/
public function handle(SymfonyRequest $request, $type = self::MASTER_REQUEST, $catch = true)
{
......@@ -38,8 +40,11 @@ class Bootstrap extends AbstractBootstrap
/**
* {@inheritdoc}
*
* @throws \MJS\TopSort\CircularDependencyException
* @throws \MJS\TopSort\ElementNotFoundException
*/
public function initializeClasses(SymfonyRequest $symfonyRequest)
public function initializeClasses(SymfonyRequest $symfonyRequest): void
{
Utf8\Bootup::initAll(); // Enables the portability layer and configures PHP for UTF-8
Utf8\Bootup::filterRequestUri(); // Redirects to an UTF-8 encoded URL if it's not already the case
......@@ -87,16 +92,12 @@ class Bootstrap extends AbstractBootstrap
*
* @throws \Throwable
*/
public function outputPage()
public function outputPage(): Response
{
/** @var \ACP3\Core\Application\ControllerActionDispatcher $controllerActionDispatcher */
$controllerActionDispatcher = $this->container->get('core.application.controller_action_dispatcher');
try {
/** @var \ACP3\Core\Authentication\AuthenticationInterface $authentication */
$authentication = $this->container->get('core.authentication');
$authentication->authenticate();
/** @var \ACP3\Core\Application\ControllerActionDispatcher $controllerActionDispatcher */
$controllerActionDispatcher = $this->container->get('core.application.controller_action_dispatcher');
......@@ -120,7 +121,7 @@ class Bootstrap extends AbstractBootstrap
/**
* {@inheritdoc}
*/
public function startupChecks()
public function isInstalled(): bool
{
\date_default_timezone_set('UTC');
......
......@@ -16,29 +16,26 @@ interface BootstrapInterface extends HttpKernelInterface
/**
* Contains the current ACP3 version string.
*/
const VERSION = '4.46.0';
public const VERSION = '4.46.0';
/**
* Performs some startup checks.
* Checks whether the ACP3 is correctly installed.
*
* @return bool
*/
public function startUpChecks();
public function isInstalled(): bool;
/**
* Initializes the dependency injection container.
*
* @param SymfonyRequest $symfonyRequest
*/
public function initializeClasses(SymfonyRequest $symfonyRequest);
public function initializeClasses(SymfonyRequest $symfonyRequest): void;
/**
* Handle the request and output the page.
*
* @return Response
*/
public function outputPage();
/**
* @return \Symfony\Component\DependencyInjection\ContainerInterface
*/
public function getContainer();
public function outputPage(): Response;
}
......@@ -7,7 +7,9 @@
namespace ACP3\Core\Authentication;
use ACP3\Core\Authentication\Model\UserModelInterface;
interface AuthenticationInterface
{
public function authenticate();
public function authenticate(UserModelInterface $userModel): void;
}
......@@ -11,14 +11,14 @@ use Symfony\Component\HttpFoundation\Cookie;
interface AuthenticationModelInterface
{
const AUTH_NAME = 'ACP3_AUTH';
public const AUTH_NAME = 'ACP3_AUTH';
/**
* Authenticates the user.
*
* @param array|int|null $userData
* @param array|null $userData
*/
public function authenticate($userData);
public function authenticate(?array $userData): void;
/**
* Logs out the current user.
......
......@@ -16,47 +16,47 @@ interface UserModelInterface
*
* @return array
*/
public function getUserInfo($userId = 0);
public function getUserInfo(int $userId = 0): array;
/**
* Returns, whether the current user is an authenticated user or not.
*
* @return bool
*/
public function isAuthenticated();
public function isAuthenticated(): bool;
/**
* @param bool $isAuthenticated
*
* @return $this
*/
public function setIsAuthenticated($isAuthenticated);
public function setIsAuthenticated(bool $isAuthenticated);
/**
* Returns the user id of the currently logged in user.
*
* @return int
*/
public function getUserId();
public function getUserId(): int;
/**
* @param int $userId
*
* @return $this
*/
public function setUserId($userId);
public function setUserId(int $userId);
/**
* Returns, whether the currently logged in user is a super user or not.
*
* @return bool
*/
public function isSuperUser();
public function isSuperUser(): bool;
/**
* @param bool $isSuperUser
*
* @return $this
*/
public function setIsSuperUser($isSuperUser);
public function setIsSuperUser(bool $isSuperUser);
}
......@@ -13,7 +13,7 @@ class AreaEnum extends BaseEnum
{
public const AREA_ADMIN = 'admin';
public const AREA_FRONTEND = 'frontend';
public const AREA_INSTALL = 'install';
public const AREA_INSTALL = 'installer';
public const AREA_WIDGET = 'widget';
/**
......
......@@ -35,7 +35,9 @@ trait DisplayActionTrait
}
return $actionResult;
} elseif (\is_string($actionResult)) {
}
if (\is_string($actionResult)) {
$this->setContent($actionResult);
} elseif (\is_array($actionResult)) {
$this->getView()->assign($actionResult);
......
......@@ -115,7 +115,7 @@ class Alerts
{
$this->setErrorBoxData($errors);
return 'system/alerts/error_box.tpl';
return 'System/Alerts/error_box.tpl';
}
/**
......
......@@ -11,8 +11,9 @@ use ACP3\Core\Controller\AreaEnum;
class Request extends AbstractRequest
{
const ADMIN_PANEL_PATTERN = '=^acp/=';
const WIDGET_PATTERN = '=^widget/=';
private const ADMIN_PANEL_PATTERN = 'acp/';
private const WIDGET_PATTERN = 'widget/';
private const FRONTEND_PATTERN = 'frontend/';
/**
* @var string
......@@ -124,18 +125,18 @@ class Request extends AbstractRequest
$this->query = $this->pathInfo;
// It's an request for the admin panel page
if (\preg_match(self::ADMIN_PANEL_PATTERN, $this->query)) {
if (\strpos($this->query, self::ADMIN_PANEL_PATTERN) === 0) {
$this->symfonyRequest->attributes->set('_area', AreaEnum::AREA_ADMIN);
// strip "acp/"
$this->query = \substr($this->query, 4);
} elseif (\preg_match(self::WIDGET_PATTERN, $this->query)) {
$this->query = \substr($this->query, \strlen(self::ADMIN_PANEL_PATTERN));
} elseif (\strpos($this->query, self::WIDGET_PATTERN) === 0) {
$this->symfonyRequest->attributes->set('_area', AreaEnum::AREA_WIDGET);
// strip "widget/"
$this->query = \substr($this->query, 7);
$this->query = \substr($this->query, \strlen(self::WIDGET_PATTERN));
} else {
if (\strpos($this->query, 'frontend/') === 0) {
$this->query = \substr($this->query, 9);
if (\strpos($this->query, self::FRONTEND_PATTERN) === 0) {
$this->query = \substr($this->query, \strlen(self::FRONTEND_PATTERN));
}
$this->symfonyRequest->attributes->set('_area', AreaEnum::AREA_FRONTEND);
......
......@@ -14,7 +14,7 @@ use ACP3\Modules\ACP3\System\Installer\Schema;
class Router implements RouterInterface
{
const ADMIN_PANEL_PATTERN = '=^(acp|admin)/=';
private const ADMIN_PANEL_PATTERN = '=^(acp|admin)/=';
/**
* @var \ACP3\Core\Http\RequestInterface
......@@ -29,13 +29,6 @@ class Router implements RouterInterface
*/
protected $config;
/**
* Router constructor.
*
* @param RequestInterface $request
* @param ApplicationPath $appPath
* @param SettingsInterface $config
*/
public function __construct(
RequestInterface $request,
ApplicationPath $appPath,
......@@ -73,13 +66,13 @@ class Router implements RouterInterface
*/
protected function preparePath(string $path): string
{
$path = $path . (!\preg_match('/\/$/', $path) ? '/' : '');
$path .= (!\preg_match('/\/$/', $path) ? '/' : '');
if ($path === 'acp/') {
$path = 'acp/acp/index/index/';
}
$prefix = 'admin/';
if (\substr($path, 0, \strlen($prefix)) == $prefix) {
if (\strpos($path, $prefix) === 0) {
$path = 'acp/' . \substr($path, \strlen($prefix));
}
......@@ -116,7 +109,7 @@ class Router implements RouterInterface
*/
protected function isAdminUri(string $path): bool
{
return \preg_match(self::ADMIN_PANEL_PATTERN, $path) != false;
return \preg_match(self::ADMIN_PANEL_PATTERN, $path) === 1;
}
/**
......@@ -134,7 +127,7 @@ class Router implements RouterInterface
$prefix .= $this->request->getHost();
}
if ($this->useModRewrite($path) || $path === '') {
if ($path === '' || $this->useModRewrite($path)) {
$prefix .= $this->appPath->getWebRoot();
} else {
$prefix .= $this->appPath->getPhpSelf() . '/';
......@@ -152,7 +145,8 @@ class Router implements RouterInterface
{
if ($isSecure === null) {
return $this->request->getScheme() . '://';
} elseif ($isSecure === true) {
}
if ($isSecure === true) {
return 'https://';
}
......
......@@ -93,6 +93,8 @@ class SessionHandler extends AbstractSessionHandler
/**
* {@inheritdoc}
*
* @throws \Doctrine\DBAL\DBALException
*/
public function close()
{
......@@ -103,7 +105,7 @@ class SessionHandler extends AbstractSessionHandler
$this->gcCalled = false;
$this->db->getConnection()->executeUpdate(
"DELETE FROM `{$this->db->getPrefix()}sessions` WHERE `session_starttime` + ? < ?;",
"DELETE FROM `{$this->db->getPrefixedTableName('sessions')}` WHERE `session_starttime` + ? < ?;",
[$this->expireTime, \time()]
);
}
......@@ -121,11 +123,13 @@ class SessionHandler extends AbstractSessionHandler
/**
* {@inheritdoc}
*
* @throws \Doctrine\DBAL\DBALException
*/
public function read($sessionId)
{
$session = $this->db->fetchColumn(
"SELECT `session_data` FROM `{$this->db->getPrefix()}sessions` WHERE `session_id` = ?;",
"SELECT `session_data` FROM `{$this->db->getPrefixedTableName('sessions')}` WHERE `session_id` = ?;",
[$sessionId]
);
......@@ -134,11 +138,13 @@ class SessionHandler extends AbstractSessionHandler
/**
* {@inheritdoc}
*
* @throws \Doctrine\DBAL\DBALException
*/
public function write($sessionId, $data)
{
$this->db->getConnection()->executeUpdate(
"INSERT INTO `{$this->db->getPrefix()}sessions` (`session_id`, `session_starttime`, `session_data`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `session_data` = ?;",
"INSERT INTO `{$this->db->getPrefixedTableName('sessions')}` (`session_id`, `session_starttime`, `session_data`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `session_data` = ?;",
[$sessionId, \time(), $data, $data]
);
......@@ -147,6 +153,8 @@ class SessionHandler extends AbstractSessionHandler
/**
* {@inheritdoc}
*
* @throws \Doctrine\DBAL\DBALException
*/
public function destroy($sessionId)
{
......@@ -165,7 +173,10 @@ class SessionHandler extends AbstractSessionHandler
}
// Delete the session from the database
$this->db->getConnection()->delete($this->db->getPrefix() . 'sessions', ['session_id' => $sessionId]);
$this->db->getConnection()->delete(
$this->db->getPrefixedTableName('sessions'),
['session_id' => $sessionId]
);
return true;
}
......
......@@ -9,8 +9,8 @@ namespace ACP3\Core\View\Renderer\Smarty\Filters;
abstract class AbstractMoveElementFilter extends AbstractFilter
{
const ELEMENT_CATCHER_REGEX_PATTERN = '';
const PLACEHOLDER = '';
public const ELEMENT_CATCHER_REGEX_PATTERN = '';
protected const PLACEHOLDER = '';
/**
* @param string $tplOutput
......
......@@ -12,8 +12,8 @@ use ACP3\Core\Http\RequestInterface;
class MoveToBottom extends AbstractMoveElementFilter
{
const ELEMENT_CATCHER_REGEX_PATTERN = '!@@@SMARTY:JAVASCRIPTS:BEGIN@@@(.*?)@@@SMARTY:JAVASCRIPTS:END@@@!is';
const PLACEHOLDER = '<!-- JAVASCRIPTS -->';
public const ELEMENT_CATCHER_REGEX_PATTERN = '!@@@SMARTY:JAVASCRIPTS:BEGIN@@@(.*?)@@@SMARTY:JAVASCRIPTS:END@@@!is';
protected const PLACEHOLDER = '<!-- JAVASCRIPTS -->';
/**
* @var \ACP3\Core\Assets\Minifier\AbstractMinifier
......
......@@ -11,8 +11,8 @@ use ACP3\Core\Assets\Minifier\MinifierInterface;
class MoveToHead extends AbstractMoveElementFilter
{
const ELEMENT_CATCHER_REGEX_PATTERN = '!@@@SMARTY:STYLESHEETS:BEGIN@@@(.*?)@@@SMARTY:STYLESHEETS:END@@@!is';
const PLACEHOLDER = '<!-- STYLESHEETS -->';
public const ELEMENT_CATCHER_REGEX_PATTERN = '!@@@SMARTY:STYLESHEETS:BEGIN@@@(.*?)@@@SMARTY:STYLESHEETS:END@@@!is';
protected const PLACEHOLDER = '<!-- STYLESHEETS -->';
/**
* @var \ACP3\Core\Assets\Minifier\MinifierInterface
......
......@@ -27,13 +27,6 @@ class SmartyConfigurator
*/
protected $environment;
/**
* SmartyConfigurator constructor.
*
* @param \ACP3\Core\Environment\ApplicationPath $appPath
* @param \ACP3\Core\Settings\SettingsInterface $config
* @param string $environment
*/
public function __construct(ApplicationPath $appPath, SettingsInterface $config, string $environment)
{
$this->appPath = $appPath;
......@@ -44,11 +37,11 @@ class SmartyConfigurator
/**
* @param \Smarty $smarty
*/
public function configure(\Smarty $smarty)
public function configure(\Smarty $smarty): void
{
$smarty->setErrorReporting($this->isDev() ? E_ALL : 0);
$smarty->setErrorReporting($this->isProduction() ? 0 : E_ALL);
$smarty->setCompileId($this->config->getSettings(Schema::MODULE_NAME)['design']);
$smarty->setCompileCheck($this->isDev());
$smarty->setCompileCheck($this->isProduction());
$smarty->setCompileDir($this->appPath->getCacheDir() . 'tpl_compiled/');
$smarty->setCacheDir($this->appPath->getCacheDir() . 'tpl_cached/');
}
......@@ -56,8 +49,8 @@ class SmartyConfigurator
/**
* @return bool
*/
protected function isDev()
private function isProduction(): bool
{
return $this->environment === ApplicationMode::DEVELOPMENT;
return $this->environment === ApplicationMode::PRODUCTION;
}
}
......@@ -18,7 +18,6 @@ class ServerError extends Core\Controller\AbstractFrontendAction
$this->translator->t('errors', 'frontend_index_server_error'),
$this->request->getQuery()
);
$this->setLayout('Errors/layout.tpl');
$this->response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
......
{extends file="asset:layout.tpl"}
{extends file="asset:$LAYOUT"}
{block CONTENT}
{include file="asset:System/Partials/no_results.tpl" no_results_text={lang t="errors|access_denied"}}
......
{extends file="asset:layout.tpl"}
{extends file="asset:$LAYOUT"}
{block CONTENT}
{include file="asset:System/Partials/no_results.tpl" no_results_text={lang t="errors|file_not_found"}}
......
......@@ -17,4 +17,3 @@ services:
class: ACP3\Modules\ACP3\Errors\Controller\Frontend\Index\ServerError
arguments:
- '@core.context.frontend'
This diff is collapsed.
# ACP3/module-installer
Repository of the installer module of the ACP3 CMS.
## Attention
Please do not make pull requests to this repository, as it is just a read only repository.
Please make pull requests to the [ACP3/cms](https://gitlab.com/ACP3/cms.git) repository.
{extends file="asset:$LAYOUT"}
{block CONTENT}
{include file="asset:System/Partials/no_results.tpl" no_results_text={lang t="errors|file_not_found"}}
{/block}
{extends file="asset:$LAYOUT"}
{block CONTENT}
{include file="asset:System/Partials/no_results.tpl" no_results_text={lang t="errors|server_unavailable"}}
<p class="text-center">
<a href="{uri args=""}" class="btn btn-primary btn-lg">{lang t="errors|retry"}</a>
</p>
{/block}
{extends file="asset:`$LAYOUT`"}
{block CONTENT}
<p>
{lang t="installer|step_1_paragraph_1"}
</p>
<fieldset>
<legend>{lang t="installer|step_1_legend"}</legend>
<ol>
<li>{lang t="installer|step_1_list_item_1"}</li>
<li>{lang t="installer|step_1_list_item_2"}</li>
<li>{lang t="installer|step_1_list_item_3"}</li>
<li>{lang t="installer|step_1_list_item_4"}</li>
</ol>
</fieldset>
<div class="well well-sm text-center">
<a href="{uri args="installer/index/licence"}" class="btn btn-default">{lang t="installer|forward"}</a>
</div>
{/block}
......@@ -2,9 +2,9 @@
{block CONTENT}
<p>
{lang t="install|installation_error"}
{lang t="installer|installation_error"}
</p>
<div class="well well-sm text-center">
<a href="{uri args="install"}" class="btn btn-default">{lang t="install|back"}</a>
<a href="{uri args="install"}" class="btn btn-default">{lang t="installer|back"}</a>
</div>
{/block}
......@@ -2,13 +2,13 @@
{block CONTENT}
<p>
{lang t="install|installation_successful_1"}
{lang t="installer|installation_successful_1"}
</p>
<div class="alert alert-warning">
{lang t="install|installation_successful_2"}
{lang t="installer|installation_successful_2"}
</div>
<div class="well well-sm text-center">
<a href="{$ROOT_DIR}" class="btn btn-default">{lang t="install|go_to_website"}</a>
<a href="{$ROOT_DIR}acp/" class="btn btn-default">{lang t="install|log_into_admin_panel"}</a>
<a href="{$ROOT_DIR}" class="btn btn-default">{lang t="installer|go_to_website"}</a>
<a href="{$ROOT_DIR}acp/" class="btn btn-default">{lang t="installer|log_into_admin_panel"}</a>
</div>
{/block}
......@@ -2,7 +2,7 @@
{block CONTENT}
{stylesheets}
{include_stylesheet module="install" file="style"}
{include_stylesheet module="installer" file="style"}
{/stylesheets}
<div class="well well-sm licence">
......@@ -189,7 +189,7 @@
</p>
</div>
<div class="well well-sm text-center">
<a href="{uri args="install/index/requirements"}" class="btn btn-success">{lang t="install|accept"}</a>
<a href="{uri args="install"}" class="btn btn-danger">{lang t="install|decline"}</a>
<a href="{uri args="installer/index/requirements"}" class="btn btn-success">{lang t="installer|accept"}</a>
<a href="{uri args="install"}" class="btn btn-danger">{lang t="installer|decline"}</a>
</div>
{/block}