array(), self::CTX_OTHER_PAGES => array(), ); private $title = array( self::MACRO_TEMPLATE_ID => 'Template ID', self::MACRO_CATEGORY => 'Category', self::MACRO_TYPE => 'Type', self::MACRO_AUTHOR => 'Author', self::MACRO_PRICE => 'Price', self::MACRO_PAGE_NUMBER => 'Page number', self::MACRO_PAGE_NAME => 'Page name', self::MACRO_PACKAGE => 'Package', ); private $macros = array( self::MACRO_TEMPLATE_ID => 'TEMPLATE-ID', self::MACRO_CATEGORY => 'CATEGORY', self::MACRO_TYPE => 'TYPE', self::MACRO_AUTHOR => 'AUTHOR', self::MACRO_PRICE => 'PRICE', self::MACRO_PAGE_NUMBER => 'PAGE-NUMBER', self::MACRO_PAGE_NAME => 'PAGE-NAME', self::MACRO_PACKAGE => 'PACKAGE', ); private $rule = array( self::MACRO_TEMPLATE_ID => '\d+', self::MACRO_CATEGORY => '[a-zA-Z\d\-]+', self::MACRO_TYPE => '[a-zA-Z\d\-]+', self::MACRO_AUTHOR => '[a-zA-Z\d\-]+', self::MACRO_PRICE => '\d+', self::MACRO_PAGE_NUMBER => '\d+', self::MACRO_PAGE_NAME => '[a-zA-Z\s\d\-]+', self::MACRO_PACKAGE => '[a-zA-Z\d\-]+', ); private $name; abstract function getRouteUriOrder($context); abstract function getUriPrefix(); function __construct() { $this->resetMatrix(); } function generateRouteString($pattern, $context) { $result = array(); $res_regexp = addcslashes($pattern, '.!$^*()?'); foreach ($this->getMacroIterator() as $key=>$macros) { $macro = "%{$macros}%"; $state = $this->getMacroState($key, $context); if ($state == self::STATE_REQUIRED) { $required_place[$key] = strpos($res_regexp, $macro); $res_regexp = str_replace($macro, "(".$this->rule[$key].")", $res_regexp); } elseif ($state == self::STATE_AVAILABLE) { $res_regexp = str_replace($macro, $this->rule[$key], $res_regexp); } } $res_uri = $this->generateRouteUri ($required_place, $context); $example = $this->substitute ($context, $pattern, $this->getExampleValues ()); return array ($res_regexp, $res_uri, $example); } private function generateRouteUri(array $required_place, $context) { $res = $this->getUriPrefix(); $order = $this->getRouteUriOrder($context); asort($required_place); foreach (array_keys($required_place) as $key) { $i = array_search($key, $order)+1; $res .= '/$'.$i; } return $res; } function markAsInapplicable ($macro, $context=self::CTX_ALL) { $this->setMacroState($macro, $context, self::STATE_INAPPLICABLE); } function markAsRequired ($macro, $context=self::CTX_ALL) { $this->setMacroState($macro, $context, self::STATE_REQUIRED); } function markAsAvailable ($macro, $context=self::CTX_ALL) { $this->setMacroState($macro, $context, self::STATE_AVAILABLE); } function setDefaultRoute ($context, $value) { $this->setMacroState(self::MACRO_DEFAULT, $context, $value); } function getDefaultRoute ($context) { return $this->getMacroState(self::MACRO_DEFAULT, $context); } function getIterator () { return new ArrayIterator($this->title); } function getMacroIterator () { return new ArrayIterator($this->macros); } function __toString () { ob_start(); foreach ($this->matrix as $context => $routes) { echo "

$context

"; foreach ($routes as $id => $state) { echo '

', $this->title[$id], ' = ', $state, '

'; } } return $message = ob_get_clean();; } private function resetMatrix () { foreach ($this as $id => $title) { $this->markAsInapplicable($id); } } function getMacroState ($macro, $context) { return $this->matrix[$context][$macro]; } private function setMacroState ($macro, $context, $state) { if ($context & self::CTX_FIRST_PAGE) { $this->matrix[self::CTX_FIRST_PAGE][$macro] = $state; } if ($context & self::CTX_OTHER_PAGES) { $this->matrix[self::CTX_OTHER_PAGES][$macro] = $state; } } function setName($name) { $this->name = $name; } function getName() { return $this->name; } function substitute($context, $pattern, array $values) { $result = $pattern; foreach ($this->getMacroIterator() as $key=>$macros) { $state = $this->getMacroState($key, $context); if (in_array($state, array(self::STATE_AVAILABLE, self::STATE_REQUIRED))) { $result = str_replace("%{$macros}%", $values[$key], $result); } } return $result; } function getExampleValues() { $values = array( self::MACRO_TEMPLATE_ID => '17955', self::MACRO_CATEGORY => 'family', self::MACRO_TYPE => 'joomla', self::MACRO_AUTHOR => 'hugo', self::MACRO_PRICE => '48', self::MACRO_PAGE_NUMBER => '6', self::MACRO_PAGE_NAME => 'Homepage', self::MACRO_PACKAGE => 'joomla-1-6-templates', ); return $values; } function getMacroNameByIndex ($index) { return $this->macros[$index]; } }