mirror of
https://github.com/avecms/AVE.cms.git
synced 2026-08-01 08:45:44 +00:00
151 lines
6.0 KiB
PHP
151 lines
6.0 KiB
PHP
<?php
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------------------
|
|
| AVE.cms
|
|
|--------------------------------------------------------------------------------------
|
|
| @package AVE.cms
|
|
| @file system/App/Frontend/PublicPageLifecycle.php
|
|
| @author AVE.cms <support@ave-cms.ru>
|
|
| @copyright 2007-2026 (c) AVE.cms
|
|
| @link https://ave-cms.ru
|
|
| @version 3.3
|
|
*/
|
|
|
|
namespace App\Frontend;
|
|
|
|
defined('BASEPATH') || die('Direct access to this location is not allowed.');
|
|
|
|
use App\Common\PublicModuleRuntime;
|
|
use App\Common\Lifecycle;
|
|
use App\Common\Registry;
|
|
use App\Common\StoredPhpRuntime;
|
|
use App\Helpers\Debug;
|
|
|
|
/** Resolves document state and finalizes output around the native page renderer. */
|
|
class PublicPageLifecycle
|
|
{
|
|
protected static $notFoundPrepared = false;
|
|
|
|
public static function resolve($requestUri)
|
|
{
|
|
$core = new PublicPageRenderer();
|
|
|
|
$resolver = new PublicDocumentResolver();
|
|
$core->curentdoc = $resolver->resolve(
|
|
PublicModuleRuntime::hasDeferredPage() ? '/' : (string) $requestUri,
|
|
UGROUP
|
|
);
|
|
self::applyDeferredMetadata($core);
|
|
PublicPageContext::setDocument($core->curentdoc);
|
|
|
|
$route = Lifecycle::event('frontend.route.resolved', 'route', 'resolved', PublicPageContext::documentId(), array(
|
|
'request_uri' => (string) $requestUri,
|
|
'document' => $core->curentdoc,
|
|
'deferred_page' => PublicPageContext::hasDeferredPage(),
|
|
), $core->curentdoc, array(), 'public_page_lifecycle');
|
|
if (is_object($route->result())) {
|
|
$core->curentdoc = $route->result();
|
|
PublicPageContext::setDocument($core->curentdoc);
|
|
}
|
|
|
|
return $core;
|
|
}
|
|
|
|
protected static function applyDeferredMetadata($core)
|
|
{
|
|
if (!PublicPageContext::hasDeferredPage() || empty($core->curentdoc)) { return; }
|
|
|
|
$page = PublicPageContext::deferredPage();
|
|
if (!empty($page['title'])) { $core->curentdoc->document_title = (string) $page['title']; }
|
|
$core->curentdoc->document_meta_description = isset($page['description']) ? (string) $page['description'] : '';
|
|
$core->curentdoc->document_meta_robots = isset($page['robots']) ? (string) $page['robots'] : 'noindex,follow';
|
|
$path = parse_url(isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/', PHP_URL_PATH);
|
|
$core->curentdoc->document_alias = trim((string) $path, '/');
|
|
}
|
|
|
|
public static function execute($content, array $context)
|
|
{
|
|
$content = (string) $content;
|
|
$rendering = Lifecycle::event('content.template.rendering', 'template', 'executing', PublicPageContext::documentId(), array(
|
|
'context' => array('document_id' => PublicPageContext::documentId()),
|
|
), $content, array('stored_php' => true), 'public_page_lifecycle');
|
|
if ($rendering->cancelled()) { echo (string) $rendering->result(); return true; }
|
|
$content = (string) $rendering->result();
|
|
// Historical template #1 denied every guest and only appeared to work while full-page cache was warm.
|
|
$content = preg_replace("#<\?php\s+if\s*\(UGROUP\s*!=\s*1\)\s*die\(['\"]Пусто['\"]\);\s*\?>#u", '', $content, 1);
|
|
try {
|
|
StoredPhpRuntime::execute($content, $context);
|
|
Lifecycle::event('content.template.rendered', 'template', 'executed', PublicPageContext::documentId(), array(
|
|
'document_id' => PublicPageContext::documentId(),
|
|
), true, array('stored_php' => true), 'public_page_lifecycle');
|
|
return true;
|
|
} catch (\Throwable $e) {
|
|
error_log(sprintf(
|
|
'Public template render failed [%s] %s in %s:%d',
|
|
get_class($e),
|
|
$e->getMessage(),
|
|
$e->getFile(),
|
|
$e->getLine()
|
|
));
|
|
http_response_code(500);
|
|
echo 'Ошибка формирования страницы.';
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static function prepareResponseStatus()
|
|
{
|
|
if (!PublicPageContext::isNotFound()) { return; }
|
|
if (!self::$notFoundPrepared) { \App\Common\CsvLogWriter::notFound(); \App\Common\NotFoundLog::record(); self::$notFoundPrepared = true; }
|
|
http_response_code(404);
|
|
}
|
|
|
|
public static function finish($render, $core)
|
|
{
|
|
if (PublicPageContext::isNotFound()) {
|
|
if (!self::$notFoundPrepared) { \App\Common\CsvLogWriter::notFound(); \App\Common\NotFoundLog::record(); self::$notFoundPrepared = true; }
|
|
http_response_code(404);
|
|
}
|
|
|
|
if (self::paginationIsOutOfRange()) {
|
|
$id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 1;
|
|
$location = $id === 1
|
|
? ABS_PATH
|
|
: ABS_PATH . (isset($core->curentdoc->document_alias) ? $core->curentdoc->document_alias : '') . URL_SUFF;
|
|
header('Location:' . $location);
|
|
exit;
|
|
}
|
|
|
|
PublicProfiler::record(array('DOCUMENT', 'CONTENT'), Debug::endTime('CONTENT'));
|
|
PublicProfiler::record(array('INIT', 'CODEEND'), Debug::endTime('CODEEND'));
|
|
$response = Lifecycle::event('frontend.response.rendering', 'response', 'rendering', PublicPageContext::documentId(), array(
|
|
'status' => (int) (http_response_code() ?: 200),
|
|
), (string) $render, array(), 'public_page_lifecycle');
|
|
$render = (string) $response->result();
|
|
$render = \App\Frontend\QuickEdit\PublicQuickEdit::inject($render);
|
|
$rendered = Lifecycle::event('frontend.response.rendered', 'response', 'rendered', PublicPageContext::documentId(), array(
|
|
'status' => (int) (http_response_code() ?: 200),
|
|
), (string) $render, array(), 'public_page_lifecycle');
|
|
$render = (string) $rendered->result();
|
|
$render = SiteAccess::injectPreviewNotice($render);
|
|
$render = \App\Frontend\Debug\PublicDebugToolbar::inject($render, $core);
|
|
Registry::clean();
|
|
PublicHtmlResponse::emit((string) $render);
|
|
|
|
}
|
|
|
|
protected static function paginationIsOutOfRange()
|
|
{
|
|
if (!empty($_REQUEST['module'])) { return false; }
|
|
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : '';
|
|
foreach (array('page', 'apage', 'artpage') as $name) {
|
|
if (!isset($_REQUEST[$name]) || !is_numeric($_REQUEST[$name])) { continue; }
|
|
$maximum = PublicPageContext::paginationMaximum($id, $name);
|
|
if ((float) $_REQUEST[$name] < 2 || (float) $_REQUEST[$name] > (float) $maximum) { return true; }
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|