src/Router/Registrar/RouteMakerBase.php
<?php
namespace Strata\Router\Registrar;
use Strata\Strata;
use Exception;
use Strata\Controller\Controller;
use Strata\Utility\Inflector;
use Strata\Utility\Hash;
/**
* Registers rewrite rules defined in model configuration
* files.
*/
abstract class RouteMakerBase
{
/**
* Keeps a lot of the additional Routing routes
* that may have been generated while adding custom
* rewrite rules.
* @var array
*/
private $additionalRoutes = array();
private $additionalRewrites = array();
// Preprocess the rewrites to group them in
// a global single regex
protected $rewriteBatch = array();
protected $model;
protected $defaultSlug;
abstract public function parseObject($model);
abstract protected function extractLocalizedInformation();
abstract protected function getRewritePattern();
abstract protected function getRewriteDestination();
abstract protected function getRewriteIdentifier();
public function getRewrites()
{
return $this->additionalRewrites;
}
public function getRoutes()
{
return $this->additionalRoutes;
}
protected function isLocalizedApp()
{
return Strata::i18n()->isLocalized();
}
protected function getLocales()
{
return Strata::i18n()->getLocales();
}
protected function addRoute($route)
{
$this->additionalRoutes[] = $route;
}
protected function addRewrite($rewrite)
{
$this->additionalRewrites[] = $rewrite;
}
protected function getController()
{
if (array_key_exists("controller", $this->model->routed)) {
$controllerName = $this->model->routed['controller'];
return new $controllerName();
}
$controllerClass = Controller::generateClassPath($this->model->getShortName());
return new $controllerClass();
}
protected function getAction($controller, $impliedActions)
{
if (is_string($impliedActions)) {
$impliedActions = array($impliedActions);
}
if (array_key_exists("action", $this->model->routed)) {
$impliedActions[] = $this->model->routed['action'];
}
$impliedActions[] = "show";
$impliedActions[] = "noActionMatch";
foreach ($impliedActions as $method) {
$method = lcfirst(Inflector::camelize(str_replace("-", "_", $method)));
if (method_exists($controller, $method)) {
return $method;
}
}
return "";
}
protected function modelSupportsRewrites()
{
return is_array($this->model->routed) && array_key_exists("rewrite", $this->model->routed);
}
protected function extractDefaultLocaleInformation()
{
$defaultLocale = null;
if ($this->isLocalizedApp()) {
$defaultLocale = Strata::i18n()->getDefaultLocale();
}
if ($this->modelSupportsRewrites()) {
foreach ($this->model->routed['rewrite'] as $routeKey => $routeUrl) {
$this->queueRewrite($routeUrl, $this->defaultSlug, $defaultLocale);
}
}
}
protected function saveRewriteBatch()
{
foreach ($this->rewriteBatch as $queryVar => $routeConfig) {
if (count($routeConfig['locale_urls'])) {
$localeUrlsBit = sprintf("(%s)?/?", implode("|", $routeConfig["locale_urls"]));
} else {
$localeUrlsBit = "";
}
$rule = sprintf($this->getRewritePattern(),
$localeUrlsBit,
implode("|", $routeConfig["model_slugs"]),
implode("|", $routeConfig["localized_slugs"])
);
$redirect = $this->getRewriteDestination();
$this->addRewrite(array($rule, $redirect));
}
}
/**
* Generates a rule readable by the Strata router which
* will attempt to catch all the extra rewrites.
* @param string $routeKey
* @param string $slug
* @return array
*/
protected function createRouteFor($routeKey, $slug, $impliedActions = null)
{
$controller = $this->getController();
if (is_null($impliedActions)) {
$impliedActions = array($routeKey);
}
$action = $this->getAction($controller, $impliedActions);
return array(
'*',
'/' . $slug ."/[:slug]/[$routeKey:rewrite]/?",
$controller->getShortName() . "#" . $action
);
}
protected function queueRewrite($routeUrl, $slug, $locale = null)
{
$queryVar = $this->getRewriteIdentifier();
$localeUrl = null;
if (!is_null($locale) && $locale->hasACustomUrl()) {
$localeUrl = $locale->getUrl();
}
if (!array_key_exists($queryVar, $this->rewriteBatch)) {
$this->rewriteBatch[$queryVar] = array(
"model_slugs" => array(),
"locale_urls" => array(),
"localized_slugs" => array(),
);
}
if (!is_null($localeUrl) && !in_array($localeUrl, $this->rewriteBatch[$queryVar]["locale_urls"])) {
$this->rewriteBatch[$queryVar]["locale_urls"][] = $localeUrl;
}
if (!in_array($routeUrl, $this->rewriteBatch[$queryVar]["localized_slugs"])) {
$this->rewriteBatch[$queryVar]["localized_slugs"][] = $routeUrl;
}
if (!in_array($slug, $this->rewriteBatch[$queryVar]["model_slugs"])) {
$this->rewriteBatch[$queryVar]["model_slugs"][] = $slug;
}
}
}