Skip to content
This repository has been archived by the owner on Feb 4, 2022. It is now read-only.

Commit

Permalink
Issue #75: Refactor View
Browse files Browse the repository at this point in the history
- Move Viiew::getRoute() to new routable behavior and make it register the 'route()' template function
- Remove the 'escape' parameter from getRoute(), set the route escaping bin ViewTemplate::setUrl()
- Add getContent() method to ViewContextInteface, and pass and set the content in View::getContext()
- Make View class properties private and add ViewInterface::getMimetype()

BREAKING! The view class properties are now private. To migrate your code use the getter methods as defined in ViewInterface
  • Loading branch information
johanjanssens committed May 1, 2016
1 parent 38606c2 commit 3b14965
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 260 deletions.
156 changes: 49 additions & 107 deletions code/view/abstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,49 +22,49 @@ abstract class ViewAbstract extends Object implements ViewInterface, CommandCall
*
* @var string|object
*/
protected $_model;
private $__model;

/**
* The uniform resource locator
*
* @var HttpUrl
*/
protected $_url;
private $__url;

/**
* The content of the view
*
* @var string
*/
protected $_content;
private $__content;

/**
* The title of the view
*
* @var string
*/
protected $_title;
private $__title;

/**
* The view data
*
* @var boolean
*/
protected $_data;
private $__data;

/**
* The view parameters
*
* @var boolean
* @var array
*/
protected $_parameters;
private $__parameters;

/**
* The mimetype
*
* @var string
*/
public $mimetype = '';
private $__mimetype;

/**
* Constructor
Expand All @@ -76,15 +76,15 @@ public function __construct(ObjectConfig $config)
parent::__construct($config);

//Set the data
$this->_data = ObjectConfig::unbox($config->data);
$this->__data = ObjectConfig::unbox($config->data);

//Set the parameters
$this->_parameters = ObjectConfig::unbox($config->parameters);
$this->__parameters = ObjectConfig::unbox($config->parameters);

$this->setUrl($config->url);
$this->setTitle($config->title);
$this->setContent($config->content);
$this->mimetype = $config->mimetype;
$this->setMimetype($config->mimetype);

$this->setModel($config->model);

Expand All @@ -111,14 +111,13 @@ protected function _initialize(ObjectConfig $config)
$config->append(array(
'data' => array(),
'parameters' => array(),
'command_chain' => 'lib:command.chain',
'command_handlers' => array('lib:command.handler.event'),
'model' => 'lib:model.empty',
'content' => '',
'mimetype' => '',
'mimetype' => 'application/octet-stream ',
'url' => $this->getObject('lib:http.url'),
'title' => ucfirst($this->getName()),
'behaviors' => array('localizable')
'behaviors' => array()
));

parent::_initialize($config);
Expand All @@ -133,17 +132,19 @@ protected function _initialize(ObjectConfig $config)
final public function render($data = array())
{
$context = $this->getContext();
$context->data = array_merge($this->getData(), $data);
$context->action = 'render';
$context->data = array_merge($this->getData(), $data);

if ($this->invokeCommand('before.render', $context) !== false)
{
//Render the view
$context->result = $this->_actionRender($context);
$context->content = $this->_actionRender($context);
$this->invokeCommand('after.render', $context);
}

return $context->result;
//Set the content
$this->setContent($context->content);

return $context->content;
}

/**
Expand All @@ -166,8 +167,7 @@ public function invokeCommandCallback($method, CommandInterface $command)
*/
protected function _actionRender(ViewContext $context)
{
$contents = $this->getContent();
return trim($contents);
return trim($context->content);
}

/**
Expand All @@ -190,7 +190,7 @@ protected function _fetchData(ViewContext $context)
*/
public function set($property, $value)
{
$this->_data[$property] = $value;
$this->__data[$property] = $value;
return $this;
}

Expand All @@ -204,7 +204,7 @@ public function set($property, $value)
*/
public function get($property, $default = null)
{
return isset($this->_data[$property]) ? $this->_data[$property] : $default;
return isset($this->__data[$property]) ? $this->__data[$property] : $default;
}

/**
Expand All @@ -215,7 +215,7 @@ public function get($property, $default = null)
*/
public function has($property)
{
return isset($this->_data[$property]);
return isset($this->__data[$property]);
}

/**
Expand All @@ -225,7 +225,7 @@ public function has($property)
*/
public function getData()
{
return $this->_data;
return $this->__data;
}

/**
Expand All @@ -250,7 +250,7 @@ public function setData($data)
*/
public function getParameters()
{
return $this->_parameters;
return $this->__parameters;
}

/**
Expand All @@ -261,7 +261,7 @@ public function getParameters()
*/
public function setParameters(array $parameters)
{
$this->_parameters = $parameters;
$this->__parameters = $parameters;
return $this;
}

