Skip to content

Instantly share code, notes, and snippets.

@AnrDaemon
Last active May 14, 2020 22:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AnrDaemon/f4201775789912506d1e5030f8339241 to your computer and use it in GitHub Desktop.
Save AnrDaemon/f4201775789912506d1e5030f8339241 to your computer and use it in GitHub Desktop.
Application bootstrap
<?php
namespace AnrDaemon\CcWeb;
// Project configuration
require_once __DIR__ . '/init-main.php';
use
AnrDaemon\Net\Url
;
$uri = Url::fromHttp();
if($uri->path[0] !== '/')
throw new Exceptions\RoutingException("Bad path in request.", 400);
if($_SERVER['REQUEST_METHOD'] === 'POST')
{
switch($uri->path)
{
case '/backend/auth':
return Controllers\AuthHandler::create($cfg)->run($_POST);
break;
case '/backend/item':
$controller = Controllers\ItemHandler::create($cfg, [
'page' => isset($uri['page']) ? $uri['page'] : null,
'iid' => isset($uri['id']) ? $uri['id'] : null,
] + $_GET);
return $controller->run(["_files_" => $_FILES] + $_POST);
break;
case '/backend/news':
$controller = Controllers\NewsHandler::create($cfg, [
'page' => isset($uri['page']) ? $uri['page'] : null,
'nid' => isset($uri['id']) ? $uri['id'] : null,
] + $_GET);
return $controller->run(["_files_" => $_FILES] + $_POST);
break;
case '/backend/order':
return Controllers\OrderHandler::create($cfg, [
'page' => 3,
'path' => $uri->path,
] + $_GET)->run(["_files_" => $_FILES] + $_POST);
break;
case '/backend/page':
$controller = Controllers\PageHandler::create($cfg, $_GET);
return $controller->run(["_files_" => $_FILES] + $_POST);
break;
case '/backend/section':
$controller = Controllers\SectionHandler::create($cfg, [
'page' => isset($uri['page']) ? $uri['page'] : null,
'sid' => isset($uri['id']) ? $uri['id'] : null,
] + $_GET);
return $controller->run(["_files_" => $_FILES] + $_POST);
break;
case '/backend/unit':
$controller = Controllers\PageUnitHandler::create($cfg, [
'page' => isset($uri['page']) ? $uri['page'] : null,
'id' => isset($uri['id']) ? $uri['id'] : null,
] + $_GET);
return $controller->run(["_files_" => $_FILES] + $_POST);
break;
default:
throw new Exceptions\RoutingException("Method not allowed", 405); // 405 Method not allowed
}
}
elseif($_SERVER['REQUEST_METHOD'] === 'GET' || $_SERVER['REQUEST_METHOD'] === 'HEAD')
{
$uri = Utility\Request::filterGet($uri);
$r = new Routers\LegacyPrerouter;
$r->dispatch($uri);
$DSN = "sqlite:" . dirname(__DIR__) . "/inc/hru_map.sqlite";
$_sqlite = new Wrappers\DbmSqlite($DSN, null, null, array(
\PDO::ATTR_PERSISTENT => false,
));
$r = new Routers\HruHackPrerouter($_sqlite);
$r->dispatch($uri);
try
{
$route = $cfg->getRouter()->findByPath($uri->path) ?: $cfg->getRouter()->tryLegacyRoute($uri->path);
}
catch(Exceptions\UnroutableDestinationException $e)
{
throw new Exceptions\RoutingException("", 404, null, $e);
}
if(empty($route))
{
switch($uri->path)
{
case '/admin':
throw new Exceptions\RoutingException("Old admin panel init workaround.", 301, '/admin/'); // 301 Moved permanently
break;
case '/admin/auth':
return Controllers\AuthForm::create($cfg, ["path" => $uri->path] + $_GET)->run();
break;
case '/backend/basket_remote':
return require "{$_SERVER['DOCUMENT_ROOT']}/backend/basket_remote.php";
break;
case '/backend/item':
return Controllers\ItemSearch::create($cfg, [] + $_GET)->run();
break;
case '/sample':
return Controllers\Sample::create($cfg, $uri)->run();
break;
default: // Path is valid but not routable =404
throw new Exceptions\RoutingException("", 404); // 404 no valid route found
}
}
if(!empty($route['path']) && ($route['path'] !== $uri->path))
{
$_redir = $uri->setParts(['path' => $route['path']]);
throw new Exceptions\RoutingException("Redirecting to canonical path.", 301, "$_redir");
}
//return var_dump($route);
$meta = $route + $cfg->getRouter()->findById(null) + (array)$uri->query;
$controller = $cfg->getRouter()->getController($route);
if(!($controller instanceof Interfaces\Controller))
{ // Does not look like it is a controller - don't know how to render.
throw new Exceptions\UnroutableDestinationException("Unable to run the page.");
}
$controller = $controller->setMetadata($meta);
return $controller->run();
}
else
{
throw new Exceptions\RoutingException("Method not allowed", 405); // 405 Method not allowed
}
<?php
/** Console _SERVER variable overrides
*
* @version $Id: config-console.php 1289 2018-08-18 14:12:37Z anrdaemon $
*/
$__override = array(
'DOCUMENT_ROOT' => dirname(__DIR__) . "/htdocs",
'SERVER_NAME' => php_uname('n'),
);
foreach($__override as $key => $value)
if(empty($_SERVER[$key]))
$_SERVER[$key] = $value;
unset($__override);
<?php
define('_BASE_DIR', dirname(__DIR__));
// Composer
require_once _BASE_DIR . "/vendor/autoload.php";
// Initial configuration
require_once __DIR__ . '/config.php';
// Console overrides
if(PHP_SAPI === 'cli')
require_once __DIR__ . '/config-console.php';
<?php
namespace AnrDaemon\CcWeb;
// Project configuration
require_once __DIR__ . '/includes.php';
use
AnrDaemon\Net\Url
;
$cfg = new SettingsManager();
try
{
$pdo = new Wrappers\DbmMysql($pdo["DSN"], $pdo["User"], $pdo["Pass"]);
}
catch(\PDOException $e)
{
$key = get_class($e) . "#" . md5(time() . mt_rand());
error_log($key);
error_log($e);
die("Unable to connect to the database (code {$e->getCode()}, key $key).");
}
$cfg->setDatabaseManager($pdo);
$cfg->setRegistry("router", new Registry\RouterRegistry($cfg));
//$cfg->setRegistry("item", new Registry\ItemRegistry($cfg, 5));
//$cfg->setRegistry("news", new Registry\NewsRegistry($cfg, 2));
//$cfg->setRegistry("page", new Registry\PageRegistry($cfg));
//$cfg->setRegistry("section", new Registry\SectionRegistry($cfg, 5));
$cfg->setRouter(new Routers\MainRouter($cfg));
$sec = new Wrappers\OldAuth($cfg, '/admin/auth');
$cfg->setSecurityManager($sec);
$tpl = new Wrappers\Smarty();
//$tpl::$_CHARSET =
$tpl->setForceCompile(isset($smarty["ForceCompile"]) ? $smarty["ForceCompile"] : false);
$tpl->setCompileCheck($smarty["CompileCheck"]);
$tpl->setCaching($smarty["Caching"]);
$tpl->setCacheLifetime($smarty["CacheLifetime"]);
$tpl->setConfigDir("{$smarty['BaseDir']}/configs");
$tpl->addPluginsDir("{$smarty['BaseDir']}/plugins");
$tpl->setTemplateDir("{$smarty['BaseDir']}/templates");
$tpl->setCacheDir("{$smarty['TempDir']}/cache");
$tpl->setCompileDir("{$smarty['TempDir']}/templates");
$tpl->configLoad('site.cfg');
$tpl->registerPlugin('function', 'svgImage', [
(new View\SvgImage('/img/cat/icon'))->setCacheLifetime(86400),
'render'
], false, [
'name', 'id', 'class', 'style', 'fallback',
]);
$tpl->registerPlugin('modifier', 'get_conf', [$cfg, 'getOption']);
$nf = new \NumberFormatter("ru_RU", \NumberFormatter::CURRENCY);
$cs = ini_get('output_encoding') ?: ini_get('iconv.output_encoding') ?: ini_get('default_charset') ?: 'ISO-8859-1';
$tpl->registerPlugin('modifier', 'price',
function($price, $currency = 'RUB')
use($nf, $cs)
{
return iconv('UTF-8', "$cs//IGNORE", $nf->formatCurrency($price, $currency));
}
);
unset($nf, $cs);
$tpl->registerPlugin('modifier', 'clear', 'AnrDaemon\\CcWeb\\Utility\\Strings::cleartext');
$tpl->registerPlugin('modifier', 'cut_string', 'AnrDaemon\\CcWeb\\Utility\\Strings::cut');
$tpl->registerPlugin('modifier', 'cyr_trans', 'AnrDaemon\\CcWeb\\Utility\\Strings::transliterate');
$tpl->registerPlugin('modifier', 'shorten', 'AnrDaemon\\CcWeb\\Utility\\Strings::shorten');
$tpl->registerPlugin('modifier', 'transurl', 'AnrDaemon\\CcWeb\\Utility\\Strings::transurl');
$preg = $cfg->getRouter()->getChildRegistry();
$tpl->registerPlugin('modifier', 'get_page', function(array $meta)
use($preg)
{
if(empty($meta[0]))
return null;
$page = $preg->findById($meta[0]);
if(empty($page['published']))
return null;
$page = empty($meta[1]) ? $page->transform() : $preg->getChildRegistry($page)->findById($meta[1])->transform();
return $page['published'] ? $page : null;
});
unset($preg);
$tpl->registerPlugin('modifier', 'dict', function($name, $dict, $field = "value")
use($cfg)
{
$result = $cfg->getDictionary($dict)->get($name, $field);
if(empty($result))
return null;
return $result;
});
$cfg->setTemplateManager($tpl);
$cfg->setDictionary('units', Registry\DictionaryProxy::createDb(
$cfg->getDatabaseManager(),
'units', 'id', 'alias', [
'title' => 'name',
'showorder' => 'showorder',
]
));
$cfg->setDictionary('templates', Registry\DictionaryProxy::createDb(
$cfg->getDatabaseManager(),
'templates', 'id', 'alias', [
'title' => 'tname',
'showorder' => 'showorder',
]
));
$cfg->setDictionary('newstypes', Registry\DictionaryProxy::createDb(
$cfg->getDatabaseManager(),
'dict_newstypes', 'type', 'name'
));
$cfg->setDictionary('sections', Registry\DictionaryProxy::createDb(
$cfg->getDatabaseManager(),
'cat_section', 'id', 'title'
));
$cfg->setDictionary('currency', Registry\DictionaryProxy::createDb(
$cfg->getDatabaseManager(),
'dict_currency', 'code', 'name'
));
$cfg->setDictionary('price', Registry\DictionaryProxy::createDb(
$cfg->getDatabaseManager(),
'dict_pricetype', 'type', 'name'
));
\call_user_func(
function()
use($cfg)
{
$url = Url::fromHttp();
\set_exception_handler(
function(\Exception $e)
// TODO:PHP7 set_exception_handler(function(\Throwable $e)
use($cfg, $url)
{
switch(true)
{
case $e instanceof Exceptions\RoutingException :
// Execute a routing exception
return Controllers\ErrorPage::create($cfg, $e)->run($url);
break;
case $e instanceof Interfaces\FrameworkException :
// Throw 500 ISE with custom message for framework errors
return Controllers\ErrorPage::create(
$cfg,
new Exceptions\RoutingException($e->getMessage() . " (code:{$e->getCode()})", 500, '', $e)
)->run($url);
break;
default:
// Any other exception: Throw 500 ISE
\error_log($e);
return Controllers\ErrorPage::create(
$cfg,
new Exceptions\RoutingException("", 500, '', $e)
)->run($url);
break;
}
}
);
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment