Beispiel #1
0
/**
 * Given a filename, render it as a ProcessWire template file
 * 
 * This is a shortcut to using the TemplateFile class. 
 * 
 * File is assumed relative to /site/templates/ (or a directory within there) unless you specify a full path. 
 * If you specify a full path, it will accept files in or below site/templates/, site/modules/, wire/modules/.
 * 
 * Note this function returns the output for you to output wherever you want (delayed output).
 * For direct output, use the wireInclude() function instead. 
 * 
 * @param string $filename Assumed relative to /site/templates/ unless you provide a full path name with the filename.
 * 	If you provide a path, it must resolve somewhere in site/templates/, site/modules/ or wire/modules/.
 * @param array $vars Optional associative array of variables to send to template file. 
 * 	Please note that all template files automatically receive all API variables already (you don't have to provide them)
 * @param array $options Associative array of options to modify behavior: 
 * 	- defaultPath: Path where files are assumed to be when only filename or relative filename is specified (default=/site/templates/)
 *  - autoExtension: Extension to assume when no ext in filename, make blank for no auto assumption (default=php) 
 * 	- allowedPaths: Array of paths that are allowed (default is templates, core modules and site modules)
 * 	- allowDotDot: Allow use of ".." in paths? (default=false)
 * 	- throwExceptions: Throw exceptions when fatal error occurs? (default=true)
 * @return string|bool Rendered template file or boolean false on fatal error (and throwExceptions disabled)
 * @throws WireException if template file doesn't exist
 * 
 */
function wireRenderFile($filename, array $vars = array(), array $options = array())
{
    $paths = wire('config')->paths;
    $defaults = array('defaultPath' => $paths->templates, 'autoExtension' => 'php', 'allowedPaths' => array($paths->templates, $paths->adminTemplates, $paths->modules, $paths->siteModules), 'allowDotDot' => false, 'throwExceptions' => true);
    $options = array_merge($defaults, $options);
    if (DIRECTORY_SEPARATOR != '/') {
        $filename = str_replace(DIRECTORY_SEPARATOR, '/', $filename);
    }
    // add .php extension if filename doesn't already have an extension
    if ($options['autoExtension'] && !strrpos(basename($filename), '.')) {
        $filename .= "." . $options['autoExtension'];
    }
    if (!$options['allowDotDot'] && strpos($filename, '..')) {
        // make path relative to /site/templates/ if filename is not an absolute path
        $error = 'Filename may not have ".."';
        if ($options['throwExceptions']) {
            throw new WireException($error);
        }
        wire()->error($error);
        return false;
    }
    if ($options['defaultPath'] && strpos($filename, './') === 0) {
        $filename = rtrim($options['defaultPath'], '/') . '/' . substr($filename, 2);
    } else {
        if ($options['defaultPath'] && strpos($filename, '/') !== 0) {
            // filename is relative to defaultPath (typically /site/templates/)
            $filename = rtrim($options['defaultPath'], '/') . '/' . $filename;
        } else {
            if (strpos($filename, '/') !== false) {
                // filename is absolute, make sure it's in a location we consider safe
                $allowed = false;
                foreach ($options['allowedPaths'] as $path) {
                    if (strpos($filename, $path) === 0) {
                        $allowed = true;
                    }
                }
                if (!$allowed) {
                    $error = "Filename {$filename} is not in an allowed path.";
                    if ($options['throwExceptions']) {
                        throw new WireException($error);
                    }
                    wire()->error($error);
                    return false;
                }
            }
        }
    }
    // render file and return output
    $t = new TemplateFile();
    $t->setThrowExceptions($options['throwExceptions']);
    $t->setFilename($filename);
    foreach ($vars as $key => $value) {
        $t->set($key, $value);
    }
    return $t->render();
}
 /**
  * Get the output TemplateFile object for rendering this page
  *
  * You can retrieve the results of this by calling $page->out or $page->output
  *
  * @internal This method is intended for internal use only, not part of the public API. 
  * @param bool $forceNew Forces it to return a new (non-cached) TemplateFile object (default=false)
  * @return TemplateFile
  *
  */
 public function output($forceNew = false)
 {
     if ($this->output && !$forceNew) {
         return $this->output;
     }
     if (!$this->template) {
         return null;
     }
     $this->output = new TemplateFile();
     $this->output->setThrowExceptions(false);
     $this->output->setFilename($this->template->filename);
     $fuel = self::getAllFuel();
     $this->output->set('wire', $fuel);
     foreach ($fuel as $key => $value) {
         $this->output->set($key, $value);
     }
     $this->output->set('page', $this);
     return $this->output;
 }