You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PlexShare/fuel/core/classes/presenter.php

351 lines
7.5 KiB

7 years ago
<?php
/**
* Part of the Fuel framework.
*
* @package Fuel
* @version 1.8
* @author Fuel Development Team
* @license MIT License
* @copyright 2010 - 2016 Fuel Development Team
* @link http://fuelphp.com
*/
namespace Fuel\Core;
/**
* Presenter
*
* @package Fuel
* @subpackage Core
* @category Core * @author Jelmer Schreuder
*/
abstract class Presenter
{
// namespace prefix
protected static $ns_prefix = 'Presenter_';
/**
* Factory for fetching the Presenter
*
* @param string $presenter Presenter classname without View_ prefix or full classname
* @param string $method Method to execute
* @param bool $auto_filter Auto filter the view data
* @param string $view View to associate with this presenter
* @return Presenter
*/
public static function forge($presenter, $method = 'view', $auto_filter = null, $view = null)
{
// determine the presenter namespace from the current request context
$namespace = \Request::active() ? ucfirst(\Request::active()->module) : '';
// create the list of possible class prefixes
$prefixes = array(static::$ns_prefix, $namespace.'\\');
/**
* Add non prefixed classnames to the list as well, for BC reasons
*
* @deprecated 1.6
*/
if ( ! empty($namespace))
{
array_unshift($prefixes, $namespace.'\\'.static::$ns_prefix);
$prefixes[] = '';
}
// loading from a specific namespace?
if (strpos($presenter, '::') !== false)
{
$split = explode('::', $presenter, 2);
if (isset($split[1]))
{
array_unshift($prefixes, ucfirst($split[0]).'\\'.static::$ns_prefix);
$presenter = $split[1];
}
}
// if no custom view is given, make it equal to the presenter name
is_null($view) and $view = $presenter;
// strip any extensions from the view name to determine the presenter to load
$presenter = \Inflector::words_to_upper(str_replace(
array('/', DS),
'_',
strpos($presenter, '.') === false ? $presenter : substr($presenter, 0, -strlen(strrchr($presenter, '.')))
));
// create the list of possible presenter classnames, start with the namespaced one
$classes = array();
foreach ($prefixes as $prefix)
{
$classes[] = $prefix.$presenter;
}
// check if we can find one
foreach ($classes as $class)
{
if (class_exists($class))
{
return new $class($method, $auto_filter, $view);
}
}
throw new \OutOfBoundsException('Presenter "'.reset($classes).'" could not be found.');
}
/**
* @var string method to execute when rendering
*/
protected $_method;
/**
* @var string|View view name, after instantiation a View object
*/
protected $_view;
/**
* @var bool whether or not to use auto filtering
*/
protected $_auto_filter;
/**
* @var Request active request during Presenter creation for proper context
*/
protected $_active_request;
protected function __construct($method, $auto_filter = null, $view = null)
{
$this->_auto_filter = $auto_filter;
$this->_view === null and $this->_view = $view;
class_exists('Request', false) and $this->_active_request = \Request::active();
if (empty($this->_view))
{
// Take the class name and guess the view name
$class = get_class($this);
$this->_view = strtolower(str_replace('_', DS, preg_replace('#^([a-z0-9_]*\\\\)?(View_)?#i', '', $class)));
}
$this->set_view();
$this->_method = $method;
}
/**
* Returns the View object associated with this Presenter
*
* @return View
*/
public function get_view()
{
return $this->_view;
}
/**
* Construct the View object
*/
protected function set_view()
{
$this->_view instanceOf View or $this->_view = \View::forge($this->_view);
}
/**
* Returns the active request object.
*
* @return Request
*/
protected function request()
{
return $this->_active_request;
}
/**
* Executed before the view method
*/
public function before() {}
/**
* The default view method
* Should set all expected variables upon itself
*/
public function view() {}
/**
* Executed after the view method
*/
public function after() {}
/**
* Fetches an existing value from the template
*
* @param mixed $name
* @return mixed
*/
public function & __get($name)
{
return $this->get($name);
}
/**
* Gets a variable from the template
*
* @param null $key
* @param null $default
* @return string
*/
public function & get($key = null, $default = null)
{
if (is_null($default) and func_num_args() === 1)
{
return $this->_view->get($key);
}
return $this->_view->get($key, $default);
}
/**
* Sets and sanitizes a variable on the template
*
* @param string $key
* @param mixed $value
* @return Presenter
*/
public function __set($key, $value)
{
return $this->set($key, $value);
}
/**
* Sets a variable on the template
*
* @param string $key
* @param mixed $value
* @param bool|null $filter
* @return $this
*/
public function set($key, $value = null, $filter = null)
{
is_null($filter) and $filter = $this->_auto_filter;
$this->_view->set($key, $value, $filter);
return $this;
}
/**
* The same as set(), except this defaults to not-encoding the variable
* on output.
*
* $view->set_safe('foo', 'bar');
*
* @param string $key variable name or an array of variables
* @param mixed $value value
* @return $this
*/
public function set_safe($key, $value = null)
{
return $this->set($key, $value, false);
}
/**
* Magic method, determines if a variable is set.
*
* isset($view->foo);
*
* @param string $key variable name
* @return boolean
*/
public function __isset($key)
{
return isset($this->_view->$key);
}
/**
* Magic method, unsets a given variable.
*
* unset($view->foo);
*
* @param string $key variable name
* @return void
*/
public function __unset($key)
{
unset($this->_view->$key);
}
/**
* Assigns a value by reference. The benefit of binding is that values can
* be altered without re-setting them. It is also possible to bind variables
* before they have values. Assigned values will be available as a
* variable within the view file:
*
* $this->bind('ref', $bar);
*
* @param string $key variable name
* @param mixed $value referenced variable
* @param bool $filter Whether to filter the var on output
* @return $this
*/
public function bind($key, &$value, $filter = null)
{
$this->_view->bind($key, $value, $filter);
return $this;
}
/**
* Change auto filter setting
*
* @param null|bool change setting (bool) or get the current setting (null)
* @return void|bool returns current setting or nothing when it is changed
*/
public function auto_filter($setting = null)
{
if (func_num_args() == 0)
{
return $this->_view->auto_filter();
}
return $this->_view->auto_filter($setting);
}
/**
* Add variables through method and after() and create template as a string
*/
public function render()
{
if (class_exists('Request', false))
{
$current_request = \Request::active();
\Request::active($this->_active_request);
}
$this->before();
$this->{$this->_method}();
$this->after();
$return = $this->_view->render();
if (class_exists('Request', false))
{
\Request::active($current_request);
}
return $return;
}
/**
* Auto-render on toString
*/
public function __toString()
{
try
{
return $this->render();
}
catch (\Exception $e)
{
\Errorhandler::exception_handler($e);
return '';
}
}
}