Basic functionality

This commit is contained in:
2022-03-12 16:25:30 +01:00
parent f3beaa64cf
commit acc21b7b24
137 changed files with 12647 additions and 5089 deletions

View 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');
}
}

View 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';
}
});
}
}

View 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;
}

View 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()]
);
}
}
}

View File

@@ -0,0 +1,8 @@
<?php declare(strict_types = 1);
namespace App\Modules\Base;
abstract class UnsecuredPresenter extends BasePresenter
{
}

View 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>

View 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>&copy; 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>