Subversion Repositories PHPX

Rev

Rev 64 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

1
<?php

namespace PointedEars\PHPX;

/**
 * A general view handled by a controller according to the MVC pattern
 *
 * @author Thomas 'PointedEars' Lahn &lt;php@PointedEars.de>
 */

class View
{
  /**
   * Default template resource path
   *
   * @var string
   */

  protected $_template = '';

  /**
   * Content that can be inserted in the template
   *
   * @var string
   */

  protected $_content = '';

  /**
   * Template variables.  The variable name serves as item key, the item's value
   * is the variable value.
   *
   * @var array
   */

  protected $_template_vars = array();

  /**
   * Stylesheets to be inserted into the <code>head</code> element
   *
   * @var array
   */

  protected $_stylesheets = array();

  /**
   * Scripts to be inserted into the <code>head</code> or
   * <code>body</code> element
   *
   * @var array
   */

  protected $_scripts = array();

  /**
   * Creates a new view
   *
   * @param string $template
   *   Template resource path
   */

  public function __construct ($template)
  {
    $this->_template = $template;
  }

  /**
   * Magic setter method used for defining template variables
   *
   * @param string $name
   *   Variable name
   * @param mixed $value
   *   Variable value
   */

  public function __set ($name, $value)
  {
    $this->_template_vars[$name] = $value;
  }

  /**
   * Magic getter method used for retrieving values of template variables
   *
   * @param string $name
   *   Variable name
   */

  public function __get ($name)
  {
    return $this->_template_vars[$name];
  }

  /**
   * Returns <var>$v</var> with occurences of '&' (ampersand), '"' (double quote),
   * "'" (single quote), '<' (less than), and '>' (greater than) replaced by their
   * HTML character entity references, if any, or their numeric HTML character
   * reference (as required primarily in HTML for attribute values and element
   * content).
   *
   * @param mixed $value
   */

  public function escape ($value)
  {
    if (is_array($value))
    {
      return array_map(array('self', 'escape'), $value);
    }
    else if (is_object($value))
    {
      if ($value instanceof AbstractModel)
      {
        foreach ($value->getPropertyVars() as $varName)
        {
          $value->$varName = self::escape($value->$varName);
        }
      }

      return $value;
    }
    else
    {
      if (is_string($value))
      {
        $encoding = mb_detect_encoding($value);
        if ($encoding === 'ASCII')
        {
          $encoding = 'ISO-8859-1';
        }
        return htmlspecialchars($value, ENT_QUOTES, $encoding);
      }

      return $value;
    }
  }

  /**
   * Assigns a value to a template variable
   *
   * @param string $name
   *   Variable name
   * @param mixed $value
   *   Variable value
   * @param bool $escape
   *   If <code>true</code>, replace all potentially conflicting characters
   *   in <var>$value</var> with their HTML entity references.  The default is
   *   <code>false</code>.
   * @return mixed The assigned value (after possible HTML encoding)
   * @see View::escape()
   */

  public function assign ($name, $value, $escape = false)
  {
    if ($escape)
    {
      $value = $this->escape($value);
    }

    $this->$name = $value;
    return $value;
  }

  /**
   * Adds a CSS resource (stylesheet) to the list of external
   * stylesheets
   *
   * @param string $uri
   *   Stylesheet URI
   * @param mixed $key (optional)
   *   Array key for the script.  May be used later to exclude
   *   or include the code for a specific stylesheet.
   */

  public function addStylesheet ($uri, $key = null)
  {
    $stylesheets =& $this->_stylesheets;

    if ($key !== null)
    {
      $stylesheets[$key] = $uri;
    }
    else
    {
      $stylesheets[] = $uri;
    }
  }

  /**
   * Adds an ECMAScript resource (script) to the list of external
   * scripts
   *
   * @param string $uri
   *   Script URI
   * @param mixed $key (optional)
   *   Array key for the script.  May be used later to exclude
   *   or include the code for a specific script.
   */

  public function addScript ($uri, $key = null)
  {
    $scripts =& $this->_scripts;

    if ($key !== null)
    {
      $scripts[$key] = $uri;
    }
    else
    {
      $scripts[] = $uri;
    }
  }

  /**
   * Renders the view by including a template
   *
   * @param string $template
   *   Optional alternative template resource path.
   *   If not provided, the default template ($template property) will be used.
   * @throws Exception if no template has been defined before
   */

  public function render ($template = null, $content = null)
  {
        if (!is_null($content))
    {
      ob_start();
        require_once $content;
        $this->_content = ob_get_contents();
      ob_end_clean();
    }

        if (!is_null($template))
        {
                require $template;
        }
    elseif ($this->_template)
    {
      require $this->_template;
    }
    else
    {
      throw new \Exception('No template defined');
    }
  }

  /**
   * Returns the code for including all stylesheets,
   * with exclusions.
   *
   * @param array $exclusions (optional, future)
   *   The keys of the stylesheets that should be excluded
   * @return string
   */

  public function getStylesheets ($exclusions = array())
  {
    return (
      implode(PHP_EOL, array_map(function ($uri) {
        return '<link rel="stylesheet" href="' . $this->escape($uri) . '">';
      }, array_diff_key($this->_stylesheets, array_flip($exclusions))))
      . PHP_EOL);
  }

  /**
   * Returns the code for including a specific stylesheet
   *
   * @param mixed $key
   * @return string
   */

  public function getStylesheet ($key)
  {
    return '<link rel="stylesheet" href="'
      . $this->escape($this->_stylesheets[$key])
      . '">' . PHP_EOL;
  }

  /**
   * Returns the code for including all stylesheets,
   * with exclusions.
   *
   * @param array $exclusions (optional, future)
   *   The keys of the scripts that should be excluded.
   *   Usually you would specify those scripts that you
   *   want to include with {@link #getScript()}.
   * @return string
   */

  public function getScripts ($exclusions = array())
  {
    return (
     implode(PHP_EOL, array_map(function ($uri) {
        return '<script type="text/javascript" src="'
          . $this->escape($uri)
          . '"></script>';
      }, array_diff_key($this->_scripts, array_flip($exclusions))))
      . PHP_EOL);
  }

  public function getScript ($key)
  {
    return '<link rel="stylesheet" href="'
      . $this->escape($this->_scripts[$key])
      . '">' . PHP_EOL;
  }

  /**
   * Returns the content for insertion into the template
   */

  public function getContent ()
  {
    return $this->_content;
  }

  /**
   * @param string[optional] $controller
   * @param string[optional] $action
   * @param int[optional] $id
   * @see Application::getURL()
   */

  public function getURL ($controller = null, $action = null, $id = null)
  {
    return Application::getInstance()->getURL($controller, $action, $id);
  }
}

?>