Basic functionality
This commit is contained in:
44
app/modules/Base/BaseError4xxPresenter.php
Executable file
44
app/modules/Base/BaseError4xxPresenter.php
Executable file
@@ -0,0 +1,44 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace App\Modules\Base;
|
||||
|
||||
use App\Model\Exception\Runtime\InvalidStateException;
|
||||
use Nette\Application\BadRequestException;
|
||||
use Nette\Application\Request;
|
||||
use Nette\Application\UI\ComponentReflection;
|
||||
|
||||
abstract class BaseError4xxPresenter extends SecuredPresenter
|
||||
{
|
||||
|
||||
/**
|
||||
* Common presenter method
|
||||
*/
|
||||
public function startup(): void
|
||||
{
|
||||
parent::startup();
|
||||
|
||||
if ($this->getRequest() !== null && $this->getRequest()->isMethod(Request::FORWARD)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->error();
|
||||
}
|
||||
|
||||
public function renderDefault(BadRequestException $exception): void
|
||||
{
|
||||
$rf1 = new ComponentReflection(static::class);
|
||||
$fileName = $rf1->getFileName();
|
||||
|
||||
// Validate if class is not in PHP core
|
||||
if ($fileName === false) {
|
||||
throw new InvalidStateException('Class is defined in the PHP core or in a PHP extension');
|
||||
}
|
||||
|
||||
$dir = dirname($fileName);
|
||||
|
||||
// Load template 403.latte or 404.latte or ... 4xx.latte
|
||||
$file = $dir . '/templates/' . $exception->getCode() . '.latte';
|
||||
$this->template->setFile(is_file($file) ? $file : $dir . '/templates/4xx.latte');
|
||||
}
|
||||
|
||||
}
|
||||
57
app/modules/Base/BaseErrorPresenter.php
Executable file
57
app/modules/Base/BaseErrorPresenter.php
Executable file
@@ -0,0 +1,57 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace App\Modules\Base;
|
||||
|
||||
use Nette\Application\BadRequestException;
|
||||
use Nette\Application\Helpers;
|
||||
use Nette\Application\IResponse as AppResponse;
|
||||
use Nette\Application\Request;
|
||||
use Nette\Application\Responses\CallbackResponse;
|
||||
use Nette\Application\Responses\ForwardResponse;
|
||||
use Nette\Http\IRequest;
|
||||
use Nette\Http\IResponse;
|
||||
use Psr\Log\LogLevel;
|
||||
use Throwable;
|
||||
use Tracy\Debugger;
|
||||
use Tracy\ILogger;
|
||||
|
||||
abstract class BaseErrorPresenter extends SecuredPresenter
|
||||
{
|
||||
|
||||
/**
|
||||
* @return ForwardResponse|CallbackResponse
|
||||
*/
|
||||
public function run(Request $request): AppResponse
|
||||
{
|
||||
$e = $request->getParameter('exception');
|
||||
|
||||
if ($e instanceof Throwable) {
|
||||
$code = $e->getCode();
|
||||
$level = ($code >= 400 && $code <= 499) ? LogLevel::WARNING : LogLevel::ERROR;
|
||||
|
||||
Debugger::log(sprintf(
|
||||
'Code %s: %s in %s:%s',
|
||||
$code,
|
||||
$e->getMessage(),
|
||||
$e->getFile(),
|
||||
$e->getLine()
|
||||
), $level);
|
||||
|
||||
Debugger::log($e, ILogger::EXCEPTION);
|
||||
}
|
||||
|
||||
if ($e instanceof BadRequestException) {
|
||||
[$module, , $sep] = Helpers::splitName($request->getPresenterName());
|
||||
|
||||
return new ForwardResponse($request->setPresenterName($module . $sep . 'Error4xx'));
|
||||
}
|
||||
|
||||
return new CallbackResponse(function (IRequest $httpRequest, IResponse $httpResponse): void {
|
||||
$header = $httpResponse->getHeader('Content-Type');
|
||||
if ($header !== null && preg_match('#^text/html(?:;|$)#', $header)) {
|
||||
require __DIR__ . '/templates/500.phtml';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
23
app/modules/Base/BasePresenter.php
Executable file
23
app/modules/Base/BasePresenter.php
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace App\Modules\Base;
|
||||
|
||||
use App\Model\Latte\TemplateProperty;
|
||||
use App\Model\Security\SecurityUser;
|
||||
use App\UI\Control\TFlashMessage;
|
||||
use App\UI\Control\TModuleUtils;
|
||||
use Contributte\Application\UI\Presenter\StructuredTemplates;
|
||||
use Nette\Application\UI\Presenter;
|
||||
|
||||
/**
|
||||
* @property-read TemplateProperty $template
|
||||
* @property-read SecurityUser $user
|
||||
*/
|
||||
abstract class BasePresenter extends Presenter
|
||||
{
|
||||
|
||||
use StructuredTemplates;
|
||||
use TFlashMessage;
|
||||
use TModuleUtils;
|
||||
|
||||
}
|
||||
30
app/modules/Base/SecuredPresenter.php
Executable file
30
app/modules/Base/SecuredPresenter.php
Executable file
@@ -0,0 +1,30 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace App\Modules\Base;
|
||||
|
||||
use App\Model\App;
|
||||
use Nette\Application\UI\ComponentReflection;
|
||||
use Nette\Security\IUserStorage;
|
||||
|
||||
abstract class SecuredPresenter extends BasePresenter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param ComponentReflection|mixed $element
|
||||
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
|
||||
*/
|
||||
public function checkRequirements($element): void
|
||||
{
|
||||
if (!$this->user->isLoggedIn()) {
|
||||
if ($this->user->getLogoutReason() === IUserStorage::INACTIVITY) {
|
||||
$this->flashInfo('You have been logged out for inactivity');
|
||||
}
|
||||
|
||||
$this->redirect(
|
||||
App::DESTINATION_SIGN_IN,
|
||||
['backlink' => $this->storeRequest()]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
8
app/modules/Base/UnsecuredPresenter.php
Executable file
8
app/modules/Base/UnsecuredPresenter.php
Executable file
@@ -0,0 +1,8 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace App\Modules\Base;
|
||||
|
||||
abstract class UnsecuredPresenter extends BasePresenter
|
||||
{
|
||||
|
||||
}
|
||||
27
app/modules/Base/templates/500.phtml
Executable file
27
app/modules/Base/templates/500.phtml
Executable file
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html><!-- "' --></textarea></script></style></pre></xmp></a></audio></button></canvas></datalist></details></dialog></iframe></listing></meter></noembed></noframes></noscript></optgroup></option></progress></rp></select></table></template></title></video>
|
||||
<meta charset="utf-8">
|
||||
<meta name="robots" content="noindex">
|
||||
<title>Server Error</title>
|
||||
|
||||
<style>
|
||||
#nette-error { all: initial; position: absolute; top: 0; left: 0; right: 0; height: 70vh; min-height: 400px; display: flex; align-items: center; justify-content: center; z-index: 1000 }
|
||||
#nette-error div { all: initial; max-width: 550px; background: white; color: #333; display: block }
|
||||
#nette-error h1 { all: initial; font: bold 50px/1.1 sans-serif; display: block; margin: 40px }
|
||||
#nette-error p { all: initial; font: 20px/1.4 sans-serif; margin: 40px; display: block }
|
||||
#nette-error small { color: gray }
|
||||
</style>
|
||||
|
||||
<div id=nette-error>
|
||||
<div>
|
||||
<h1>Server Error</h1>
|
||||
|
||||
<p>We're sorry! The server encountered an internal error and
|
||||
was unable to complete your request. Please try again later.</p>
|
||||
|
||||
<p><small>error 500</small></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.body.insertBefore(document.getElementById('nette-error'), document.body.firstChild);
|
||||
</script>
|
||||
65
app/modules/Base/templates/@layout.latte
Executable file
65
app/modules/Base/templates/@layout.latte
Executable file
@@ -0,0 +1,65 @@
|
||||
{**
|
||||
* @param string $basePath web base path
|
||||
* @param array $flashes flash messages
|
||||
*}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>{ifset title}{include title|striptags} | {/ifset}Nette Sandbox</title>
|
||||
|
||||
<link rel="stylesheet" href="{$basePath}/css/style.css">
|
||||
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
|
||||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
|
||||
{block head}{/block}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<hgroup>
|
||||
<h1>My Dictionary</h1>
|
||||
<h2>multilanguage dictionary with pronunciations</h2>
|
||||
</hgroup>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="{link Homepage:default}">Jednoduchý</a></li>
|
||||
<li><a href="{link Homepage:ipa}">s výslovnosťou</a></li>
|
||||
<li><a href="{link Homepage:interactive}">Interaktívny</a></li>
|
||||
<li><a href="{link Homepage:alphabet}">Abeceda</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<a href="#" title="Jaro's Solutions homepage"><img src="logo.gif" alt="Jaro's Solutions" /></a>
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<h1 n:ifset="$title">{$title}</h1>
|
||||
|
||||
<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{$flash->message}</div>
|
||||
|
||||
{include content}
|
||||
</article>
|
||||
|
||||
<section>
|
||||
<h1>Slovníky</h1>
|
||||
<ul>
|
||||
{foreach $translations as $tr}
|
||||
<li><a href="{link Homepage:select $tr["slug"] }">{$tr["lang"]}</a></li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<p>© 2016 Jaro's Solutions - <a href="#">Sitemap</a> </p>
|
||||
</footer>
|
||||
|
||||
{block scripts}
|
||||
<script src="https://nette.github.io/resources/js/netteForms.min.js"></script>
|
||||
<script src="{$basePath}/js/nette.ajax.js"></script>
|
||||
<script src="{$basePath}/js/main.js"></script>
|
||||
{/block}
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user