Guest User

Untitled

a guest
Dec 26th, 2013
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 10.54 KB | None | 0 0
  1. <?php
  2.  
  3. namespace Delicious;
  4.  
  5. /**
  6.  * This class provides the template rendering functions.
  7.  *
  8.  * @author Michael
  9.  * @copyright (c) 2013, Michael Beers | Online Media en Design
  10.  * @link http://michaelbeers.nl
  11.  * @since 1.0
  12.  */
  13. class View {
  14.  
  15.     private $_module = '';
  16.     private $_controller = '';
  17.     private $_action = '';
  18.     private $_theme = null; // The theme name.
  19.     private $_layout = false; // The layout where the body should be wrapped in.
  20.     private $_title = '';
  21.     private $_titleSeparator = ' - ';
  22.     private $_metadata = array();
  23.     private $_scripts = array();
  24.     private $_partials = array();
  25.     private $_breadcrumbs = array();
  26.     private $_cacheLifetime = 0;
  27.     private $_data = array();
  28.     private $_output = null;
  29.  
  30.     /**
  31.      * Constructor.
  32.      */
  33.     public function __construct(array $config) {
  34.         $this->_titleSeparator = $config['title_separator'];
  35.         $this->_theme = $config['theme'];
  36.         $this->_cacheLifetime = $config['cache_lifetime'];
  37.  
  38.         // Setup module, controller and action.
  39.         $mc = explode("\\Controller\\", Dispatch::$_controller);
  40.         $this->_module = $mc[0];
  41.         $this->_controller = $mc[1];
  42.         $this->_action = Dispatch::$_action;
  43.     }
  44.  
  45.     /**
  46.      * Magic get function for getting view data.
  47.      *
  48.      * @param string $name
  49.      * @return mixed
  50.      */
  51.     public function __get($name) {
  52.         return $this->_data[$name];
  53.     }
  54.  
  55.     /**
  56.      * Magic set function for setting view data.
  57.      *
  58.      * @param string $name
  59.      * @param mixed $value
  60.      */
  61.     public function __set($name, $value) {
  62.         $this->_data[$name] = $value;
  63.     }
  64.  
  65.     /**
  66.      * Magic function for rendering the view data.
  67.      */
  68.     public function __toString() {
  69.         $view = strtolower($this->_controller) . '-' . strtolower($this->_action);
  70.         return $this->render($view, array(), true);
  71.     }
  72.  
  73.     // ----------------------------------------------------------------------
  74.  
  75.     /**
  76.      * Render the HTML output.
  77.      *
  78.      * @param string $view
  79.      * @param array $data
  80.      * @param boolean $return
  81.      */
  82.     public function render($view, array $data = array(), $return = false) {
  83.         // Merge all the given data to use it in all view files.
  84.         is_array($data) || $data = (array) $data;
  85.         $this->_data = array_merge($this->_data, $data);
  86.  
  87.         // Check if the data is cached or not.
  88.         if ($this->_cacheLifetime > 0 && $this->_inCache($view)) {
  89.             // The template is cached so it will loaded from the cache.
  90.             $this->_output = $this->_loadCachedView($view);
  91.         } else {
  92.             // The template is not cached so it will be loaded by searching.
  93.             if (empty($this->_title)) {
  94.                 // Guess the title whether its empty.
  95.                 $this->_title = $this->_guessTitle();
  96.             }
  97.  
  98.             // Setup the default template variable.
  99.             $template = array();
  100.             $template['title'] = $this->_title;
  101.             $template['breadcrumbs'] = $this->_breadcrumbs;
  102.             $template['metadata'] = implode("\n\t\t", $this->_metadata) . "\n";
  103.             $template['scripts'] = implode("\n\t\t", $this->_scripts) . "\n";
  104.             $template['partials'] = array();
  105.  
  106.             $this->_data['template'] = &$template; // Make an reference for later updates.
  107.             // Load all partial data.
  108.             foreach ($this->_partials as $name => $partial) {
  109.                 // Fix data array.
  110.                 is_array($partial['data']) || $partial['data'] = (array) $partial['data'];
  111.  
  112.                 if (isset($partial['view'])) {
  113.                     $template['partials'][$name] = $this->_loadView($partial['view'], $partial['data']);
  114.                 } else {
  115.                     $template['partials'][$name] = $partial['string'];
  116.                 }
  117.             }
  118.  
  119.             // Load basic view.
  120.             $this->_output = $this->_loadView($view, array());
  121.  
  122.             // Wrap the output into a template file.
  123.             // Cache the view?
  124.             if ($this->_cacheLifetime > 0) {
  125.                 $this->_setCache($view, $this->_output);
  126.             }
  127.         }
  128.  
  129.         // Return or print the output.
  130.         if (!$return) {
  131.             print $this->_output;
  132.             return;
  133.         }
  134.  
  135.         return $this->_output;
  136.     }
  137.  
  138.     // ----------------------------------------------------------------------
  139.  
  140.     /**
  141.      * Set the page title.
  142.      *
  143.      * @param string Each parameter will be a segment.
  144.      */
  145.     public function setTitle() {
  146.         if ($segments = func_get_args()) {
  147.             $this->_title = implode($this->_titleSeparator, $segments);
  148.         } else {
  149.             $this->_title = $this->_guessTitle();
  150.         }
  151.     }
  152.  
  153.     /**
  154.      * Guess the title based on the module, controller and action.
  155.      *
  156.      * @return string
  157.      */
  158.     private function _guessTitle() {
  159.         $title_parts = array();
  160.  
  161.         // Check whether the action isn't the default index.
  162.         if ($this->_action != 'index') {
  163.             $title_parts[] = $this->_action;
  164.         }
  165.  
  166.         // Make sure the controller name does not exists as title part.
  167.         if (!in_array($this->_controller, $title_parts)) {
  168.             $title_parts[] = $this->_controller;
  169.         }
  170.  
  171.         // Make sure the module name does not exists as title part.
  172.         if (!in_array($this->_module, $title_parts)) {
  173.             $title_parts[] = $this->_module;
  174.         }
  175.  
  176.         $title = humanize(implode($this->_titleSeparator, $title_parts));
  177.         return $title;
  178.     }
  179.  
  180.     // ----------------------------------------------------------------------
  181.    
  182.     /**
  183.      * Add new breadcrumb to the page.
  184.      *
  185.      * @param type $name
  186.      * @param type $url
  187.      */
  188.     public function addBreadcrumb($name, $url = '') {
  189.         $this->_breadcrumbs[] = array('name' => $name, 'url' => $url);
  190.     }
  191.  
  192.     /**
  193.      * Add new metadata to the page.
  194.      *
  195.      * @param string $name Name of the metadata.
  196.      * @param string $content Content of the metadata.
  197.      * @param string $type Metadata type (meta, link or charset).
  198.      */
  199.     public function addMeta($name, $content, $type = 'meta') {
  200.         $name = h(strip_tags($name));
  201.         $content = h(strip_tags($content));
  202.  
  203.         // Fix for keywords.
  204.         if ($name === 'keywords' && !strpos($content, ', ')) {
  205.             $content = preg_replace('/[\s]+/', ', ', trim($content));
  206.         }
  207.  
  208.         // Fix for html5 charset
  209.         if ($name === 'charset') {
  210.             $type = 'charset';
  211.         }
  212.  
  213.         switch ($type) {
  214.             case 'meta':
  215.                 $this->_metadata[$name] = '<meta name="' . $name . '" content="' . $content .
  216.                         '" />';
  217.                 break;
  218.             case 'link':
  219.                 $this->_metadata[$content] = '<link rel="' . $name . '" href="' . $content .
  220.                         '" />';
  221.                 break;
  222.             case 'charset':
  223.                 $this->_metadata[$name] = '<meta charset="' . $content . '" />';
  224.                 break;
  225.         }
  226.     }
  227.  
  228.     /**
  229.      * Add new script to the page.
  230.      *
  231.      * @param string $name Name of the script.
  232.      * @param string $url Url of the script.
  233.      */
  234.     public function addScript($name, $url, $type = 'text/javascript') {
  235.         $this->_scripts[$name] = '<script type="' . $type . '" src="' . $url . '"></script>';
  236.     }
  237.  
  238.     // ----------------------------------------------------------------------
  239.  
  240.     /**
  241.      * Return cache id.
  242.      *
  243.      * @param string $view
  244.      * @return string
  245.      */
  246.     private function _getCacheId($view) {
  247.         $parts = array(
  248.             strtolower($this->_module),
  249.             strtolower($this->_controller),
  250.             strtolower($this->_action),
  251.             $view
  252.         );
  253.  
  254.         return md5(implode('-', $parts));
  255.     }
  256.  
  257.     /**
  258.      * Return whether the view is already in the cache or not.
  259.      *
  260.      * @param string $view
  261.      * @return boolean
  262.      */
  263.     private function _inCache($view) {
  264.         $id = $this->_getCacheId($view);
  265.         $filename = PUBLIC_PATH . 'data' . DS . 'cache' . DS . $id . '.cache';
  266.  
  267.         if (is_file($filename)) {
  268.             clearstatcache();
  269.  
  270.             if (filemtime($filename) > (time() - $this->_cacheLifetime)) {
  271.                 $isCached = true;
  272.             }
  273.         }
  274.  
  275.         return isset($isCached) ? true : false;
  276.     }
  277.  
  278.     /**
  279.      * Sets a file to the cache.
  280.      *
  281.      * @param string $view
  282.      * @param mixed $content
  283.      */
  284.     private function _setCache($view, $content) {
  285.         $id = $this->_getCacheId($view);
  286.         $filename = PUBLIC_PATH . 'data' . DS . 'cache' . DS . $id . '.cache';
  287.         $directory = PUBLIC_PATH . 'data' . DS . 'cache' . DS;
  288.  
  289.         // Make directory if not exists.
  290.         @mkdir($directory, 0775);
  291.  
  292.         // Write the content to the cache.
  293.         if ($fp = fopen($filename, 'wb')) {
  294.             fwrite($fp, $content);
  295.             fclose($fp);
  296.         }
  297.     }
  298.  
  299.     /**
  300.      * Return a cached view.
  301.      *
  302.      * @param string $view
  303.      * @return mixed
  304.      */
  305.     private function _loadCachedView($view) {
  306.         $id = $this->_getCacheId($view);
  307.         $filename = PUBLIC_PATH . 'data' . DS . 'cache' . DS . $id . '.cache';
  308.  
  309.         if ($fp = fopen($filename, 'rb')) {
  310.             $output = fread($fp, filesize($filename));
  311.             fclose($fp);
  312.         }
  313.  
  314.         return isset($output) ? $output : false;
  315.     }
  316.  
  317.     /**
  318.      * Return a normal view.
  319.      *
  320.      * @param string $view
  321.      * @param array $data
  322.      * @param string $override_path
  323.      * @return mixed
  324.      */
  325.     private function _loadView($view, array $data = array(), $override_path = false) {
  326.         $path = PACKAGE_PATH . ucfirst($this->_module) . DS . 'View' . DS . $view . EXT;
  327.  
  328.         // Override the default path.
  329.         if ($override_path) {
  330.             $path = $override_path . $view . EXT;
  331.         }
  332.  
  333.         // Check if the file exists.
  334.         if (!file_exists($path)) {
  335.             $output = 'Error loading view "' . $view . '" in "' . ucfirst($this->_module) . DS . 'View' . '".';
  336.             log_message($output);
  337.             return $output;
  338.         }
  339.  
  340.         // Start rendering (gzip compression supported)
  341.         if (ob_start("ob_gzhandler") === false) {
  342.             ob_start();
  343.         }
  344.  
  345.         extract($this->_data);
  346.         require ($path);
  347.         $output = ob_get_clean();
  348.         // End rendering...
  349.  
  350.         return $output;
  351.     }
  352.  
  353. }
Advertisement
Add Comment
Please, Sign In to add comment