diff -r 56befcb22751 -r 94a1dc255022 thd/cache/frontend/prod/config/config_core_compile.yml.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thd/cache/frontend/prod/config/config_core_compile.yml.php Tue Sep 22 16:40:38 2009 +0200 @@ -0,0 +1,4062 @@ +overriden[$class] = $path; + $this->classes[$class] = $path; + } + public function getClassPath($class) + { + return isset($this->classes[$class]) ? $this->classes[$class] : null; + } + public function reloadClasses($force = false) + { + if (self::$freshCache) + { + return; + } + $configuration = sfProjectConfiguration::getActive(); + if (!$configuration || !$configuration instanceof sfApplicationConfiguration) + { + return; + } + self::$freshCache = true; + if (file_exists($configuration->getConfigCache()->getCacheName('config/autoload.yml'))) + { + self::$freshCache = false; + if ($force) + { + unlink($configuration->getConfigCache()->getCacheName('config/autoload.yml')); + } + } + $file = $configuration->getConfigCache()->checkConfig('config/autoload.yml'); + $this->classes = include($file); + foreach ($this->overriden as $class => $path) + { + $this->classes[$class] = $path; + } + } + public function autoload($class) + { + if (!$this->classes) + { + self::reloadClasses(); + } + return self::loadClass($class); + } + public function autoloadAgain($class) + { + self::reloadClasses(true); + return self::loadClass($class); + } + public function loadClass($class) + { + if (class_exists($class, false) || interface_exists($class, false)) + { + return true; + } + if (isset($this->classes[$class])) + { + require($this->classes[$class]); + return true; + } + if (sfContext::hasInstance() && ($module = sfContext::getInstance()->getModuleName()) && isset($this->classes[$module.'/'.$class])) + { + require($this->classes[$module.'/'.$class]); + return true; + } + return false; + } +} + + +abstract class sfComponent +{ + protected + $moduleName = '', + $actionName = '', + $context = null, + $dispatcher = null, + $request = null, + $response = null, + $varHolder = null, + $requestParameterHolder = null; + public function __construct($context, $moduleName, $actionName) + { + $this->initialize($context, $moduleName, $actionName); + } + public function initialize($context, $moduleName, $actionName) + { + $this->moduleName = $moduleName; + $this->actionName = $actionName; + $this->context = $context; + $this->dispatcher = $context->getEventDispatcher(); + $this->varHolder = new sfParameterHolder(); + $this->request = $context->getRequest(); + $this->response = $context->getResponse(); + $this->requestParameterHolder = $this->request->getParameterHolder(); + } + abstract function execute($request); + public function getModuleName() + { + return $this->moduleName; + } + public function getActionName() + { + return $this->actionName; + } + public final function getContext() + { + return $this->context; + } + public final function getLogger() + { + return $this->context->getLogger(); + } + public function logMessage($message, $priority = 'info') + { + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array($message, 'priority' => constant('sfLogger::'.strtoupper($priority))))); + } + } + public function debugMessage($message) + { + if (sfConfig::get('sf_web_debug') && sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent(null, 'application.log', array('This feature is deprecated in favor of the log_message helper.', 'priority' => sfLogger::ERR))); + } + } + public function getRequestParameter($name, $default = null) + { + return $this->requestParameterHolder->get($name, $default); + } + public function hasRequestParameter($name) + { + return $this->requestParameterHolder->has($name); + } + public function getRequest() + { + return $this->request; + } + public function getResponse() + { + return $this->response; + } + public function getController() + { + return $this->context->getController(); + } + public function generateUrl($route, $params = array(), $absolute = false) + { + return $this->context->getRouting()->generate($route, $params, $absolute); + } + public function getUser() + { + return $this->context->getUser(); + } + public function setVar($name, $value, $safe = false) + { + $this->varHolder->set($name, $safe ? new sfOutputEscaperSafe($value) : $value); + } + public function getVar($name) + { + return $this->varHolder->get($name); + } + public function getVarHolder() + { + return $this->varHolder; + } + public function __set($key, $value) + { + return $this->varHolder->setByRef($key, $value); + } + public function & __get($key) + { + return $this->varHolder->get($key); + } + public function __isset($name) + { + return $this->varHolder->has($name); + } + public function __unset($name) + { + $this->varHolder->remove($name); + } + public function __call($method, $arguments) + { + $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'component.method_not_found', array('method' => $method, 'arguments' => $arguments))); + if (!$event->isProcessed()) + { + throw new sfException(sprintf('Call to undefined method %s::%s.', get_class($this), $method)); + } + return $event->getReturnValue(); + } +} + + +abstract class sfAction extends sfComponent +{ + protected + $security = array(); + public function initialize($context, $moduleName, $actionName) + { + parent::initialize($context, $moduleName, $actionName); + if ($file = $context->getConfigCache()->checkConfig('modules/'.$this->getModuleName().'/config/security.yml', true)) + { + require($file); + } + } + public function preExecute() + { + } + public function postExecute() + { + } + public function forward404($message = null) + { + throw new sfError404Exception($this->get404Message($message)); + } + public function forward404Unless($condition, $message = null) + { + if (!$condition) + { + throw new sfError404Exception($this->get404Message($message)); + } + } + public function forward404If($condition, $message = null) + { + if ($condition) + { + throw new sfError404Exception($this->get404Message($message)); + } + } + public function redirect404() + { + return $this->redirect('/'.sfConfig::get('sf_error_404_module').'/'.sfConfig::get('sf_error_404_action')); + } + public function forward($module, $action) + { + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Forward to action "%s/%s"', $module, $action)))); + } + $this->getController()->forward($module, $action); + throw new sfStopException(); + } + public function forwardIf($condition, $module, $action) + { + if ($condition) + { + $this->forward($module, $action); + } + } + public function forwardUnless($condition, $module, $action) + { + if (!$condition) + { + $this->forward($module, $action); + } + } + public function redirect($url, $statusCode = 302) + { + $this->getController()->redirect($url, 0, $statusCode); + throw new sfStopException(); + } + public function redirectIf($condition, $url, $statusCode = 302) + { + if ($condition) + { + $this->redirect($url, $statusCode); + } + } + public function redirectUnless($condition, $url, $statusCode = 302) + { + if (!$condition) + { + $this->redirect($url, $statusCode); + } + } + public function renderText($text) + { + $this->getResponse()->setContent($this->getResponse()->getContent().$text); + return sfView::NONE; + } + public function getPartial($templateName, $vars = null) + { + $this->getContext()->getConfiguration()->loadHelpers('Partial'); + $vars = !is_null($vars) ? $vars : $this->varHolder->getAll(); + return get_partial($templateName, $vars); + } + public function renderPartial($templateName, $vars = null) + { + return $this->renderText($this->getPartial($templateName, $vars)); + } + public function getComponent($moduleName, $componentName, $vars = null) + { + $this->getContext()->getConfiguration()->loadHelpers('Partial'); + $vars = !is_null($vars) ? $vars : $this->varHolder->getAll(); + return get_component($moduleName, $componentName, $vars); + } + public function renderComponent($moduleName, $componentName, $vars = null) + { + return $this->renderText($this->getComponent($moduleName, $componentName, $vars)); + } + public function getDefaultView() + { + if (!sfConfig::get('sf_compat_10')) + { + throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); + } + return sfView::INPUT; + } + public function handleError() + { + if (!sfConfig::get('sf_compat_10')) + { + throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); + } + return sfView::ERROR; + } + public function validate() + { + if (!sfConfig::get('sf_compat_10')) + { + throw new sfConfigurationException('You must set "compat_10" to true if you want to use this method which is deprecated.'); + } + return true; + } + public function getSecurityConfiguration() + { + return $this->security; + } + public function setSecurityConfiguration($security) + { + $this->security = $security; + } + public function isSecure() + { + $actionName = strtolower($this->getActionName()); + if (isset($this->security[$actionName]['is_secure'])) + { + return $this->security[$actionName]['is_secure']; + } + if (isset($this->security['all']['is_secure'])) + { + return $this->security['all']['is_secure']; + } + return false; + } + public function getCredential() + { + $actionName = strtolower($this->getActionName()); + if (isset($this->security[$actionName]['credentials'])) + { + $credentials = $this->security[$actionName]['credentials']; + } + else if (isset($this->security['all']['credentials'])) + { + $credentials = $this->security['all']['credentials']; + } + else + { + $credentials = null; + } + return $credentials; + } + public function setTemplate($name, $module = null) + { + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Change template to "%s/%s"', is_null($module) ? 'CURRENT' : $module, $name)))); + } + if (!is_null($module)) + { + $name = sfConfig::get('sf_app_dir').'/modules/'.$module.'/templates/'.$name; + } + sfConfig::set('symfony.view.'.$this->getModuleName().'_'.$this->getActionName().'_template', $name); + } + public function getTemplate() + { + return sfConfig::get('symfony.view.'.$this->getModuleName().'_'.$this->getActionName().'_template'); + } + public function setLayout($name) + { + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Change layout to "%s"', $name)))); + } + sfConfig::set('symfony.view.'.$this->getModuleName().'_'.$this->getActionName().'_layout', $name); + } + public function getLayout() + { + return sfConfig::get('symfony.view.'.$this->getModuleName().'_'.$this->getActionName().'_layout'); + } + public function setViewClass($class) + { + sfConfig::set('mod_'.strtolower($this->getModuleName()).'_view_class', $class); + } + public function getRoute() + { + return $this->getRequest()->getAttribute('sf_route'); + } + protected function get404Message($message = null) + { + return is_null($message) ? sprintf('This request has been forwarded to a 404 error page by the action "%s/%s".', $this->getModuleName(), $this->getActionName()) : $message; + } +} + + +abstract class sfActions extends sfAction +{ + public function execute($request) + { + $actionToRun = 'execute'.ucfirst($this->getActionName()); + if ($actionToRun === 'execute') + { + throw new sfInitializationException(sprintf('sfAction initialization failed for module "%s". There was no action given.', $this->getModuleName())); + } + if (!is_callable(array($this, $actionToRun))) + { + throw new sfInitializationException(sprintf('sfAction initialization failed for module "%s", action "%s". You must create a "%s" method.', $this->getModuleName(), $this->getActionName(), $actionToRun)); + } + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Call "%s->%s()"', get_class($this), $actionToRun)))); + } + return $this->$actionToRun($request); + } +} + + +class sfActionStack +{ + protected + $stack = array(); + public function addEntry($moduleName, $actionName, $actionInstance) + { + $actionEntry = new sfActionStackEntry($moduleName, $actionName, $actionInstance); + $this->stack[] = $actionEntry; + return $actionEntry; + } + public function getEntry($index) + { + $retval = null; + if ($index > -1 && $index < count($this->stack)) + { + $retval = $this->stack[$index]; + } + return $retval; + } + public function popEntry() + { + return array_pop($this->stack); + } + public function getFirstEntry() + { + $retval = null; + if (isset($this->stack[0])) + { + $retval = $this->stack[0]; + } + return $retval; + } + public function getLastEntry() + { + $count = count($this->stack); + $retval = null; + if (isset($this->stack[0])) + { + $retval = $this->stack[$count - 1]; + } + return $retval; + } + public function getSize() + { + return count($this->stack); + } +} + + +class sfActionStackEntry +{ + protected + $actionInstance = null, + $actionName = null, + $moduleName = null, + $presentation = null; + public function __construct($moduleName, $actionName, $actionInstance) + { + $this->actionName = $actionName; + $this->actionInstance = $actionInstance; + $this->moduleName = $moduleName; + } + public function getActionName() + { + return $this->actionName; + } + public function getActionInstance() + { + return $this->actionInstance; + } + public function getModuleName() + { + return $this->moduleName; + } + public function & getPresentation() + { + return $this->presentation; + } + public function setPresentation(&$presentation) + { + $this->presentation =& $presentation; + } +} + + +class sfLoader +{ + static public function getHelperDirs($moduleName = '') + { + $configuration = sfProjectConfiguration::getActive(); + $configuration->getEventDispatcher()->notify(new sfEvent(null, 'application.log', array('The sfLoader::getHelperDirs() method is deprecated. Please use the same method from sfApplicationConfiguration.', 'priority' => sfLogger::ERR))); + return $configuration->getHelperDirs($moduleName); + } + static public function loadHelpers($helpers, $moduleName = '') + { + $configuration = sfProjectConfiguration::getActive(); + $configuration->getEventDispatcher()->notify(new sfEvent(null, 'application.log', array('The sfLoader::loadHelpers() method is deprecated. Please use the same method from sfApplicationConfiguration.', 'priority' => sfLogger::ERR))); + return $configuration->loadHelpers($helpers, $moduleName); + } +} + + +abstract class sfController +{ + protected + $context = null, + $dispatcher = null, + $controllerClasses = array(), + $maxForwards = 5, + $renderMode = sfView::RENDER_CLIENT; + public function __construct($context) + { + $this->initialize($context); + } + public function initialize($context) + { + $this->context = $context; + $this->dispatcher = $context->getEventDispatcher(); + $this->maxForwards = sfConfig::get('sf_max_forwards', $this->maxForwards); + } + public function componentExists($moduleName, $componentName) + { + return $this->controllerExists($moduleName, $componentName, 'component', false); + } + public function actionExists($moduleName, $actionName) + { + return $this->controllerExists($moduleName, $actionName, 'action', false); + } + protected function controllerExists($moduleName, $controllerName, $extension, $throwExceptions) + { + $dirs = $this->context->getConfiguration()->getControllerDirs($moduleName); + foreach ($dirs as $dir => $checkEnabled) + { + if ($checkEnabled && !in_array($moduleName, sfConfig::get('sf_enabled_modules')) && is_readable($dir)) + { + throw new sfConfigurationException(sprintf('The module "%s" is not enabled.', $moduleName)); + } + $classFile = strtolower($extension); + $classSuffix = ucfirst(strtolower($extension)); + $file = $dir.'/'.$controllerName.$classSuffix.'.class.php'; + if (is_readable($file)) + { + require_once($file); + $this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix] = $controllerName.$classSuffix; + return true; + } + $module_file = $dir.'/'.$classFile.'s.class.php'; + if (is_readable($module_file)) + { + require_once($module_file); + if (!class_exists($moduleName.$classSuffix.'s', false)) + { + if ($throwExceptions) + { + throw new sfControllerException(sprintf('There is no "%s" class in your action file "%s".', $moduleName.$classSuffix.'s', $module_file)); + } + return false; + } + if (!in_array('execute'.ucfirst($controllerName), get_class_methods($moduleName.$classSuffix.'s'))) + { + if ($throwExceptions) + { + throw new sfControllerException(sprintf('There is no "%s" method in your action class "%s".', 'execute'.ucfirst($controllerName), $moduleName.$classSuffix.'s')); + } + return false; + } + $this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix] = $moduleName.$classSuffix.'s'; + return true; + } + } + if ($throwExceptions && sfConfig::get('sf_debug')) + { + $dirs = array_keys($dirs); + foreach ($dirs as &$dir) + { + $dir = str_replace(sfConfig::get('sf_root_dir'), '%SF_ROOT_DIR%', $dir); + } + throw new sfControllerException(sprintf('Controller "%s/%s" does not exist in: %s.', $moduleName, $controllerName, implode(', ', $dirs))); + } + return false; + } + public function forward($moduleName, $actionName) + { + $moduleName = preg_replace('/[^a-z0-9_]+/i', '', $moduleName); + $actionName = preg_replace('/[^a-z0-9_]+/i', '', $actionName); + if ($this->getActionStack()->getSize() >= $this->maxForwards) + { + throw new sfForwardException(sprintf('Too many forwards have been detected for this request (> %d).', $this->maxForwards)); + } + $this->context->getConfigCache()->import('modules/'.$moduleName.'/config/generator.yml', false, true); + if (!$this->actionExists($moduleName, $actionName)) + { + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Action "%s/%s" does not exist', $moduleName, $actionName)))); + } + throw new sfError404Exception(sprintf('Action "%s/%s" does not exist.', $moduleName, $actionName)); + } + $actionInstance = $this->getAction($moduleName, $actionName); + $this->getActionStack()->addEntry($moduleName, $actionName, $actionInstance); + require($this->context->getConfigCache()->checkConfig('modules/'.$moduleName.'/config/module.yml')); + if ($this->getActionStack()->getSize() == 1 && sfConfig::get('mod_'.strtolower($moduleName).'_is_internal') && !sfConfig::get('sf_test')) + { + throw new sfConfigurationException(sprintf('Action "%s" from module "%s" cannot be called directly.', $actionName, $moduleName)); + } + if (sfConfig::get('mod_'.strtolower($moduleName).'_enabled')) + { + $moduleConfig = sfConfig::get('sf_app_module_dir').'/'.$moduleName.'/config/config.php'; + if (is_readable($moduleConfig)) + { + require_once($moduleConfig); + } + $filterChain = new sfFilterChain(); + $filterChain->loadConfiguration($actionInstance); + $this->context->getEventDispatcher()->notify(new sfEvent($this, 'controller.change_action', array('module' => $moduleName, 'action' => $actionName))); + if ($moduleName == sfConfig::get('sf_error_404_module') && $actionName == sfConfig::get('sf_error_404_action')) + { + $this->context->getResponse()->setStatusCode(404); + $this->context->getResponse()->setHttpHeader('Status', '404 Not Found'); + $this->dispatcher->notify(new sfEvent($this, 'controller.page_not_found', array('module' => $moduleName, 'action' => $actionName))); + } + $filterChain->execute(); + } + else + { + $moduleName = sfConfig::get('sf_module_disabled_module'); + $actionName = sfConfig::get('sf_module_disabled_action'); + if (!$this->actionExists($moduleName, $actionName)) + { + throw new sfConfigurationException(sprintf('Invalid configuration settings: [sf_module_disabled_module] "%s", [sf_module_disabled_action] "%s".', $moduleName, $actionName)); + } + $this->forward($moduleName, $actionName); + } + } + public function getAction($moduleName, $actionName) + { + return $this->getController($moduleName, $actionName, 'action'); + } + public function getComponent($moduleName, $componentName) + { + return $this->getController($moduleName, $componentName, 'component'); + } + protected function getController($moduleName, $controllerName, $extension) + { + $classSuffix = ucfirst(strtolower($extension)); + if (!isset($this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix])) + { + $this->controllerExists($moduleName, $controllerName, $extension, true); + } + $class = $this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix]; + $moduleClass = $moduleName.'_'.$class; + if (class_exists($moduleClass, false)) + { + $class = $moduleClass; + } + return new $class($this->context, $moduleName, $controllerName); + } + public function getActionStack() + { + return $this->context->getActionStack(); + } + public function getRenderMode() + { + return $this->renderMode; + } + public function getView($moduleName, $actionName, $viewName) + { + $file = sfConfig::get('sf_app_module_dir').'/'.$moduleName.'/view/'.$actionName.$viewName.'View.class.php'; + if (is_readable($file)) + { + require_once($file); + $class = $actionName.$viewName.'View'; + $moduleClass = $moduleName.'_'.$class; + if (class_exists($moduleClass, false)) + { + $class = $moduleClass; + } + } + else + { + $class = sfConfig::get('mod_'.strtolower($moduleName).'_view_class', 'sfPHP').'View'; + } + return new $class($this->context, $moduleName, $actionName, $viewName); + } + public function sendEmail($module, $action) + { + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array('sendEmail method is deprecated', 'priority' => sfLogger::ERR))); + } + return $this->getPresentationFor($module, $action, 'sfMail'); + } + public function getPresentationFor($module, $action, $viewName = null) + { + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Get presentation for action "%s/%s" (view class: "%s")', $module, $action, $viewName)))); + } + $renderMode = $this->getRenderMode(); + $this->setRenderMode(sfView::RENDER_VAR); + $actionStack = $this->getActionStack(); + $index = $actionStack->getSize(); + if ($viewName) + { + $currentViewName = sfConfig::get('mod_'.strtolower($module).'_view_class'); + sfConfig::set('mod_'.strtolower($module).'_view_class', $viewName); + } + try + { + $this->forward($module, $action); + } + catch (Exception $e) + { + $this->setRenderMode($renderMode); + if ($viewName) + { + sfConfig::set('mod_'.strtolower($module).'_view_class', $currentViewName); + } + throw $e; + } + $actionEntry = $actionStack->getEntry($index); + $presentation =& $actionEntry->getPresentation(); + $this->setRenderMode($renderMode); + $nb = $actionStack->getSize() - $index; + while ($nb-- > 0) + { + $actionEntry = $actionStack->popEntry(); + if ($actionEntry->getModuleName() == sfConfig::get('sf_login_module') && $actionEntry->getActionName() == sfConfig::get('sf_login_action')) + { + throw new sfException('Your action is secured, but the user is not authenticated.'); + } + else if ($actionEntry->getModuleName() == sfConfig::get('sf_secure_module') && $actionEntry->getActionName() == sfConfig::get('sf_secure_action')) + { + throw new sfException('Your action is secured, but the user does not have access.'); + } + } + if ($viewName) + { + sfConfig::set('mod_'.strtolower($module).'_view_class', $currentViewName); + } + return $presentation; + } + public function setRenderMode($mode) + { + if ($mode == sfView::RENDER_CLIENT || $mode == sfView::RENDER_VAR || $mode == sfView::RENDER_NONE) + { + $this->renderMode = $mode; + return; + } + throw new sfRenderException(sprintf('Invalid rendering mode: %s.', $mode)); + } + public function inCLI() + { + return 0 == strncasecmp(PHP_SAPI, 'cli', 3); + } + public function __call($method, $arguments) + { + $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'controller.method_not_found', array('method' => $method, 'arguments' => $arguments))); + if (!$event->isProcessed()) + { + throw new sfException(sprintf('Call to undefined method %s::%s.', get_class($this), $method)); + } + return $event->getReturnValue(); + } +} + + +class sfDatabaseManager +{ + protected + $configuration = null, + $databases = array(); + public function __construct(sfProjectConfiguration $configuration, $options = array()) + { + $this->initialize($configuration); + if (!isset($options['auto_shutdown']) || $options['auto_shutdown']) + { + register_shutdown_function(array($this, 'shutdown')); + } + } + public function initialize(sfProjectConfiguration $configuration) + { + $this->configuration = $configuration; + $this->loadConfiguration(); + } + public function loadConfiguration() + { + if ($this->configuration instanceof sfApplicationConfiguration) + { + $databases = include($this->configuration->getConfigCache()->checkConfig('config/databases.yml')); + } + else + { + $configHandler = new sfDatabaseConfigHandler(); + $databases = $configHandler->evaluate(array($this->configuration->getRootDir().'/config/databases.yml')); + } + foreach ($databases as $name => $database) + { + $this->setDatabase($name, $database); + } + } + public function setDatabase($name, sfDatabase $database) + { + $this->databases[$name] = $database; + } + public function getDatabase($name = 'default') + { + if (isset($this->databases[$name])) + { + return $this->databases[$name]; + } + throw new sfDatabaseException(sprintf('Database "%s" does not exist.', $name)); + } + public function getNames() + { + return array_keys($this->databases); + } + public function shutdown() + { + foreach ($this->databases as $database) + { + $database->shutdown(); + } + } +} + + +class sfEvent implements ArrayAccess +{ + protected + $value = null, + $processed = false, + $subject = null, + $name = '', + $parameters = null; + public function __construct($subject, $name, $parameters = array()) + { + $this->subject = $subject; + $this->name = $name; + $this->parameters = $parameters; + } + public function getSubject() + { + return $this->subject; + } + public function getName() + { + return $this->name; + } + public function setReturnValue($value) + { + $this->value = $value; + } + public function getReturnValue() + { + return $this->value; + } + public function setProcessed($processed) + { + $this->processed = (boolean) $processed; + } + public function isProcessed() + { + return $this->processed; + } + public function getParameters() + { + return $this->parameters; + } + public function offsetExists($name) + { + return array_key_exists($name, $this->parameters); + } + public function offsetGet($name) + { + if (!array_key_exists($name, $this->parameters)) + { + throw new InvalidArgumentException(sprintf('The event "%s" has no "%s" parameter.', $this->name, $name)); + } + return $this->parameters[$name]; + } + public function offsetSet($name, $value) + { + $this->parameters[$name] = $value; + } + public function offsetUnset($name) + { + unset($this->parameters[$name]); + } +} + + +abstract class sfFilter +{ + protected + $parameterHolder = null, + $context = null; + public static + $filterCalled = array(); + public function __construct($context, $parameters = array()) + { + $this->initialize($context, $parameters); + } + public function initialize($context, $parameters = array()) + { + $this->context = $context; + $this->parameterHolder = new sfParameterHolder(); + $this->parameterHolder->add($parameters); + return true; + } + protected function isFirstCall() + { + $class = get_class($this); + if (isset(self::$filterCalled[$class])) + { + return false; + } + else + { + self::$filterCalled[$class] = true; + return true; + } + } + public final function getContext() + { + return $this->context; + } + public function getParameterHolder() + { + return $this->parameterHolder; + } + public function getParameter($name, $default = null) + { + return $this->parameterHolder->get($name, $default); + } + public function hasParameter($name) + { + return $this->parameterHolder->has($name); + } + public function setParameter($name, $value) + { + return $this->parameterHolder->set($name, $value); + } +} + + +class sfCommonFilter extends sfFilter +{ + public function execute($filterChain) + { + $filterChain->execute(); + $response = $this->context->getResponse(); + $content = $response->getContent(); + if (false !== ($pos = strpos($content, ''))) + { + $this->context->getConfiguration()->loadHelpers(array('Tag', 'Asset')); + $html = ''; + if (!sfConfig::get('symfony.asset.javascripts_included', false)) + { + $html .= get_javascripts($response); + } + if (!sfConfig::get('symfony.asset.stylesheets_included', false)) + { + $html .= get_stylesheets($response); + } + if ($html) + { + $response->setContent(substr($content, 0, $pos).$html.substr($content, $pos)); + } + } + sfConfig::set('symfony.asset.javascripts_included', false); + sfConfig::set('symfony.asset.stylesheets_included', false); + } +} + + +class sfExecutionFilter extends sfFilter +{ + public function execute($filterChain) + { + $actionInstance = $this->context->getController()->getActionStack()->getLastEntry()->getActionInstance(); + if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled')) + { + $timer = sfTimerManager::getTimer(sprintf('Action "%s/%s"', $actionInstance->getModuleName(), $actionInstance->getActionName())); + $viewName = $this->handleAction($filterChain, $actionInstance); + $timer->addTime(); + $timer = sfTimerManager::getTimer(sprintf('View "%s" for "%s/%s"', $viewName, $actionInstance->getModuleName(), $actionInstance->getActionName())); + $this->handleView($filterChain, $actionInstance, $viewName); + $timer->addTime(); + } + else + { + $viewName = $this->handleAction($filterChain, $actionInstance); + $this->handleView($filterChain, $actionInstance, $viewName); + } + } + protected function handleAction($filterChain, $actionInstance) + { + $uri = $this->context->getRouting()->getCurrentInternalUri(); + if (sfConfig::get('sf_cache') && !is_null($uri) && $this->context->getViewCacheManager()->hasActionCache($uri)) + { + return sfView::SUCCESS; + } + return $this->executeAction($actionInstance); + } + protected function executeAction($actionInstance) + { + $actionInstance->preExecute(); + $viewName = $actionInstance->execute($this->context->getRequest()); + $actionInstance->postExecute(); + return is_null($viewName) ? sfView::SUCCESS : $viewName; + } + protected function handleView($filterChain, $actionInstance, $viewName) + { + switch ($viewName) + { + case sfView::HEADER_ONLY: + $this->context->getResponse()->setHeaderOnly(true); + return; + case sfView::NONE: + return; + } + $this->executeView($actionInstance->getModuleName(), $actionInstance->getActionName(), $viewName, $actionInstance->getVarHolder()->getAll()); + } + protected function executeView($moduleName, $actionName, $viewName, $viewAttributes) + { + $controller = $this->context->getController(); + $view = $controller->getView($moduleName, $actionName, $viewName); + $view->execute(); + $view->getAttributeHolder()->add($viewAttributes); + switch ($controller->getRenderMode()) + { + case sfView::RENDER_NONE: + break; + case sfView::RENDER_CLIENT: + $viewData = $view->render(); + $this->context->getResponse()->setContent($viewData); + break; + case sfView::RENDER_VAR: + $viewData = $view->render(); + $controller->getActionStack()->getLastEntry()->setPresentation($viewData); + break; + } + } +} + + +class sfRenderingFilter extends sfFilter +{ + public function execute($filterChain) + { + $filterChain->execute(); + $response = $this->context->getResponse(); + if (sfForm::hasToStringException()) + { + throw sfForm::getToStringException(); + } + else if (sfFormField::hasToStringException()) + { + throw sfFormField::getToStringException(); + } + $response->send(); + } +} + + +class sfFilterChain +{ + protected + $chain = array(), + $index = -1; + public function loadConfiguration($actionInstance) + { + require(sfContext::getInstance()->getConfigCache()->checkConfig('modules/'.$actionInstance->getModuleName().'/config/filters.yml')); + } + public function execute() + { + ++$this->index; + if ($this->index < count($this->chain)) + { + if (sfConfig::get('sf_logging_enabled')) + { + sfContext::getInstance()->getEventDispatcher()->notify(new sfEvent($this, 'application.log', array(sprintf('Executing filter "%s"', get_class($this->chain[$this->index]))))); + } + $this->chain[$this->index]->execute($this); + } + } + public function hasFilter($class) + { + foreach ($this->chain as $filter) + { + if ($filter instanceof $class) + { + return true; + } + } + return false; + } + public function register($filter) + { + $this->chain[] = $filter; + } +} + + +abstract class sfLogger +{ + const EMERG = 0; const ALERT = 1; const CRIT = 2; const ERR = 3; const WARNING = 4; const NOTICE = 5; const INFO = 6; const DEBUG = 7; + protected + $level = self::INFO; + public function __construct(sfEventDispatcher $dispatcher, $options = array()) + { + $this->initialize($dispatcher, $options); + if (!isset($options['auto_shutdown']) || $options['auto_shutdown']) + { + register_shutdown_function(array($this, 'shutdown')); + } + } + public function initialize(sfEventDispatcher $dispatcher, $options = array()) + { + if (isset($options['level'])) + { + $this->setLogLevel($options['level']); + } + $dispatcher->connect('application.log', array($this, 'listenToLogEvent')); + } + public function getLogLevel() + { + return $this->level; + } + public function setLogLevel($level) + { + if (!is_int($level)) + { + $level = constant('sfLogger::'.strtoupper($level)); + } + $this->level = $level; + } + public function log($message, $priority = self::INFO) + { + if ($this->getLogLevel() < $priority) + { + return false; + } + return $this->doLog($message, $priority); + } + abstract protected function doLog($message, $priority); + public function emerg($message) + { + $this->log($message, self::EMERG); + } + public function alert($message) + { + $this->log($message, self::ALERT); + } + public function crit($message) + { + $this->log($message, self::CRIT); + } + public function err($message) + { + $this->log($message, self::ERR); + } + public function warning($message) + { + $this->log($message, self::WARNING); + } + public function notice($message) + { + $this->log($message, self::NOTICE); + } + public function info($message) + { + $this->log($message, self::INFO); + } + public function debug($message) + { + $this->log($message, self::DEBUG); + } + public function listenToLogEvent(sfEvent $event) + { + $priority = isset($event['priority']) ? $event['priority'] : self::INFO; + $subject = $event->getSubject(); + $subject = is_object($subject) ? get_class($subject) : (is_string($subject) ? $subject : 'main'); + foreach ($event->getParameters() as $key => $message) + { + if ('priority' === $key) + { + continue; + } + $this->log(sprintf('{%s} %s', $subject, $message), $priority); + } + } + public function shutdown() + { + } + static public function getPriorityName($priority) + { + static $levels = array( + self::EMERG => 'emerg', + self::ALERT => 'alert', + self::CRIT => 'crit', + self::ERR => 'err', + self::WARNING => 'warning', + self::NOTICE => 'notice', + self::INFO => 'info', + self::DEBUG => 'debug', + ); + if (!isset($levels[$priority])) + { + throw new sfException(sprintf('The priority level "%s" does not exist.', $priority)); + } + return $levels[$priority]; + } +} + + +class sfNoLogger extends sfLogger +{ + public function initialize(sfEventDispatcher $dispatcher, $options = array()) + { + } + protected function doLog($message, $priority) + { + } +} + + +abstract class sfRequest +{ + const GET = 'GET'; + const POST = 'POST'; + const PUT = 'PUT'; + const DELETE = 'DELETE'; + const HEAD = 'HEAD'; + protected + $dispatcher = null, + $method = null, + $options = array(), + $parameterHolder = null, + $attributeHolder = null; + public function __construct(sfEventDispatcher $dispatcher, $parameters = array(), $attributes = array(), $options = array()) + { + $this->initialize($dispatcher, $parameters, $attributes, $options); + } + public function initialize(sfEventDispatcher $dispatcher, $parameters = array(), $attributes = array(), $options = array()) + { + $this->dispatcher = $dispatcher; + $this->options = $options; + if (!isset($this->options['logging'])) + { + $this->options['logging'] = false; + } + $this->parameterHolder = new sfParameterHolder(); + $this->attributeHolder = new sfParameterHolder(); + $this->parameterHolder->add($parameters); + $this->attributeHolder->add($attributes); + } + public function extractParameters($names) + { + $array = array(); + $parameters = $this->parameterHolder->getAll(); + foreach ($parameters as $key => $value) + { + if (in_array($key, $names)) + { + $array[$key] = $value; + } + } + return $array; + } + public function getMethod() + { + return $this->method; + } + public function setMethod($method) + { + if (!in_array(strtoupper($method), array(self::GET, self::POST, self::PUT, self::DELETE, self::HEAD))) + { + throw new sfException(sprintf('Invalid request method: %s.', $method)); + } + $this->method = strtoupper($method); + } + public function getParameterHolder() + { + return $this->parameterHolder; + } + public function getAttributeHolder() + { + return $this->attributeHolder; + } + public function getAttribute($name, $default = null) + { + return $this->attributeHolder->get($name, $default); + } + public function hasAttribute($name) + { + return $this->attributeHolder->has($name); + } + public function setAttribute($name, $value) + { + $this->attributeHolder->set($name, $value); + } + public function getParameter($name, $default = null) + { + return $this->parameterHolder->get($name, $default); + } + public function hasParameter($name) + { + return $this->parameterHolder->has($name); + } + public function setParameter($name, $value) + { + $this->parameterHolder->set($name, $value); + } + public function __call($method, $arguments) + { + $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'request.method_not_found', array('method' => $method, 'arguments' => $arguments))); + if (!$event->isProcessed()) + { + throw new sfException(sprintf('Call to undefined method %s::%s.', get_class($this), $method)); + } + return $event->getReturnValue(); + } + public function __clone() + { + $this->parameterHolder = clone $this->parameterHolder; + $this->attributeHolder = clone $this->attributeHolder; + } +} + + +abstract class sfResponse implements Serializable +{ + protected + $options = array(), + $dispatcher = null, + $content = ''; + public function __construct(sfEventDispatcher $dispatcher, $options = array()) + { + $this->initialize($dispatcher, $options); + } + public function initialize(sfEventDispatcher $dispatcher, $options = array()) + { + $this->dispatcher = $dispatcher; + $this->options = $options; + if (!isset($this->options['logging'])) + { + $this->options['logging'] = false; + } + } + public function setEventDispatcher(sfEventDispatcher $dispatcher) + { + $this->dispatcher = $dispatcher; + } + public function setContent($content) + { + $this->content = $content; + } + public function getContent() + { + return $this->content; + } + public function sendContent() + { + $event = $this->dispatcher->filter(new sfEvent($this, 'response.filter_content'), $this->getContent()); + $content = $event->getReturnValue(); + if ($this->options['logging']) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Send content (%s o)', strlen($content))))); + } + echo $content; + } + public function send() + { + $this->sendContent(); + } + public function getOptions() + { + return $this->options; + } + public function __call($method, $arguments) + { + $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'response.method_not_found', array('method' => $method, 'arguments' => $arguments))); + if (!$event->isProcessed()) + { + throw new sfException(sprintf('Call to undefined method %s::%s.', get_class($this), $method)); + } + return $event->getReturnValue(); + } + public function serialize() + { + return serialize($this->content); + } + public function unserialize($serialized) + { + $this->content = unserialize($serialized); + } +} + + +abstract class sfRouting +{ + protected + $dispatcher = null, + $cache = null, + $defaultParameters = array(), + $options = array(); + public function __construct(sfEventDispatcher $dispatcher, sfCache $cache = null, $options = array()) + { + $this->initialize($dispatcher, $cache, $options); + if (!isset($this->options['auto_shutdown']) || $this->options['auto_shutdown']) + { + register_shutdown_function(array($this, 'shutdown')); + } + } + public function getCache() + { + return $this->cache; + } + public function initialize(sfEventDispatcher $dispatcher, sfCache $cache = null, $options = array()) + { + $this->dispatcher = $dispatcher; + $options['debug'] = isset($options['debug']) ? (boolean) $options['debug'] : false; + $this->cache = $options['debug'] ? null : $cache; + $this->setDefaultParameter('module', isset($options['default_module']) ? $options['default_module'] : 'default'); + $this->setDefaultParameter('action', isset($options['default_action']) ? $options['default_action'] : 'index'); + if (!isset($options['logging'])) + { + $options['logging'] = false; + } + if (!isset($options['context'])) + { + $options['context'] = array(); + } + $this->options = $options; + $this->dispatcher->connect('user.change_culture', array($this, 'listenToChangeCultureEvent')); + $this->dispatcher->connect('request.filter_parameters', array($this, 'filterParametersEvent')); + $this->loadConfiguration(); + } + public function getOptions() + { + return $this->options; + } + public function loadConfiguration() + { + $this->dispatcher->notify(new sfEvent($this, 'routing.load_configuration')); + } + abstract public function getCurrentInternalUri($with_route_name = false); + abstract public function getRoutes(); + abstract public function setRoutes($routes); + abstract public function hasRoutes(); + abstract public function clearRoutes(); + abstract public function generate($name, $params = array(), $absolute = false); + abstract public function parse($url); + public function getDefaultParameters() + { + return $this->defaultParameters; + } + public function getDefaultParameter($key) + { + return isset($this->defaultParameters[$key]) ? $this->defaultParameters[$key] : null; + } + public function setDefaultParameter($key, $value) + { + $this->defaultParameters[$key] = $value; + } + public function setDefaultParameters($parameters) + { + $this->defaultParameters = $parameters; + } + protected function mergeArrays($arr1, $arr2) + { + foreach ($arr2 as $key => $value) + { + $arr1[$key] = $value; + } + return $arr1; + } + public function listenToChangeCultureEvent(sfEvent $event) + { + $this->setDefaultParameter('sf_culture', $event['culture']); + } + public function filterParametersEvent(sfEvent $event, $parameters) + { + $context = $event->getParameters(); + $this->options['context'] = $context; + if (false === $params = $this->parse($event['path_info'])) + { + return $parameters; + } + return array_merge($parameters, $params); + } + protected function fixGeneratedUrl($url, $absolute = false) + { + if (isset($this->options['context']['prefix'])) + { + if (0 === strpos($url, 'http')) + { + $url = preg_replace('#https?\://[^/]+#', '$0'.$this->options['context']['prefix'], $url); + } + else + { + $url = $this->options['context']['prefix'].$url; + } + } + if ($absolute && isset($this->options['context']['host']) && 0 !== strpos($url, 'http')) + { + $url = 'http'.(isset($this->options['context']['is_secure']) && $this->options['context']['is_secure'] ? 's' : '').'://'.$this->options['context']['host'].$url; + } + return $url; + } + public function shutdown() + { + } +} + + +abstract class sfStorage +{ + protected + $options = array(); + public function __construct($options = array()) + { + $this->initialize($options); + if ($this->options['auto_shutdown']) + { + register_shutdown_function(array($this, 'shutdown')); + } + } + public function initialize($options = array()) + { + $this->options = array_merge(array( + 'auto_shutdown' => true, + ), $options); + } + public function getOptions() + { + return $this->options; + } + abstract public function read($key); + abstract public function regenerate($destroy = false); + abstract public function remove($key); + abstract public function shutdown(); + abstract public function write($key, $data); +} + + +class sfUser +{ + const ATTRIBUTE_NAMESPACE = 'symfony/user/sfUser/attributes'; + const CULTURE_NAMESPACE = 'symfony/user/sfUser/culture'; + protected + $options = array(), + $attributeHolder = null, + $culture = null, + $storage = null, + $dispatcher = null; + public function __construct(sfEventDispatcher $dispatcher, sfStorage $storage, $options = array()) + { + $this->initialize($dispatcher, $storage, $options); + if ($this->options['auto_shutdown']) + { + register_shutdown_function(array($this, 'shutdown')); + } + } + public function initialize(sfEventDispatcher $dispatcher, sfStorage $storage, $options = array()) + { + $this->dispatcher = $dispatcher; + $this->storage = $storage; + $this->options = array_merge(array( + 'auto_shutdown' => true, + 'culture' => null, + 'default_culture' => 'en', + 'use_flash' => false, + 'logging' => false, + ), $options); + $this->attributeHolder = new sfNamespacedParameterHolder(self::ATTRIBUTE_NAMESPACE); + $attributes = $storage->read(self::ATTRIBUTE_NAMESPACE); + if (is_array($attributes)) + { + foreach ($attributes as $namespace => $values) + { + $this->attributeHolder->add($values, $namespace); + } + } + $currentCulture = $storage->read(self::CULTURE_NAMESPACE); + $this->setCulture(!is_null($this->options['culture']) ? $this->options['culture'] : (!is_null($currentCulture) ? $currentCulture : $this->options['default_culture'])); + if ($this->options['use_flash'] && $names = $this->attributeHolder->getNames('symfony/user/sfUser/flash')) + { + if ($this->options['logging']) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Flag old flash messages ("%s")', implode('", "', $names))))); + } + foreach ($names as $name) + { + $this->attributeHolder->set($name, true, 'symfony/user/sfUser/flash/remove'); + } + } + } + public function getOptions() + { + return $this->options; + } + public function setCulture($culture) + { + if ($this->culture != $culture) + { + $this->culture = $culture; + $this->dispatcher->notify(new sfEvent($this, 'user.change_culture', array('culture' => $culture))); + } + } + public function setFlash($name, $value, $persist = true) + { + if (!$this->options['use_flash']) + { + return; + } + $this->setAttribute($name, $value, 'symfony/user/sfUser/flash'); + if ($persist) + { + $this->attributeHolder->remove($name, null, 'symfony/user/sfUser/flash/remove'); + } + else + { + $this->setAttribute($name, true, 'symfony/user/sfUser/flash/remove'); + } + } + public function getFlash($name, $default = null) + { + if (!$this->options['use_flash']) + { + return $default; + } + return $this->getAttribute($name, $default, 'symfony/user/sfUser/flash'); + } + public function hasFlash($name) + { + if (!$this->options['use_flash']) + { + return false; + } + return $this->hasAttribute($name, 'symfony/user/sfUser/flash'); + } + public function getCulture() + { + return $this->culture; + } + public function getAttributeHolder() + { + return $this->attributeHolder; + } + public function getAttribute($name, $default = null, $ns = null) + { + return $this->attributeHolder->get($name, $default, $ns); + } + public function hasAttribute($name, $ns = null) + { + return $this->attributeHolder->has($name, $ns); + } + public function setAttribute($name, $value, $ns = null) + { + return $this->attributeHolder->set($name, $value, $ns); + } + public function shutdown() + { + if ($this->options['use_flash'] && $names = $this->attributeHolder->getNames('symfony/user/sfUser/flash/remove')) + { + if ($this->options['logging']) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Remove old flash messages ("%s")', implode('", "', $names))))); + } + foreach ($names as $name) + { + $this->attributeHolder->remove($name, null, 'symfony/user/sfUser/flash'); + $this->attributeHolder->remove($name, null, 'symfony/user/sfUser/flash/remove'); + } + } + $attributes = array(); + foreach ($this->attributeHolder->getNamespaces() as $namespace) + { + $attributes[$namespace] = $this->attributeHolder->getAll($namespace); + } + $this->storage->write(self::ATTRIBUTE_NAMESPACE, $attributes); + $this->storage->write(self::CULTURE_NAMESPACE, $this->culture); + } + public function __call($method, $arguments) + { + $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'user.method_not_found', array('method' => $method, 'arguments' => $arguments))); + if (!$event->isProcessed()) + { + throw new sfException(sprintf('Call to undefined method %s::%s.', get_class($this), $method)); + } + return $event->getReturnValue(); + } +} + + +class sfNamespacedParameterHolder extends sfParameterHolder +{ + protected $default_namespace = null; + protected $parameters = array(); + public function __construct($namespace = 'symfony/default') + { + $this->default_namespace = $namespace; + } + public function setDefaultNamespace($namespace, $move = true) + { + if ($move) + { + $values = $this->removeNamespace(); + $this->addByRef($values, $namespace); + } + $this->default_namespace = $namespace; + } + public function getDefaultNamespace() + { + return $this->default_namespace; + } + public function clear() + { + $this->parameters = null; + $this->parameters = array(); + } + public function & get($name, $default = null, $ns = null) + { + if (!$ns) + { + $ns = $this->default_namespace; + } + if (isset($this->parameters[$ns][$name])) + { + $value = & $this->parameters[$ns][$name]; + } + else if (isset($this->parameters[$ns])) + { + $value = sfToolkit::getArrayValueForPath($this->parameters[$ns], $name, $default); + } + else + { + $value = $default; + } + return $value; + } + public function getNames($ns = null) + { + if (!$ns) + { + $ns = $this->default_namespace; + } + if (isset($this->parameters[$ns])) + { + return array_keys($this->parameters[$ns]); + } + return array(); + } + public function getNamespaces() + { + return array_keys($this->parameters); + } + public function & getAll($ns = null) + { + if (!$ns) + { + $ns = $this->default_namespace; + } + $parameters = array(); + if (isset($this->parameters[$ns])) + { + $parameters = $this->parameters[$ns]; + } + return $parameters; + } + public function has($name, $ns = null) + { + if (!$ns) + { + $ns = $this->default_namespace; + } + if (isset($this->parameters[$ns][$name])) + { + return true; + } + else if (isset($this->parameters[$ns])) + { + return sfToolkit::hasArrayValueForPath($this->parameters[$ns], $name); + } + return false; + } + public function hasNamespace($ns) + { + return isset($this->parameters[$ns]); + } + public function remove($name, $default = null, $ns = null) + { + if (!$ns) + { + $ns = $this->default_namespace; + } + $retval = $default; + if (isset($this->parameters[$ns]) && array_key_exists($name, $this->parameters[$ns])) + { + $retval = $this->parameters[$ns][$name]; + unset($this->parameters[$ns][$name]); + } + else + { + $retval = sfToolkit::removeArrayValueForPath($this->parameters[$ns], $name, $default); + } + return $retval; + } + public function & removeNamespace($ns = null) + { + if (!$ns) + { + $ns = $this->default_namespace; + } + $retval = null; + if (isset($this->parameters[$ns])) + { + $retval =& $this->parameters[$ns]; + unset($this->parameters[$ns]); + } + return $retval; + } + public function set($name, $value, $ns = null) + { + if (!$ns) + { + $ns = $this->default_namespace; + } + if (!isset($this->parameters[$ns])) + { + $this->parameters[$ns] = array(); + } + $this->parameters[$ns][$name] = $value; + } + public function setByRef($name, & $value, $ns = null) + { + if (!$ns) + { + $ns = $this->default_namespace; + } + if (!isset($this->parameters[$ns])) + { + $this->parameters[$ns] = array(); + } + $this->parameters[$ns][$name] =& $value; + } + public function add($parameters, $ns = null) + { + if ($parameters === null) return; + if (!$ns) + { + $ns = $this->default_namespace; + } + if (!isset($this->parameters[$ns])) + { + $this->parameters[$ns] = array(); + } + foreach ($parameters as $key => $value) + { + $this->parameters[$ns][$key] = $value; + } + } + public function addByRef(& $parameters, $ns = null) + { + if (!$ns) + { + $ns = $this->default_namespace; + } + if (!isset($this->parameters[$ns])) + { + $this->parameters[$ns] = array(); + } + foreach ($parameters as $key => &$value) + { + $this->parameters[$ns][$key] =& $value; + } + } + public function serialize() + { + return serialize(array($this->default_namespace, $this->parameters)); + } + public function unserialize($serialized) + { + $data = unserialize($serialized); + $this->default_namespace = $data[0]; + $this->parameters = $data[1]; + } +} + + +abstract class sfView +{ + const ALERT = 'Alert'; + const ERROR = 'Error'; + const INPUT = 'Input'; + const NONE = 'None'; + const SUCCESS = 'Success'; + const RENDER_NONE = 1; + const RENDER_CLIENT = 2; + const RENDER_VAR = 4; + const HEADER_ONLY = 8; + protected + $context = null, + $dispatcher = null, + $decorator = false, + $decoratorDirectory = null, + $decoratorTemplate = null, + $directory = null, + $componentSlots = array(), + $template = null, + $attributeHolder = null, + $parameterHolder = null, + $moduleName = '', + $actionName = '', + $viewName = '', + $extension = '.php'; + public function __construct($context, $moduleName, $actionName, $viewName) + { + $this->initialize($context, $moduleName, $actionName, $viewName); + } + public function initialize($context, $moduleName, $actionName, $viewName) + { + $this->moduleName = $moduleName; + $this->actionName = $actionName; + $this->viewName = $viewName; + $this->context = $context; + $this->dispatcher = $context->getEventDispatcher(); + sfOutputEscaper::markClassesAsSafe(array('sfForm', 'sfModelGeneratorHelper')); + $this->attributeHolder = $this->initializeAttributeHolder(); + $this->parameterHolder = new sfParameterHolder(); + $this->parameterHolder->add(sfConfig::get('mod_'.strtolower($moduleName).'_view_param', array())); + $request = $context->getRequest(); + if (!is_null($format = $request->getRequestFormat())) + { + if ('html' != $format) + { + $this->setExtension('.'.$format.$this->getExtension()); + } + if ($mimeType = $request->getMimeType($format)) + { + $this->context->getResponse()->setContentType($mimeType); + if ('html' != $format) + { + $this->setDecorator(false); + } + } + $this->dispatcher->notify(new sfEvent($this, 'view.configure_format', array('format' => $format, 'response' => $context->getResponse(), 'request' => $context->getRequest()))); + } + $this->configure(); + return true; + } + protected function initializeAttributeHolder($attributes = array()) + { + if ('both' === sfConfig::get('sf_escaping_strategy')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array('Escaping strategy "both" is deprecated, please use "on".', 'priority' => sfLogger::ERR))); + sfConfig::set('sf_escaping_strategy', 'on'); + } + else if ('bc' === sfConfig::get('sf_escaping_strategy')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array('Escaping strategy "bc" is deprecated, please use "off".', 'priority' => sfLogger::ERR))); + sfConfig::set('sf_escaping_strategy', 'off'); + } + $attributeHolder = new sfViewParameterHolder($this->dispatcher, $attributes, array( + 'escaping_method' => sfConfig::get('sf_escaping_method'), + 'escaping_strategy' => sfConfig::get('sf_escaping_strategy'), + )); + return $attributeHolder; + } + abstract function execute(); + abstract function configure(); + public function getDecoratorDirectory() + { + return $this->decoratorDirectory; + } + public function getDecoratorTemplate() + { + return $this->decoratorTemplate; + } + public function getDirectory() + { + return $this->directory; + } + abstract function getEngine(); + public function getTemplate() + { + return $this->template; + } + public function getAttributeHolder() + { + return $this->attributeHolder; + } + public function getAttribute($name, $default = null) + { + return $this->attributeHolder->get($name, $default); + } + public function hasAttribute($name) + { + return $this->attributeHolder->has($name); + } + public function setAttribute($name, $value) + { + $this->attributeHolder->set($name, $value); + } + public function getParameterHolder() + { + return $this->parameterHolder; + } + public function getParameter($name, $default = null) + { + return $this->parameterHolder->get($name, $default); + } + public function hasParameter($name) + { + return $this->parameterHolder->has($name); + } + public function setParameter($name, $value) + { + $this->parameterHolder->set($name, $value); + } + public function isDecorator() + { + return $this->decorator; + } + public function setDecorator($boolean) + { + $this->decorator = (boolean) $boolean; + if (false === $boolean) + { + $this->decoratorTemplate = false; + } + } + protected function preRenderCheck() + { + if (is_null($this->template)) + { + throw new sfRenderException('A template has not been set.'); + } + if (!is_readable($this->directory.'/'.$this->template)) + { + if ('404' == $this->context->getResponse()->getStatusCode()) + { + $this->template = sfException::getTemplatePathForError($this->context->getRequest()->getRequestFormat(), false); + $this->directory = dirname($this->template); + $this->template = basename($this->template); + $this->setAttribute('code', '404'); + $this->setAttribute('text', 'Not Found'); + } + else + { + throw new sfRenderException(sprintf('The template "%s" does not exist or is unreadable in "%s".', $this->template, $this->directory)); + } + } + if ($this->decorator && !is_readable($this->decoratorDirectory.'/'.$this->decoratorTemplate)) + { + throw new sfRenderException(sprintf('The decorator template "%s" does not exist or is unreadable in "%s".', $this->decoratorTemplate, $this->decoratorDirectory)); + } + } + abstract function render(); + public function setDecoratorDirectory($directory) + { + $this->decoratorDirectory = $directory; + } + public function setDecoratorTemplate($template) + { + if (false === $template) + { + $this->setDecorator(false); + return; + } + else if (is_null($template)) + { + return; + } + if (!strpos($template, '.')) + { + $template .= $this->getExtension(); + } + if (sfToolkit::isPathAbsolute($template)) + { + $this->decoratorDirectory = dirname($template); + $this->decoratorTemplate = basename($template); + } + else + { + $this->decoratorDirectory = $this->context->getConfiguration()->getDecoratorDir($template); + $this->decoratorTemplate = $template; + } + $this->decorator = true; + } + public function setDirectory($directory) + { + $this->directory = $directory; + } + public function setComponentSlot($attributeName, $moduleName, $componentName) + { + $this->componentSlots[$attributeName] = array(); + $this->componentSlots[$attributeName]['module_name'] = $moduleName; + $this->componentSlots[$attributeName]['component_name'] = $componentName; + } + public function hasComponentSlot($name) + { + return isset($this->componentSlots[$name]); + } + public function getComponentSlot($name) + { + if (isset($this->componentSlots[$name]) && $this->componentSlots[$name]['module_name'] && $this->componentSlots[$name]['component_name']) + { + return array($this->componentSlots[$name]['module_name'], $this->componentSlots[$name]['component_name']); + } + return null; + } + public function setTemplate($template) + { + if (sfToolkit::isPathAbsolute($template)) + { + $this->directory = dirname($template); + $this->template = basename($template); + } + else + { + $this->directory = $this->context->getConfiguration()->getTemplateDir($this->moduleName, $template); + $this->template = $template; + } + } + public function getExtension() + { + return $this->extension; + } + public function setExtension($extension) + { + $this->extension = $extension; + } + public function getModuleName() + { + return $this->moduleName; + } + public function getActionName() + { + return $this->actionName; + } + public function getViewName() + { + return $this->viewName; + } + public function __call($method, $arguments) + { + $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'view.method_not_found', array('method' => $method, 'arguments' => $arguments))); + if (!$event->isProcessed()) + { + throw new sfException(sprintf('Call to undefined method %s::%s.', get_class($this), $method)); + } + return $event->getReturnValue(); + } +} + + +class sfViewParameterHolder extends sfParameterHolder +{ + protected + $dispatcher = null, + $escaping = null, + $escapingMethod = null; + public function __construct(sfEventDispatcher $dispatcher, $parameters = array(), $options = array()) + { + $this->initialize($dispatcher, $parameters, $options); + } + public function initialize(sfEventDispatcher $dispatcher, $parameters = array(), $options = array()) + { + $this->dispatcher = $dispatcher; + $this->add($parameters); + $this->setEscaping(isset($options['escaping_strategy']) ? $options['escaping_strategy'] : false); + $this->setEscapingMethod(isset($options['escaping_method']) ? $options['escaping_method'] : 'ESC_SPECIALCHARS'); + } + public function isEscaped() + { + return in_array($this->getEscaping(), array('on', true), true); + } + public function toArray() + { + $event = $this->dispatcher->filter(new sfEvent($this, 'template.filter_parameters'), $this->getAll()); + $parameters = $event->getReturnValue(); + $attributes = array(); + if ($this->isEscaped()) + { + $attributes['sf_data'] = sfOutputEscaper::escape($this->getEscapingMethod(), $parameters); + foreach ($attributes['sf_data'] as $key => $value) + { + $attributes[$key] = $value; + } + } + else if (in_array($this->getEscaping(), array('off', false), true)) + { + $attributes = $parameters; + $attributes['sf_data'] = sfOutputEscaper::escape(ESC_RAW, $parameters); + } + else + { + throw new InvalidArgumentException(sprintf('Unknown strategy "%s".', $this->getEscaping())); + } + return $attributes; + } + public function getEscaping() + { + return $this->escaping; + } + public function setEscaping($escaping) + { + $this->escaping = $escaping; + } + public function getEscapingMethod() + { + if (empty($this->escapingMethod)) + { + return $this->escapingMethod; + } + if (!defined($this->escapingMethod)) + { + throw new InvalidArgumentException(sprintf('The escaping method "%s" is not available.', $this->escapingMethod)); + } + return constant($this->escapingMethod); + } + public function setEscapingMethod($method) + { + $this->escapingMethod = $method; + } + public function serialize() + { + return serialize(array($this->getAll(), $this->escapingMethod, $this->escaping)); + } + public function unserialize($serialized) + { + list($this->parameters, $escapingMethod, $escaping) = unserialize($serialized); + $this->initialize(sfContext::hasInstance() ? sfContext::getInstance()->getEventDispatcher() : new sfEventDispatcher()); + $this->setEscapingMethod($escapingMethod); + $this->setEscaping($escaping); + } +} + + +abstract class sfWebController extends sfController +{ + public function genUrl($parameters = array(), $absolute = false) + { + if (is_string($parameters) && preg_match('#^[a-z][a-z0-9\+.\-]*\://#i', $parameters)) + { + return $parameters; + } + if (is_string($parameters) && 0 === strpos($parameters, '/')) + { + return $parameters; + } + if (is_string($parameters) && $parameters == '#') + { + return $parameters; + } + $route = ''; + $fragment = ''; + if (is_string($parameters)) + { + if (false !== ($pos = strpos($parameters, '#'))) + { + $fragment = substr($parameters, $pos + 1); + $parameters = substr($parameters, 0, $pos); + } + list($route, $parameters) = $this->convertUrlStringToParameters($parameters); + } + else if (is_array($parameters)) + { + if (isset($parameters['sf_route'])) + { + $route = $parameters['sf_route']; + unset($parameters['sf_route']); + } + } + $url = $this->context->getRouting()->generate($route, $parameters, $absolute); + if ($fragment) + { + $url .= '#'.$fragment; + } + return $url; + } + public function convertUrlStringToParameters($url) + { + $givenUrl = $url; + $params = array(); + $queryString = ''; + $route = ''; + if (!$url) + { + $url = '/'; + } + if ($pos = strpos($url, '?')) + { + $queryString = substr($url, $pos + 1); + $url = substr($url, 0, $pos); + } + if ($url[0] == '/') + { + $url = substr($url, 1); + } + if ($url[0] == '@') + { + $route = substr($url, 1); + } + else if (false !== strpos($url, '/')) + { + list($params['module'], $params['action']) = explode('/', $url); + } + else if (!$queryString) + { + $route = $givenUrl; + } + else + { + throw new InvalidArgumentException(sprintf('An internal URI must contain a module and an action (module/action) ("%s" given).', $givenUrl)); + } + if ($queryString) + { + $matched = preg_match_all('/ + ([^&=]+) # key + = # = + (.*?) # value + (?: + (?=&[^&=]+=) | $ # followed by another key= or the end of the string + ) + /x', $queryString, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); + foreach ($matches as $match) + { + $params[urldecode($match[1][0])] = urldecode($match[2][0]); + } + if (!$matched) + { + throw new sfParseException(sprintf('Unable to parse query string "%s".', $queryString)); + } + } + return array($route, $params); + } + public function redirect($url, $delay = 0, $statusCode = 302) + { + $url = $this->genUrl($url, true); + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Redirect to "%s"', $url)))); + } + $response = $this->context->getResponse(); + $response->clearHttpHeaders(); + $response->setStatusCode($statusCode); + $response->setHttpHeader('Location', $url); + $response->setContent(sprintf('', $delay, htmlspecialchars($url, ENT_QUOTES, sfConfig::get('sf_charset')))); + $response->send(); + } +} + + +class sfFrontWebController extends sfWebController +{ + public function dispatch() + { + try + { + sfFilter::$filterCalled = array(); + $request = $this->context->getRequest(); + $moduleName = $request->getParameter('module'); + $actionName = $request->getParameter('action'); + if (empty($moduleName) || empty($actionName)) + { + throw new sfError404Exception(sprintf('Empty module and/or action after parsing the URL "%s" (%s/%s).', $request->getPathInfo(), $moduleName, $actionName)); + } + $this->forward($moduleName, $actionName); + } + catch (sfException $e) + { + $e->printStackTrace(); + } + catch (Exception $e) + { + sfException::createFromException($e)->printStackTrace(); + } + } +} + + +class sfWebRequest extends sfRequest +{ + protected + $languages = null, + $charsets = null, + $acceptableContentTypes = null, + $pathInfoArray = null, + $relativeUrlRoot = null, + $getParameters = null, + $postParameters = null, + $requestParameters = null, + $formats = array(), + $format = null, + $fixedFileArray = false; + public function initialize(sfEventDispatcher $dispatcher, $parameters = array(), $attributes = array(), $options = array()) + { + parent::initialize($dispatcher, $parameters, $attributes, $options); + $this->getParameters = get_magic_quotes_gpc() ? sfToolkit::stripslashesDeep($_GET) : $_GET; + $this->parameterHolder->add($this->getParameters); + $this->postParameters = get_magic_quotes_gpc() ? sfToolkit::stripslashesDeep($_POST) : $_POST; + $this->parameterHolder->add($this->postParameters); + if (isset($_SERVER['REQUEST_METHOD'])) + { + switch ($_SERVER['REQUEST_METHOD']) + { + case 'GET': + $this->setMethod(self::GET); + break; + case 'POST': + $this->setMethod(strtoupper($this->getParameter('sf_method', 'POST'))); + $this->parameterHolder->remove('sf_method'); + break; + case 'PUT': + $this->setMethod(self::PUT); + break; + case 'DELETE': + $this->setMethod(self::DELETE); + break; + case 'HEAD': + $this->setMethod(self::HEAD); + break; + default: + $this->setMethod(self::GET); + } + } + else + { + $this->setMethod(self::GET); + } + if (isset($this->options['formats'])) + { + foreach ($this->options['formats'] as $format => $mimeTypes) + { + $this->setFormat($format, $mimeTypes); + } + } + if (!isset($this->options['path_info_key'])) + { + $this->options['path_info_key'] = 'PATH_INFO'; + } + if (!isset($this->options['path_info_array'])) + { + $this->options['path_info_array'] = 'SERVER'; + } + $this->requestParameters = $this->parseRequestParameters(); + $this->parameterHolder->add($this->requestParameters); + $this->fixParameters(); + } + public function getUri() + { + $pathArray = $this->getPathInfoArray(); + if ('HTTP_X_REWRITE_URL' == $this->options['path_info_key']) + { + $uri = isset($pathArray['HTTP_X_REWRITE_URL']) ? $pathArray['HTTP_X_REWRITE_URL'] : ''; + } + else + { + $uri = isset($pathArray['REQUEST_URI']) ? $pathArray['REQUEST_URI'] : ''; + } + return $this->isAbsUri() ? $uri : $this->getUriPrefix().$uri; + } + public function isAbsUri() + { + $pathArray = $this->getPathInfoArray(); + return isset($pathArray['REQUEST_URI']) ? preg_match('/^http/', $pathArray['REQUEST_URI']) : false; + } + public function getUriPrefix() + { + $pathArray = $this->getPathInfoArray(); + if ($this->isSecure()) + { + $standardPort = '443'; + $protocol = 'https'; + } + else + { + $standardPort = '80'; + $protocol = 'http'; + } + $host = explode(":", $this->getHost()); + if (count($host) == 1) + { + $host[] = isset($pathArray['SERVER_PORT']) ? $pathArray['SERVER_PORT'] : ''; + } + if ($host[1] == $standardPort || empty($host[1])) + { + unset($host[1]); + } + return $protocol.'://'.implode(':', $host);; + } + public function getPathInfo() + { + $pathInfo = ''; + $pathArray = $this->getPathInfoArray(); + $sf_path_info_key = $this->options['path_info_key']; + if (!isset($pathArray[$sf_path_info_key]) || !$pathArray[$sf_path_info_key]) + { + if (isset($pathArray['REQUEST_URI'])) + { + $script_name = $this->getScriptName(); + $uri_prefix = $this->isAbsUri() ? $this->getUriPrefix() : ''; + $pathInfo = preg_replace('/^'.preg_quote($uri_prefix, '/').'/','',$pathArray['REQUEST_URI']); + $pathInfo = preg_replace('/^'.preg_quote($script_name, '/').'/', '', $pathInfo); + $prefix_name = preg_replace('#/[^/]+$#', '', $script_name); + $pathInfo = preg_replace('/^'.preg_quote($prefix_name, '/').'/', '', $pathInfo); + $pathInfo = preg_replace('/\??'.preg_quote($pathArray['QUERY_STRING'], '/').'$/', '', $pathInfo); + } + } + else + { + $pathInfo = $pathArray[$sf_path_info_key]; + if ($relativeUrlRoot = $this->getRelativeUrlRoot()) + { + $pathInfo = preg_replace('/^'.str_replace('/', '\\/', $relativeUrlRoot).'\//', '', $pathInfo); + } + } + if (isset($_SERVER['SERVER_SOFTWARE']) && false !== stripos($_SERVER['SERVER_SOFTWARE'], 'iis') && $pos = stripos($pathInfo, '.php')) + { + $pathInfo = substr($pathInfo, $pos + 4); + } + if (!$pathInfo) + { + $pathInfo = '/'; + } + return $pathInfo; + } + public function getPathInfoPrefix() + { + $prefix = $this->getRelativeUrlRoot(); + if (!isset($this->options['no_script_name']) || !$this->options['no_script_name']) + { + $scriptName = $this->getScriptName(); + $prefix = is_null($prefix) ? $scriptName : $prefix.'/'.basename($scriptName); + } + return $prefix; + } + public function getGetParameters() + { + return $this->getParameters; + } + public function getPostParameters() + { + return $this->postParameters; + } + public function getRequestParameters() + { + return $this->requestParameters; + } + public function addRequestParameters($parameters) + { + $this->requestParameters = array_merge($this->requestParameters, $parameters); + $this->getParameterHolder()->add($parameters); + $this->fixParameters(); + } + public function getReferer() + { + $pathArray = $this->getPathInfoArray(); + return isset($pathArray['HTTP_REFERER']) ? $pathArray['HTTP_REFERER'] : ''; + } + public function getHost() + { + $pathArray = $this->getPathInfoArray(); + return isset($pathArray['HTTP_X_FORWARDED_HOST']) ? $pathArray['HTTP_X_FORWARDED_HOST'] : (isset($pathArray['HTTP_HOST']) ? $pathArray['HTTP_HOST'] : ''); + } + public function getScriptName() + { + $pathArray = $this->getPathInfoArray(); + return isset($pathArray['SCRIPT_NAME']) ? $pathArray['SCRIPT_NAME'] : (isset($pathArray['ORIG_SCRIPT_NAME']) ? $pathArray['ORIG_SCRIPT_NAME'] : ''); + } + public function isMethod($method) + { + return strtoupper($method) == $this->getMethod(); + } + public function getMethodName() + { + if ($this->options['logging']) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array('The "sfWebRequest::getMethodName()" method is deprecated, please use "getMethod()" instead.', 'priority' => sfLogger::WARNING))); + } + return $this->getMethod(); + } + public function getPreferredCulture(array $cultures = null) + { + $preferredCultures = $this->getLanguages(); + if (is_null($cultures)) + { + return isset($preferredCultures[0]) ? $preferredCultures[0] : null; + } + if (!$preferredCultures) + { + return $cultures[0]; + } + $preferredCultures = array_values(array_intersect($preferredCultures, $cultures)); + return isset($preferredCultures[0]) ? $preferredCultures[0] : $cultures[0]; + } + public function getLanguages() + { + if ($this->languages) + { + return $this->languages; + } + if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) + { + return array(); + } + $languages = $this->splitHttpAcceptHeader($_SERVER['HTTP_ACCEPT_LANGUAGE']); + foreach ($languages as $lang) + { + if (strstr($lang, '-')) + { + $codes = explode('-', $lang); + if ($codes[0] == 'i') + { + if (count($codes) > 1) + { + $lang = $codes[1]; + } + } + else + { + for ($i = 0, $max = count($codes); $i < $max; $i++) + { + if ($i == 0) + { + $lang = strtolower($codes[0]); + } + else + { + $lang .= '_'.strtoupper($codes[$i]); + } + } + } + } + $this->languages[] = $lang; + } + return $this->languages; + } + public function getCharsets() + { + if ($this->charsets) + { + return $this->charsets; + } + if (!isset($_SERVER['HTTP_ACCEPT_CHARSET'])) + { + return array(); + } + $this->charsets = $this->splitHttpAcceptHeader($_SERVER['HTTP_ACCEPT_CHARSET']); + return $this->charsets; + } + public function getAcceptableContentTypes() + { + if ($this->acceptableContentTypes) + { + return $this->acceptableContentTypes; + } + if (!isset($_SERVER['HTTP_ACCEPT'])) + { + return array(); + } + $this->acceptableContentTypes = $this->splitHttpAcceptHeader($_SERVER['HTTP_ACCEPT']); + return $this->acceptableContentTypes; + } + public function isXmlHttpRequest() + { + return ($this->getHttpHeader('X_REQUESTED_WITH') == 'XMLHttpRequest'); + } + public function getHttpHeader($name, $prefix = 'http') + { + if ($prefix) + { + $prefix = strtoupper($prefix).'_'; + } + $name = $prefix.strtoupper(strtr($name, '-', '_')); + $pathArray = $this->getPathInfoArray(); + return isset($pathArray[$name]) ? sfToolkit::stripslashesDeep($pathArray[$name]) : null; + } + public function getCookie($name, $defaultValue = null) + { + $retval = $defaultValue; + if (isset($_COOKIE[$name])) + { + $retval = get_magic_quotes_gpc() ? sfToolkit::stripslashesDeep($_COOKIE[$name]) : $_COOKIE[$name]; + } + return $retval; + } + public function isSecure() + { + $pathArray = $this->getPathInfoArray(); + return ( + (isset($pathArray['HTTPS']) && (strtolower($pathArray['HTTPS']) == 'on' || $pathArray['HTTPS'] == 1)) + || + (isset($pathArray['HTTP_SSL_HTTPS']) && (strtolower($pathArray['HTTP_SSL_HTTPS']) == 'on' || $pathArray['HTTP_SSL_HTTPS'] == 1)) + || + (isset($pathArray['HTTP_X_FORWARDED_PROTO']) && strtolower($pathArray['HTTP_X_FORWARDED_PROTO']) == 'https') + ); + } + public function getRelativeUrlRoot() + { + if (is_null($this->relativeUrlRoot)) + { + if (!isset($this->options['relative_url_root'])) + { + $this->relativeUrlRoot = preg_replace('#/[^/]+\.php5?$#', '', $this->getScriptName()); + } + else + { + $this->relativeUrlRoot = $this->options['relative_url_root']; + } + } + return $this->relativeUrlRoot; + } + public function setRelativeUrlRoot($value) + { + $this->relativeUrlRoot = $value; + } + public function splitHttpAcceptHeader($header) + { + $values = array(); + foreach (array_filter(explode(',', $header)) as $value) + { + if ($pos = strpos($value, ';')) + { + $q = (float) trim(substr($value, $pos + 3)); + $value = trim(substr($value, 0, $pos)); + } + else + { + $q = 1; + } + $values[$value] = $q; + } + arsort($values); + return array_keys($values); + } + public function getPathInfoArray() + { + if (!$this->pathInfoArray) + { + switch ($this->options['path_info_array']) + { + case 'SERVER': + $this->pathInfoArray =& $_SERVER; + break; + case 'ENV': + default: + $this->pathInfoArray =& $_ENV; + } + } + return $this->pathInfoArray; + } + public function getMimeType($format) + { + return isset($this->formats[$format]) ? $this->formats[$format][0] : null; + } + public function getFormat($mimeType) + { + foreach ($this->formats as $format => $mimeTypes) + { + if (in_array($mimeType, $mimeTypes)) + { + return $format; + } + } + return null; + } + public function setFormat($format, $mimeTypes) + { + $this->formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes); + } + public function setRequestFormat($format) + { + $this->format = $format; + } + public function getRequestFormat() + { + if (is_null($this->format)) + { + $this->setRequestFormat($this->getParameter('sf_format')); + } + return $this->format; + } + public function getFiles($key = null) + { + if (false === $this->fixedFileArray) + { + $this->fixedFileArray = self::convertFileInformation($_FILES); + } + return is_null($key) ? $this->fixedFileArray : (isset($this->fixedFileArray[$key]) ? $this->fixedFileArray[$key] : array()); + } + static public function convertFileInformation(array $taintedFiles) + { + $files = array(); + foreach ($taintedFiles as $key => $data) + { + $files[$key] = self::fixPhpFilesArray($data); + } + return $files; + } + static protected function fixPhpFilesArray($data) + { + $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type'); + $keys = array_keys($data); + sort($keys); + if ($fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) + { + return $data; + } + $files = $data; + foreach ($fileKeys as $k) + { + unset($files[$k]); + } + foreach (array_keys($data['name']) as $key) + { + $files[$key] = self::fixPhpFilesArray(array( + 'error' => $data['error'][$key], + 'name' => $data['name'][$key], + 'type' => $data['type'][$key], + 'tmp_name' => $data['tmp_name'][$key], + 'size' => $data['size'][$key], + )); + } + return $files; + } + public function getGetParameter($name, $default = null) + { + if (isset($this->getParameters[$name])) + { + return $this->getParameters[$name]; + } + else + { + return sfToolkit::getArrayValueForPath($this->getParameters, $name, $default); + } + } + public function getPostParameter($name, $default = null) + { + if (isset($this->postParameters[$name])) + { + return $this->postParameters[$name]; + } + else + { + return sfToolkit::getArrayValueForPath($this->postParameters, $name, $default); + } + } + public function getUrlParameter($name, $default = null) + { + if (isset($this->requestParameters[$name])) + { + return $this->requestParameters[$name]; + } + else + { + return sfToolkit::getArrayValueForPath($this->requestParameters, $name, $default); + } + } + public function getRemoteAddress() + { + $pathInfo = $this->getPathInfoArray(); + return $pathInfo['REMOTE_ADDR']; + } + public function getForwardedFor() + { + $pathInfo = $this->getPathInfoArray(); + if (empty($pathInfo['HTTP_X_FORWARDED_FOR'])) + { + return null; + } + return explode(', ', $pathInfo['HTTP_X_FORWARDED_FOR']); + } + public function checkCSRFProtection() + { + $form = new sfForm(); + $form->bind($form->isCSRFProtected() ? array($form->getCSRFFieldName() => $this->getParameter($form->getCSRFFieldName())) : array()); + if (!$form->isValid()) + { + throw $form->getErrorSchema(); + } + } + protected function parseRequestParameters() + { + return $this->dispatcher->filter(new sfEvent($this, 'request.filter_parameters', $this->getRequestContext()), array())->getReturnValue(); + } + public function getRequestContext() + { + return array( + 'path_info' => $this->getPathInfo(), + 'prefix' => $this->getPathInfoPrefix(), + 'method' => $this->getMethod(), + 'format' => $this->getRequestFormat(), + 'host' => $this->getHost(), + 'is_secure' => $this->isSecure(), + 'request_uri' => $this->getUri(), + ); + } + protected function fixParameters() + { + foreach ($this->parameterHolder->getAll() as $key => $value) + { + if (0 === stripos($key, '_sf_')) + { + $this->parameterHolder->remove($key); + $this->setAttribute(substr($key, 1), $value); + } + } + } +} + + +class sfPatternRouting extends sfRouting +{ + protected + $currentRouteName = null, + $currentInternalUri = array(), + $routes = array(), + $cacheData = array(), + $cacheChanged = false, + $routesFullyLoaded = true; + public function initialize(sfEventDispatcher $dispatcher, sfCache $cache = null, $options = array()) + { + $options = array_merge(array( + 'variable_prefixes' => array(':'), + 'segment_separators' => array('/', '.'), + 'variable_regex' => '[\w\d_]+', + 'load_configuration' => false, + 'suffix' => '', + 'generate_shortest_url' => true, + 'extra_parameters_as_query_string' => true, + 'lazy_routes_deserialize' => false, + 'lookup_cache_dedicated_keys' => false, + ), $options); + if ('.' == $options['suffix']) + { + $options['suffix'] = ''; + } + parent::initialize($dispatcher, $cache, $options); + if (!is_null($this->cache) && !$options['lookup_cache_dedicated_keys'] && $cacheData = $this->cache->get('symfony.routing.data')) + { + $this->cacheData = unserialize($cacheData); + } + } + public function loadConfiguration() + { + if (!is_null($this->cache) && $routes = $this->cache->get('symfony.routing.configuration')) + { + $this->routes = unserialize($routes); + $this->routesFullyLoaded = false; + } + else + { + if ($this->options['load_configuration'] && $config = sfContext::getInstance()->getConfigCache()->checkConfig('config/routing.yml', true)) + { + $this->setRoutes(include($config)); + } + parent::loadConfiguration(); + if (!is_null($this->cache)) + { + if (!$this->options['lazy_routes_deserialize']) + { + $this->cache->set('symfony.routing.configuration', serialize($this->routes)); + } + else + { + $lazyMap = array(); + foreach ($this->routes as $name => $route) + { + if (is_string($route)) + { + $route = $this->loadRoute($name); + } + $lazyMap[$name] = serialize($route); + } + $this->cache->set('symfony.routing.configuration', serialize($lazyMap)); + } + } + } + } + protected function loadRoute($name) + { + if (is_string($route = $this->routes[$name])) + { + $this->routes[$name] = unserialize($route); + $this->routes[$name]->setDefaultParameters($this->defaultParameters); + return $this->routes[$name]; + } + else + { + return $route; + } + } + protected function loadRoutes() + { + if ($this->routesFullyLoaded) + { + return; + } + foreach ($this->routes as $name => $route) + { + if (is_string($route)) + { + $this->loadRoute($name); + } + } + $this->routesFullyLoaded = true; + } + public function getCurrentInternalUri($withRouteName = false) + { + return is_null($this->currentRouteName) ? null : $this->currentInternalUri[$withRouteName ? 0 : 1]; + } + public function getCurrentRouteName() + { + return $this->currentRouteName; + } + public function getRoutes() + { + if (!$this->routesFullyLoaded) + { + $this->loadRoutes(); + } + return $this->routes; + } + public function setRoutes($routes) + { + foreach ($routes as $name => $route) + { + $this->connect($name, $route); + } + if (!$this->routesFullyLoaded) + { + $this->loadRoutes(); + } + return $this->routes; + } + public function hasRoutes() + { + return count($this->routes) ? true : false; + } + public function clearRoutes() + { + if ($this->options['logging']) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array('Clear all current routes'))); + } + $this->routes = array(); + } + public function hasRouteName($name) + { + return isset($this->routes[$name]) ? true : false; + } + public function prependRoute($name, $route) + { + $routes = $this->routes; + $this->routes = array(); + $newroutes = $this->connect($name, $route); + $this->routes = array_merge($newroutes, $routes); + if (!$this->routesFullyLoaded) + { + $this->loadRoutes(); + } + return $this->routes; + } + public function appendRoute($name, $route) + { + return $this->connect($name, $route); + } + public function insertRouteBefore($pivot, $name, $route) + { + if (!isset($this->routes[$pivot])) + { + throw new sfConfigurationException(sprintf('Unable to insert route "%s" before inexistent route "%s".', $name, $pivot)); + } + $routes = $this->routes; + $this->routes = array(); + $newroutes = array(); + foreach ($routes as $key => $value) + { + if ($key == $pivot) + { + $newroutes = array_merge($newroutes, $this->connect($name, $route)); + } + $newroutes[$key] = $value; + } + $this->routes = $newroutes; + if (!$this->routesFullyLoaded) + { + $this->loadRoutes(); + } + return $this->routes; + } + public function connect($name, $route) + { + $routes = $route instanceof sfRouteCollection ? $route : array($name => $route); + foreach (self::flattenRoutes($routes) as $name => $route) + { + $this->routes[$name] = $route; + $this->configureRoute($route); + if ($this->options['logging']) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Connect %s "%s" (%s)', get_class($route), $name, $route->getPattern())))); + } + } + if (!$this->routesFullyLoaded) + { + $this->loadRoutes(); + } + return $this->routes; + } + public function configureRoute(sfRoute $route) + { + $route->setDefaultParameters($this->defaultParameters); + $route->setDefaultOptions($this->options); + } + public function generate($name, $params = array(), $absolute = false) + { + if (!is_null($this->cache)) + { + $cacheKey = 'generate_'.$name.'_'.md5(serialize(array_merge($this->defaultParameters, $params))).'_'.md5(serialize($this->options['context'])); + if ($this->options['lookup_cache_dedicated_keys'] && $url = $this->cache->get('symfony.routing.data.'.$cacheKey)) + { + return $this->fixGeneratedUrl($url, $absolute); + } + elseif (isset($this->cacheData[$cacheKey])) + { + return $this->fixGeneratedUrl($this->cacheData[$cacheKey], $absolute); + } + } + if ($name) + { + if (!isset($this->routes[$name])) + { + throw new sfConfigurationException(sprintf('The route "%s" does not exist.', $name)); + } + $route = $this->routes[$name]; + if (is_string($route)) + { + $route = $this->loadRoute($name); + } + $route->setDefaultParameters($this->defaultParameters); + } + else + { + if (false === $route = $this->getRouteThatMatchesParameters($params, $this->options['context'])) + { + throw new sfConfigurationException(sprintf('Unable to find a matching route to generate url for params "%s".', is_object($params) ? 'Object('.get_class($params).')' : str_replace("\n", '', var_export($params, true)))); + } + } + $url = $route->generate($params, $this->options['context'], $absolute); + if (!is_null($this->cache)) + { + if ($this->options['lookup_cache_dedicated_keys']) + { + $this->cache->set('symfony.routing.data.'.$cacheKey, $url); + } + else + { + $this->cacheChanged = true; + $this->cacheData[$cacheKey] = $url; + } + } + return $this->fixGeneratedUrl($url, $absolute); + } + public function parse($url) + { + if (false === $info = $this->findRoute($url)) + { + $this->currentRouteName = null; + $this->currentInternalUri = array(); + return false; + } + if ($this->options['logging']) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Match route "%s" (%s) for %s with parameters %s', $info['name'], $info['pattern'], $url, str_replace("\n", '', var_export($info['parameters'], true)))))); + } + $this->updateCurrentInternalUri($info['name'], $info['parameters']); + $route = $this->routes[$info['name']]; + if (is_string($route)) + { + $route = $this->loadRoute($info['name']); + } + $route->setDefaultParameters($this->defaultParameters); + $route->bind($this->options['context'], $info['parameters']); + $info['parameters']['_sf_route'] = $route; + return $info['parameters']; + } + protected function updateCurrentInternalUri($name, array $parameters) + { + $this->currentRouteName = $name; + $internalUri = array('@'.$this->currentRouteName, $parameters['module'].'/'.$parameters['action']); + unset($parameters['module'], $parameters['action']); + $params = array(); + foreach ($parameters as $key => $value) + { + $params[] = $key.'='.$value; + } + sort($params); + $params = $params ? '?'.implode('&', $params) : ''; + $this->currentInternalUri = array($internalUri[0].$params, $internalUri[1].$params); + } + public function findRoute($url) + { + $url = $this->normalizeUrl($url); + if (!is_null($this->cache)) + { + $cacheKey = 'parse_'.$url.'_'.md5(serialize($this->options['context'])); + if ($this->options['lookup_cache_dedicated_keys'] && $info = $this->cache->get('symfony.routing.data.'.$cacheKey)) + { + return unserialize($info); + } + elseif (isset($this->cacheData[$cacheKey])) + { + return $this->cacheData[$cacheKey]; + } + } + $info = $this->getRouteThatMatchesUrl($url); + if (!is_null($this->cache)) + { + if ($this->options['lookup_cache_dedicated_keys']) + { + $this->cache->set('symfony.routing.data.'.$cacheKey, serialize($info)); + } + else + { + $this->cacheChanged = true; + $this->cacheData[$cacheKey] = $info; + } + } + return $info; + } + static public function flattenRoutes($routes) + { + $flattenRoutes = array(); + foreach ($routes as $name => $route) + { + if ($route instanceof sfRouteCollection) + { + $flattenRoutes = array_merge($flattenRoutes, self::flattenRoutes($route)); + } + else + { + $flattenRoutes[$name] = $route; + } + } + return $flattenRoutes; + } + protected function getRouteThatMatchesUrl($url) + { + foreach ($this->routes as $name => $route) + { + if (is_string($route)) + { + $route = $this->loadRoute($name); + } + $route->setDefaultParameters($this->defaultParameters); + if (false === $parameters = $route->matchesUrl($url, $this->options['context'])) + { + continue; + } + return array('name' => $name, 'pattern' => $route->getPattern(), 'parameters' => $parameters); + } + return false; + } + protected function getRouteThatMatchesParameters($parameters) + { + foreach ($this->routes as $name => $route) + { + if (is_string($route)) + { + $route = $this->loadRoute($name); + } + $route->setDefaultParameters($this->defaultParameters); + if ($route->matchesParameters($parameters, $this->options['context'])) + { + return $route; + } + } + return false; + } + protected function normalizeUrl($url) + { + if ('/' != substr($url, 0, 1)) + { + $url = '/'.$url; + } + if (false !== $pos = strpos($url, '?')) + { + $url = substr($url, 0, $pos); + } + $url = preg_replace('#/+#', '/', $url); + return $url; + } + public function shutdown() + { + if (!is_null($this->cache) && $this->cacheChanged) + { + $this->cacheChanged = false; + $this->cache->set('symfony.routing.data', serialize($this->cacheData)); + } + } +} + + +class sfWebResponse extends sfResponse +{ + const + FIRST = 'first', + MIDDLE = '', + LAST = 'last', + ALL = 'ALL', + RAW = 'RAW'; + protected + $cookies = array(), + $statusCode = 200, + $statusText = 'OK', + $headerOnly = false, + $headers = array(), + $metas = array(), + $httpMetas = array(), + $positions = array('first', '', 'last'), + $stylesheets = array(), + $javascripts = array(), + $slots = array(); + static protected $statusTexts = array( + '100' => 'Continue', + '101' => 'Switching Protocols', + '200' => 'OK', + '201' => 'Created', + '202' => 'Accepted', + '203' => 'Non-Authoritative Information', + '204' => 'No Content', + '205' => 'Reset Content', + '206' => 'Partial Content', + '300' => 'Multiple Choices', + '301' => 'Moved Permanently', + '302' => 'Found', + '303' => 'See Other', + '304' => 'Not Modified', + '305' => 'Use Proxy', + '306' => '(Unused)', + '307' => 'Temporary Redirect', + '400' => 'Bad Request', + '401' => 'Unauthorized', + '402' => 'Payment Required', + '403' => 'Forbidden', + '404' => 'Not Found', + '405' => 'Method Not Allowed', + '406' => 'Not Acceptable', + '407' => 'Proxy Authentication Required', + '408' => 'Request Timeout', + '409' => 'Conflict', + '410' => 'Gone', + '411' => 'Length Required', + '412' => 'Precondition Failed', + '413' => 'Request Entity Too Large', + '414' => 'Request-URI Too Long', + '415' => 'Unsupported Media Type', + '416' => 'Requested Range Not Satisfiable', + '417' => 'Expectation Failed', + '500' => 'Internal Server Error', + '501' => 'Not Implemented', + '502' => 'Bad Gateway', + '503' => 'Service Unavailable', + '504' => 'Gateway Timeout', + '505' => 'HTTP Version Not Supported', + ); + public function initialize(sfEventDispatcher $dispatcher, $options = array()) + { + parent::initialize($dispatcher, $options); + $this->javascripts = array_combine($this->positions, array_fill(0, count($this->positions), array())); + $this->stylesheets = array_combine($this->positions, array_fill(0, count($this->positions), array())); + if (!isset($this->options['charset'])) + { + $this->options['charset'] = 'utf-8'; + } + if (!isset($this->options['send_http_headers'])) + { + $this->options['send_http_headers'] = true; + } + if (!isset($this->options['http_protocol'])) + { + $this->options['http_protocol'] = 'HTTP/1.0'; + } + $this->options['content_type'] = $this->fixContentType(isset($this->options['content_type']) ? $this->options['content_type'] : 'text/html'); + } + public function setHeaderOnly($value = true) + { + $this->headerOnly = (boolean) $value; + } + public function isHeaderOnly() + { + return $this->headerOnly; + } + public function setCookie($name, $value, $expire = null, $path = '/', $domain = '', $secure = false, $httpOnly = false) + { + if ($expire !== null) + { + if (is_numeric($expire)) + { + $expire = (int) $expire; + } + else + { + $expire = strtotime($expire); + if ($expire === false || $expire == -1) + { + throw new sfException('Your expire parameter is not valid.'); + } + } + } + $this->cookies[$name] = array( + 'name' => $name, + 'value' => $value, + 'expire' => $expire, + 'path' => $path, + 'domain' => $domain, + 'secure' => $secure ? true : false, + 'httpOnly' => $httpOnly, + ); + } + public function setStatusCode($code, $name = null) + { + $this->statusCode = $code; + $this->statusText = null !== $name ? $name : self::$statusTexts[$code]; + } + public function getStatusText() + { + return $this->statusText; + } + public function getStatusCode() + { + return $this->statusCode; + } + public function setHttpHeader($name, $value, $replace = true) + { + $name = $this->normalizeHeaderName($name); + if (is_null($value)) + { + unset($this->headers[$name]); + return; + } + if ('Content-Type' == $name) + { + if ($replace || !$this->getHttpHeader('Content-Type', null)) + { + $this->setContentType($value); + } + return; + } + if (!$replace) + { + $current = isset($this->headers[$name]) ? $this->headers[$name] : ''; + $value = ($current ? $current.', ' : '').$value; + } + $this->headers[$name] = $value; + } + public function getHttpHeader($name, $default = null) + { + $name = $this->normalizeHeaderName($name); + return isset($this->headers[$name]) ? $this->headers[$name] : $default; + } + public function hasHttpHeader($name) + { + return array_key_exists($this->normalizeHeaderName($name), $this->headers); + } + public function setContentType($value) + { + $this->headers['Content-Type'] = $this->fixContentType($value); + } + public function getCharset() + { + return $this->options['charset']; + } + public function getContentType() + { + return $this->getHttpHeader('Content-Type', $this->options['content_type']); + } + public function sendHttpHeaders() + { + if (!$this->options['send_http_headers']) + { + return; + } + $status = $this->options['http_protocol'].' '.$this->statusCode.' '.$this->statusText; + header($status); + if ($this->options['logging']) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Send status "%s"', $status)))); + } + if (!$this->getHttpHeader('Content-Type')) + { + $this->setContentType($this->options['content_type']); + } + foreach ($this->headers as $name => $value) + { + header($name.': '.$value); + if ($value != '' && $this->options['logging']) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Send header "%s: %s"', $name, $value)))); + } + } + foreach ($this->cookies as $cookie) + { + setrawcookie($cookie['name'], $cookie['value'], $cookie['expire'], $cookie['path'], $cookie['domain'], $cookie['secure'], $cookie['httpOnly']); + if ($this->options['logging']) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Send cookie "%s": "%s"', $cookie['name'], $cookie['value'])))); + } + } + } + public function sendContent() + { + if (!$this->headerOnly) + { + parent::sendContent(); + } + } + public function send() + { + $this->sendHttpHeaders(); + $this->sendContent(); + } + protected function normalizeHeaderName($name) + { + return preg_replace('/\-(.)/e', "'-'.strtoupper('\\1')", strtr(ucfirst(strtolower($name)), '_', '-')); + } + static public function getDate($timestamp, $type = 'rfc1123') + { + $type = strtolower($type); + if ($type == 'rfc1123') + { + return substr(gmdate('r', $timestamp), 0, -5).'GMT'; + } + else if ($type == 'rfc1036') + { + return gmdate('l, d-M-y H:i:s ', $timestamp).'GMT'; + } + else if ($type == 'asctime') + { + return gmdate('D M j H:i:s', $timestamp); + } + else + { + throw new InvalidArgumentException('The second getDate() method parameter must be one of: rfc1123, rfc1036 or asctime.'); + } + } + public function addVaryHttpHeader($header) + { + $vary = $this->getHttpHeader('Vary'); + $currentHeaders = array(); + if ($vary) + { + $currentHeaders = preg_split('/\s*,\s*/', $vary); + } + $header = $this->normalizeHeaderName($header); + if (!in_array($header, $currentHeaders)) + { + $currentHeaders[] = $header; + $this->setHttpHeader('Vary', implode(', ', $currentHeaders)); + } + } + public function addCacheControlHttpHeader($name, $value = null) + { + $cacheControl = $this->getHttpHeader('Cache-Control'); + $currentHeaders = array(); + if ($cacheControl) + { + foreach (preg_split('/\s*,\s*/', $cacheControl) as $tmp) + { + $tmp = explode('=', $tmp); + $currentHeaders[$tmp[0]] = isset($tmp[1]) ? $tmp[1] : null; + } + } + $currentHeaders[strtr(strtolower($name), '_', '-')] = $value; + $headers = array(); + foreach ($currentHeaders as $key => $value) + { + $headers[] = $key.(null !== $value ? '='.$value : ''); + } + $this->setHttpHeader('Cache-Control', implode(', ', $headers)); + } + public function getHttpMetas() + { + return $this->httpMetas; + } + public function addHttpMeta($key, $value, $replace = true) + { + $key = $this->normalizeHeaderName($key); + $this->setHttpHeader($key, $value, $replace); + if (is_null($value)) + { + unset($this->httpMetas[$key]); + return; + } + if ('Content-Type' == $key) + { + $value = $this->getContentType(); + } + elseif (!$replace) + { + $current = isset($this->httpMetas[$key]) ? $this->httpMetas[$key] : ''; + $value = ($current ? $current.', ' : '').$value; + } + $this->httpMetas[$key] = $value; + } + public function getMetas() + { + return $this->metas; + } + public function addMeta($key, $value, $replace = true, $escape = true) + { + $key = strtolower($key); + if (is_null($value)) + { + unset($this->metas[$key]); + return; + } + if ($escape) + { + $value = htmlspecialchars($value, ENT_QUOTES, $this->options['charset']); + } + $current = isset($this->metas[$key]) ? $this->metas[$key] : null; + if ($replace || !$current) + { + $this->metas[$key] = $value; + } + } + public function getTitle() + { + return isset($this->metas['title']) ? $this->metas['title'] : ''; + } + public function setTitle($title, $escape = true) + { + $this->addMeta('title', $title, true, $escape); + } + public function getPositions() + { + return $this->positions; + } + public function getStylesheets($position = self::ALL) + { + if (self::ALL === $position) + { + $stylesheets = array(); + foreach ($this->getPositions() as $position) + { + foreach ($this->stylesheets[$position] as $file => $options) + { + $stylesheets[$file] = $options; + } + } + return $stylesheets; + } + else if (self::RAW === $position) + { + return $this->stylesheets; + } + $this->validatePosition($position); + return $this->stylesheets[$position]; + } + public function addStylesheet($file, $position = '', $options = array()) + { + $this->validatePosition($position); + $this->stylesheets[$position][$file] = $options; + } + public function removeStylesheet($file) + { + foreach ($this->getPositions() as $position) + { + unset($this->stylesheets[$position][$file]); + } + } + public function getJavascripts($position = self::ALL) + { + if (self::ALL === $position) + { + $javascripts = array(); + foreach ($this->getPositions() as $position) + { + foreach ($this->javascripts[$position] as $file => $options) + { + $javascripts[$file] = $options; + } + } + return $javascripts; + } + else if (self::RAW === $position) + { + return $this->javascripts; + } + $this->validatePosition($position); + return $this->javascripts[$position]; + } + public function addJavascript($file, $position = '', $options = array()) + { + $this->validatePosition($position); + $this->javascripts[$position][$file] = $options; + } + public function removeJavascript($file) + { + foreach ($this->getPositions() as $position) + { + unset($this->javascripts[$position][$file]); + } + } + public function getSlots() + { + return $this->slots; + } + public function setSlot($name, $content) + { + $this->slots[$name] = $content; + } + public function getCookies() + { + return $this->cookies; + } + public function getHttpHeaders() + { + return $this->headers; + } + public function clearHttpHeaders() + { + $this->headers = array(); + } + public function copyProperties(sfWebResponse $response) + { + $this->options = $response->getOptions(); + $this->headers = $response->getHttpHeaders(); + $this->metas = $response->getMetas(); + $this->httpMetas = $response->getHttpMetas(); + $this->stylesheets = $response->getStylesheets(self::RAW); + $this->javascripts = $response->getJavascripts(self::RAW); + $this->slots = $response->getSlots(); + } + public function merge(sfWebResponse $response) + { + foreach ($this->getPositions() as $position) + { + $this->javascripts[$position] = array_merge($this->getJavascripts($position), $response->getJavascripts($position)); + $this->stylesheets[$position] = array_merge($this->getStylesheets($position), $response->getStylesheets($position)); + } + $this->slots = array_merge($this->getSlots(), $response->getSlots()); + } + public function serialize() + { + return serialize(array($this->content, $this->statusCode, $this->statusText, $this->options, $this->cookies, $this->headerOnly, $this->headers, $this->metas, $this->httpMetas, $this->stylesheets, $this->javascripts, $this->slots)); + } + public function unserialize($serialized) + { + list($this->content, $this->statusCode, $this->statusText, $this->options, $this->cookies, $this->headerOnly, $this->headers, $this->metas, $this->httpMetas, $this->stylesheets, $this->javascripts, $this->slots) = unserialize($serialized); + } + protected function validatePosition($position) + { + if (!in_array($position, $this->positions, true)) + { + throw new InvalidArgumentException(sprintf('The position "%s" does not exist (available positions: %s).', $position, implode(', ', $this->positions))); + } + } + protected function fixContentType($contentType) + { + if (false === stripos($contentType, 'charset') && (0 === stripos($contentType, 'text/') || strlen($contentType) - 3 === strripos($contentType, 'xml'))) + { + $contentType .= '; charset='.$this->options['charset']; + } + if (preg_match('/charset\s*=\s*(.+)\s*$/', $contentType, $match)) + { + $this->options['charset'] = $match[1]; + } + return $contentType; + } +} + + +class sfSessionStorage extends sfStorage +{ + static protected + $sessionIdRegenerated = false, + $sessionStarted = false; + public function initialize($options = null) + { + $cookieDefaults = session_get_cookie_params(); + $options = array_merge(array( + 'session_name' => 'symfony', + 'session_id' => null, + 'auto_start' => true, + 'session_cookie_lifetime' => $cookieDefaults['lifetime'], + 'session_cookie_path' => $cookieDefaults['path'], + 'session_cookie_domain' => $cookieDefaults['domain'], + 'session_cookie_secure' => $cookieDefaults['secure'], + 'session_cookie_httponly' => isset($cookieDefaults['httponly']) ? $cookieDefaults['httponly'] : false, + 'session_cache_limiter' => 'none', + ), $options); + parent::initialize($options); + $sessionName = $this->options['session_name']; + session_name($sessionName); + if (!(boolean) ini_get('session.use_cookies') && $sessionId = $this->options['session_id']) + { + session_id($sessionId); + } + $lifetime = $this->options['session_cookie_lifetime']; + $path = $this->options['session_cookie_path']; + $domain = $this->options['session_cookie_domain']; + $secure = $this->options['session_cookie_secure']; + $httpOnly = $this->options['session_cookie_httponly']; + session_set_cookie_params($lifetime, $path, $domain, $secure, $httpOnly); + if (!is_null($this->options['session_cache_limiter'])) + { + session_cache_limiter($this->options['session_cache_limiter']); + } + if ($this->options['auto_start'] && !self::$sessionStarted) + { + session_start(); + self::$sessionStarted = true; + } + } + public function read($key) + { + $retval = null; + if (isset($_SESSION[$key])) + { + $retval = $_SESSION[$key]; + } + return $retval; + } + public function remove($key) + { + $retval = null; + if (isset($_SESSION[$key])) + { + $retval = $_SESSION[$key]; + unset($_SESSION[$key]); + } + return $retval; + } + public function write($key, $data) + { + $_SESSION[$key] = $data; + } + public function regenerate($destroy = false) + { + if (self::$sessionIdRegenerated) + { + return; + } + session_regenerate_id($destroy); + self::$sessionIdRegenerated = true; + } + public function shutdown() + { + session_write_close(); + } +} + + +class sfPHPView extends sfView +{ + public function execute() + { + } + protected function loadCoreAndStandardHelpers() + { + static $coreHelpersLoaded = 0; + if ($coreHelpersLoaded) + { + return; + } + $coreHelpersLoaded = 1; + $helpers = array_unique(array_merge(array('Helper', 'Url', 'Asset', 'Tag', 'Escaping'), sfConfig::get('sf_standard_helpers'))); + if (!sfConfig::get('sf_compat_10') && false !== $i = array_search('Form', $helpers)) + { + unset($helpers[$i]); + } + $this->context->getConfiguration()->loadHelpers($helpers); + } + protected function renderFile($_sfFile) + { + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Render "%s"', $_sfFile)))); + } + $this->loadCoreAndStandardHelpers(); + extract($this->attributeHolder->toArray()); + ob_start(); + ob_implicit_flush(0); + require($_sfFile); + return ob_get_clean(); + } + public function getEngine() + { + return null; + } + public function configure() + { + $this->context->set('view_instance', $this); + require($this->context->getConfigCache()->checkConfig('modules/'.$this->moduleName.'/config/view.yml')); + if (!$this->directory) + { + $this->setDirectory($this->context->getConfiguration()->getTemplateDir($this->moduleName, $this->getTemplate())); + } + } + protected function decorate($content) + { + if (sfConfig::get('sf_logging_enabled')) + { + $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Decorate content with "%s/%s"', $this->getDecoratorDirectory(), $this->getDecoratorTemplate())))); + } + $attributeHolder = $this->attributeHolder; + $this->attributeHolder = $this->initializeAttributeHolder(array('sf_content' => new sfOutputEscaperSafe($content))); + $this->attributeHolder->set('sf_type', 'layout'); + $ret = $this->renderFile($this->getDecoratorDirectory().'/'.$this->getDecoratorTemplate()); + $this->attributeHolder = $attributeHolder; + return $ret; + } + public function render() + { + $content = null; + if (sfConfig::get('sf_cache')) + { + $viewCache = $this->context->getViewCacheManager(); + $uri = $this->context->getRouting()->getCurrentInternalUri(); + if (!is_null($uri)) + { + list($content, $decoratorTemplate) = $viewCache->getActionCache($uri); + if (!is_null($content)) + { + $this->setDecoratorTemplate($decoratorTemplate); + } + } + } + if (is_null($content)) + { + $this->preRenderCheck(); + $this->attributeHolder->set('sf_type', 'action'); + $content = $this->renderFile($this->getDirectory().'/'.$this->getTemplate()); + if (sfConfig::get('sf_cache') && !is_null($uri)) + { + $content = $viewCache->setActionCache($uri, $content, $this->isDecorator() ? $this->getDecoratorDirectory().'/'.$this->getDecoratorTemplate() : false); + } + } + if ($this->isDecorator()) + { + $content = $this->decorate($content); + } + return $content; + } +} + + +class sfOutputEscaperSafe extends ArrayIterator +{ + protected + $value = null; + public function __construct($value) + { + $this->value = $value; + if (is_array($value) || is_object($value)) + { + parent::__construct($value); + } + } + public function __toString() + { + return (string) $this->value; + } + public function __get($key) + { + return $this->value->$key; + } + public function __set($key, $value) + { + $this->value->$key = $value; + } + public function __call($method, $arguments) + { + return call_user_func_array(array($this->value, $method), $arguments); + } + public function __isset($key) + { + return isset($this->value->$key); + } + public function __unset($key) + { + unset($this->value->$key); + } + public function getValue() + { + return $this->value; + } +} +