Expand All @@ -272,7 +272,7 @@ public function setParameters(array $parameters)
*/
public function getTitle()
{
return $this->_title;
return $this->__title;
}

/**
Expand All @@ -282,7 +282,7 @@ public function getTitle()
*/
public function setTitle($title)
{
$this->_title = $title;
$this->__title = $title;
return $this;
}

Expand All @@ -293,7 +293,7 @@ public function setTitle($title)
*/
public function getContent()
{
return $this->_content;
return $this->__content;
}

/**
Expand All @@ -304,7 +304,7 @@ public function getContent()
*/
public function setContent($content)
{
$this->_content = $content;
$this->__content = $content;
return $this;
}

Expand All @@ -316,19 +316,19 @@ public function setContent($content)
*/
public function getModel()
{
if(!$this->_model instanceof ModelInterface)
if(!$this->__model instanceof ModelInterface)
{
$this->_model = $this->getObject($this->_model);
$this->__model = $this->getObject($this->__model);

if(!$this->_model instanceof ModelInterface)
if(!$this->__model instanceof ModelInterface)
{
throw new \UnexpectedValueException(
'Model: '.get_class($this->_model).' does not implement ModelInterface'
'Model: '.get_class($this->__model).' does not implement ModelInterface'
);
}
}

return $this->_model;
return $this->__model;
}

/**
Expand Down Expand Up @@ -360,7 +360,7 @@ public function setModel($model)
$model = $identifier;
}

$this->_model = $model;
$this->__model = $model;

return $this;
}
Expand All @@ -372,7 +372,7 @@ public function setModel($model)
*/
public function getUrl()
{
return $this->_url;
return $this->__url;
}

/**
Expand All @@ -388,79 +388,10 @@ public function setUrl(HttpUrl $url)
unset($url->pass);
unset($url->port);

$this->_url = $url;
$this->__url = $url;
return $this;
}

/**
* Get a route based on a full or partial query string
*
* 'option', 'view' and 'layout' can be omitted. The following variations will all result in the same route :
*
* - foo=bar
* - component=[package]&view=[name]&foo=bar
*
* In templates, use route()
*
* @param string|array $route The query string or array used to create the route
* @param boolean $fqr If TRUE create a fully qualified route. Defaults to TRUE.
* @param boolean $escape If TRUE escapes the route for xml compliance. Defaults to TRUE.
* @return DispatcherRouterRoute The route
*/
public function getRoute($route = '', $fqr = true, $escape = true)
{
//Parse route
$parts = array();

if(is_string($route)) {
parse_str(trim($route), $parts);
} else {
$parts = $route;
}

//Check to see if there is component information in the route if not add it
if (!isset($parts['component'])) {
$parts['component'] = $this->getIdentifier()->package;
}

//Add the view information to the route if it's not set
if (!isset($parts['view'])) {
$parts['view'] = $this->getName();
}

//Add the format information to the route only if it's not 'html'
if (!isset($parts['format']) && $this->getIdentifier()->name !== 'html') {
$parts['format'] = $this->getIdentifier()->name;
}

//Add the model state only for routes to the same view
if ($parts['component'] == $this->getIdentifier()->package && $parts['view'] == $this->getName())
{
$states = array();
foreach($this->getModel()->getState() as $name => $state)
{
if($state->default != $state->value && !$state->internal) {
$states[$name] = $state->value;
}
}

$parts = array_merge($states, $parts);
}

//Create the route
$route = $this->getObject('lib:dispatcher.router.route', array('escape' => $escape))
->setQuery($parts);

//Add the host and the schema
if ($fqr === true)
{
$route->scheme = $this->getUrl()->scheme;
$route->host = $this->getUrl()->host;
}

return $route;
}

/**
* Get the view context
*
Expand All @@ -471,6 +402,7 @@ public function getContext()
$context = new ViewContext();
$context->setSubject($this);
$context->setData($this->getData());
$context->setContent($this->getContent());
$context->setParameters($this->getParameters());

return $context;
Expand All @@ -497,6 +429,16 @@ public function getFormat()
return $this->getIdentifier()->name;
}

/**
* Get the mimetype
*
* @return string The mimetype of the view
*/
public function getMimetype()
{
return $this->__mimetype;
}

/**
* Returns the views output
*
Expand Down
6 changes: 5 additions & 1 deletion code/view/behavior/decoratable.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,16 @@ protected function _afterRender(ViewContextInterface $context)
{
foreach ($this->getDecorators() as $decorator)
{
//Set the content to allow it to be decorated
$this->setContent($context->content);

//A fully qualified template path is required
$layout = $this->qualifyLayout($decorator);

//Unpack the data (first level only)
$data = $context->data->toArray();

$context->result = $this->getTemplate()
$context->content = $this->getTemplate()
->setParameters($context->parameters)
->render($layout, $data);
}
Expand Down
Loading

0 comments on commit 3b14965

Please sign in to comment.