Skip to content

Instantly share code, notes, and snippets.

@NoelDavies
Created December 29, 2015 20:19
Show Gist options
  • Save NoelDavies/78d85a2e54461a7c10bb to your computer and use it in GitHub Desktop.
Save NoelDavies/78d85a2e54461a7c10bb to your computer and use it in GitHub Desktop.
<?php
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
use Nette\Caching\Cache;
use Nette\Caching\Storages\FileStorage;
use Nette\Utils\Strings;
/**
* Class ApplicationRouter
*/
class ApplicationRouter {
/** @var \DibiConnection */
public $db;
/** @var RouteList */
public $router;
/** @var array */
public $variables;
/** @var FileStorage */
private $storage;
/** @var array */
private $languages;
/**
* @param RouteList $router
* @param array $variables
* @param DibiConnection $db
* @param FileStorage $storage
*/
public function __construct(RouteList $router, array $variables, DibiConnection $db, FileStorage $storage) {
$this->router = $router;
$this->variables = $variables;
$this->db = $db;
$this->storage = $storage;
}
/**
* @internal param $router
* @internal param array $variables
*/
public function createRoutesServer() {
$router = $this->router;
$variables = $this->variables;
$url = $variables['url'];
$presenter = $variables['presenter'];
$action = $variables['action'];
$lang = $variables['lang'];
$matskup = $variables['matskup'];
$router[] = new Route('index.php', 'Eshop:' . $presenter . ':' . $action, Route::ONE_WAY);
$router[] = new Route('sitemap.xml', 'Eshop:Response:generateSitemap', Route::ONE_WAY);
$this->defineRoutesAdmin($router, $url, 'Admin', $lang);
$this->defineRoutesOdbyt($router, $url, 'Odbyt');
$this->defineRoutesEshop($router, $url, 'Eshop', $lang, $matskup);
}
/**
* @param $router
* @param $url
* @param $module
*
* @param $def_lang
*
* @return array
*/
protected function defineRoutesAdmin($router, $url, $module, $def_lang) {
$router[] = $adminRouter = new RouteList($module);
$adminRouter[] = new Route(
'//' . $url . '/[!<lang [a-z]{2}>/]' . strtolower($module) . '/<presenter>/<action>[/<id>]',
[
"presenter" => "Default",
"action" => "default",
"lang" => $def_lang,
]
);
return $router;
}
/**
* @param $router
* @param $url
* @param $module
*
* @return mixed
*/
protected function defineRoutesOdbyt($router, $url, $module) {
$router[] = $moduleRouter = new RouteList($module);
$lang = 'sk';
$module = strtolower($module) . '/';
$page = '?page=<paginator-page>';
$id = '[/<id>]';
$matskup = '[/<matskup>]';
$langs = '/[!<lang [a-z]{2}>/]';
$key = '[/<key>]';
$way = '//' . $url . $langs . $module;
$cmpSelect = '[/<companiesSelect-tab p|f|null>][/<companiesSelect-p-page=0 [0-9]>]';
$cmpSelectTable = [
'f' => 'companies',
'p' => 'traffics',
null => 'all',
];
$moduleRouter[] = new Route(
$way . 'vyber-subjektu' . $cmpSelect, [
'presenter' => 'Login',
'action' => 'select',
'companiesSelect-tab' => [
Route::FILTER_IN => function ($tab) use ($cmpSelectTable) {
return $cmpSelectTable[$tab === '' || $tab === 'all' ? '' : $tab];
},
Route::FILTER_OUT => function ($tab) use ($cmpSelectTable) {
return array_search($tab, $cmpSelectTable, true);
},
],
'lang' => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'katalog/akcie' . $matskup . $id . $page, [
"presenter" => "Catalog",
"action" => "discounts",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'katalog/novinky' . $matskup . $id . $page, [
"presenter" => "Catalog",
"action" => "introductions",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'katalog/vypredaj' . $matskup . $id . $page, [
"presenter" => "Catalog",
"action" => "sales",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'katalog' . $matskup . $id . $page, [
"presenter" => "Catalog",
"action" => "view",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'hladaj' . $id . $page, [
"presenter" => "Catalog",
"action" => "search",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'kategorie' . $matskup . $id . $page, [
"presenter" => "Catalog",
"action" => "categories",
"lang" => $lang,
]
);
/** odtialto */
$moduleRouter[] = new Route(
$way . 'objednavky' . $id . $page, [
"presenter" => "Orders",
"action" => "default",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'objednavka' . $key . $id . $page, [
"presenter" => "Orders",
"action" => "view",
"lang" => $lang,
]
);
$cart = 'kosiky';
$moduleRouter[] = new Route(
$way . $cart . $id . $page,
["presenter" => "Cart", "action" => "default", "lang" => $lang]
);
$moduleRouter[] = new Route(
$way . $cart . '/detail' . $key . $id . $page, [
"presenter" => "Cart",
"action" => "view",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . $cart . '/kontrola' . $key . $id . $page, [
"presenter" => "Cart",
"action" => "view",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . $cart . '/doprava' . $key . $id . $page, [
"presenter" => "Cart",
"action" => "options",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . $cart . '/doprava' . $key . $id . $page, [
"presenter" => "Tranposrt",
"action" => "default",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'prihlasenie' . $key . $id . $page, [
"presenter" => "Login",
"action" => "login",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'kontakty' . $id . $page,
["presenter" => "Homepage", "action" => "contacts", "lang" => $lang]
);
$moduleRouter[] = new Route(
$way . 'uvod' . $id . $page,
["presenter" => "Homepage", "action" => "default", "lang" => $lang]
);
$moduleRouter[] = new Route(
$way . 'obchodne-podmienky' . $id . $page, [
"presenter" => "Homepage",
"action" => "terms",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'prepravne-podmienky' . $id . $page, [
"presenter" => "Homepage",
"action" => "dop",
"lang" => $lang,
]
);
$moduleRouter[] = new Route(
$way . 'produkt' . $key . $id . $page, [
"presenter" => "Product",
"action" => "default",
"lang" => $lang,
]
);
/** sem */
$moduleRouter[] = new Route(
$way . '<presenter>/<action>' . $matskup . $id, [
"presenter" => 'Cart',
"action" => 'default',
"lang" => $lang,
]
);
return $router;
}
/**
* @param $router
* @param $url
* @param $module
* @param $lang
* @param $smatskup
*
* @internal param $matskup
* @return array
*/
protected function defineRoutesEshop($router, $url, $module, $lang, $smatskup) {
$moduleRouter = new RouteList($module);
$slang = '/[!<lang [a-z]{2}>/]';
$way = '//' . $url;
$extends['catalog'] = '[/<matskup>]?page=<paginator-page>';
$extends['product'] = '/<key>[/<key2>]';
$md5 = md5("{$url}-{$lang}");
$cache = new Cache($this->storage);
if ($cache->offsetExists('eshop-router-' . $md5) && !in_array(
$_SERVER['REMOTE_ADDR'],
['127.0.0.1', 'localhost']
)
) {
$this->customRoutes($router, $lang, $way);
$router[] = $cache->load('eshop-router-' . $md5);
return $router;
}
$this->languages = $this->db
->select('*')
->from('jazyky')
->fetchPairs('skratka', 'skratka');
$routes = $this->db
->select('webalized, link, unique_key, enabled, primar')
->from('menu')
->where('link like %~like~', ':')
// ->where('enabled IN %in', [1, 2])
->fetchAssoc('unique_key');
$primare_routes = [];
$catalog_routes = [];
foreach ($routes as $key => $page) {
$builded = false;
if ($page->unique_key !== 'carts' &&
(Strings::startsWith($page->unique_key, 'cart') ||
Strings::startsWith($page->unique_key, 'transport') ||
$page->unique_key === 'thanks-giving')
) {
$this->routeGroup(
$page,
$routes['carts'],
['way' => $way, 'extend' => '[/<key>]'],
$moduleRouter
);
$builded = true;
} elseif ($page->unique_key !== 'catalog' && Strings::startsWith($page->unique_key, 'catalog')) {
$this->routeGroup(
$page,
$routes['catalog'],
['way' => $way, 'extend' => $extends['catalog']],
$moduleRouter
);
$builded = true;
} elseif ($page->unique_key === 'order') {
$this->routeGroup(
$page,
$routes['orders'],
['way' => $way, 'extend' => '[/<key>]'],
$moduleRouter
);
$builded = true;
} elseif ($page->unique_key !== 'register' && Strings::startsWith($page->unique_key, 'register')) {
$this->routeGroup(
$page,
$routes['register'],
['way' => $way, 'extend' => null],
$moduleRouter
);
$builded = true;
} elseif ($page->unique_key !== 'cms' && Strings::startsWith($page->link, 'Cms:')) {
$this->routeGroup(
$page,
$routes['cms'],
['way' => $way, 'extend' => null],
$moduleRouter
);
$builded = true;
} elseif ($page->unique_key !== 'account' && Strings::startsWith($page->unique_key, 'account')) {
$this->routeGroup(
$page,
$routes['account'],
['way' => $way, 'extend' => null],
$moduleRouter
);
$builded = true;
}
if ($builded === false || $page->primar) {
list($presenter, $action) = explode(':', $page->link);
$un = @unserialize($page->webalized);
if ($un !== false) {
$not_set = [];
if (count($un) !== count($this->languages)) {
$not_set = array_diff_key($this->languages, $un);
}
foreach ($un as $l => $web) {
//@todo: Commented, who knows why its not working
// if (!empty($primare_routes)) {
// continue;
// }
if (!empty($not_set) && $l === $this->variables['lang']) {
$not_set[] = $l;
$r_lang = '/[!<lang (' . join('|', $not_set) . ')>/]';
} else {
$r_lang = '/[!<lang (' . $l . ')>/]';
}
if (count($un) === 1) {
$r_lang = '/[!<lang [a-z]{2}>/]';
}
if (!$page->primar) {
$route = new Route(
$way . $r_lang . $web .
(isset($extends[$page->unique_key]) ? $extends[$page->unique_key] : null),
[
'presenter' => $presenter,
'action' => $action,
'lang' => $l,
]
);
if ($page->unique_key === 'catalog' && $page->link === 'Catalog:categories') {
$url = $way . $r_lang . $web .
(isset($extends[$page->unique_key]) ? $extends[$page->unique_key] : null);
$url = str_replace('[/<matskup>]', '/<matskup>', $url);
$catalog_routes[] = new Route(
$url,
[
'presenter' => 'Catalog',
'action' => 'view',
'lang' => $l,
]
);
} elseif ($page->unique_key === 'catalog' && $page->link !== 'Catalog:categories') {
$catalog_routes[] = $route;
} else {
$moduleRouter[] = $route;
}
} else {
if ($page->unique_key === 'catalog' && $page->link === 'Catalog:categories') {
$url = $way . $r_lang . $web .
(isset($extends[$page->unique_key]) ? $extends[$page->unique_key] : null);
$url = str_replace('[/<matskup>]', '/<matskup>', $url);
$catalog_routes[] = new Route(
$url,
[
'presenter' => 'Catalog',
'action' => 'view',
'lang' => $l,
]
);
}
$primare_routes[] = new Route(
$way . $r_lang . $web .
(isset($extends[$page->unique_key]) ? $extends[$page->unique_key] : null),
[
'presenter' => $presenter,
'action' => $action,
'lang' => $l,
]
);
$primare_routes[] = new Route(
$way .
'/[!<lang (' . join('|', array_keys($un)) . ')>/]<presenter>/<action>' .
(isset($extends[$page->unique_key]) ? $extends[$page->unique_key] : null),
[
'presenter' => $presenter,
'action' => $action,
'matskup' => $smatskup,
'lang' => $l,
]
);
}
}
}
}
}
foreach ($catalog_routes as $route) {
$moduleRouter[] = $route;
}
foreach ($primare_routes as $l => $route) {
$moduleRouter[] = $route;
}
$cache->save(
'eshop-router-' . $md5,
$moduleRouter,
[
Cache::EXPIRATION => '+4 hours',
Cache::TAGS => ['menu', 'router'],
]
);
$this->customRoutes($router, $lang, $way . $slang);
$router[] = $moduleRouter;
return $router;
}
private function routeGroup($page, $main, array $route_parts, &$router) {
if ($page->primar) {
return;
}
$main_webalized = @unserialize(@$main->webalized);
$un = @unserialize($page->webalized);
list($presenter, $action) = explode(':', $page->link);
if ($un !== false) {
// Check all languages, which not have translation
$not_set = [];
if (count($un) !== count($this->languages)) {
$not_set = array_diff_key($this->languages, $un);
}
foreach ($un as $l => $web) {
if (!$web) {
$web = $main_webalized[$this->variables['lang']];
}
if (!empty($not_set) && $l === $this->variables['lang']) {
$not_set[] = $l;
$r_lang = '/[!<lang (' . join('|', $not_set) . ')>/]';
} else {
$r_lang = '/[!<lang (' . $l . ')>/]';
}
if (count($un) === 1) {
$r_lang = '/[!<lang [a-z]{2}>/]';
}
$web_main = isset($main_webalized[$l])
? $main_webalized[$l]
: $main_webalized[$this->variables['lang']];
$route = new Route(
$route_parts['way'] . $r_lang . $web_main . '/' . $web .
$route_parts['extend'],
[
'presenter' => $presenter,
'action' => $action,
'lang' => $l,
]
);
$router[] = $route;
}
}
}
/**
* @param $router
* @param $lang
* @param $way
*/
protected function customRoutes(&$router, $lang, $way) {
/******** CUSTOM *********/
$router[] = new Route(
$way . 'servis[/<id>]', [
'module' => 'Eshop',
'presenter' => 'Service',
'action' => 'client',
'lang' => $lang,
'id' => [
Route::FILTER_IN => function ($id) {
switch ($id) {
case 'odstupenie-od-zmluvy':
return 'withdrawal';
case 'reklamacny-protokol':
return 'claim';
default:
return $id;
}
},
Route::FILTER_OUT => function ($id) {
switch ($id) {
case 'withdrawal':
return 'odstupenie-od-zmluvy';
case 'claim':
return 'reklamacny-protokol';
default:
return $id;
}
},
],
]
);
/******** *********/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment