Seditio Source
Root |
./othercms/ips_4.3.4/system/Theme/Cache/Template.php
<?php
/**
 * @brief        Magic Template Class for cachable templates
 * @author        <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
 * @copyright    (c) Invision Power Services, Inc.
 * @license        https://www.invisioncommunity.com/legal/standards/
 * @package        Invision Community
 * @since        06 Aug 2013
 */

namespace IPS\Theme\Cache;

/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
   
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
    exit;
}

/**
 * Magic Template Class for cachable templates
 */
class _Template extends \IPS\Theme\Template
{
   
/**
     * @brief    Source File
     */
   
protected static $file = NULL;
   
   
/**
     * @brief    Template object
     */
   
protected static $object = NULL;
   
   
/**
     * @brief    Theme object
     */
   
protected static $theme = NULL;
   
   
/**
     * @brief    Class name
     */
   
protected static $className = NULL;
   
   
/**
     * Constructor
     *
     * @param    string    $app                Application Key
     * @param    string    $templateLocation    Template location (admin/public/etc.)
     * @param    string    $templateName        Template Name
     * @return    void
     */
   
public function __construct( $app, $templateLocation, $templateName )
    {
       
parent::__construct( $app, $templateLocation, $templateName );
       
        static::
$theme = \IPS\Theme::$memberTheme;
       
        if ( ! static::
$theme->cache_key )
         {
             
/* This theme has never received a cache key, so lets create one now */
             
static::$theme->resetCacheKey();
         }
         
        static::
$className = 'class_' . $app . '_' . $templateLocation . '_' . $templateName;
       
$key = \strtolower( 'template_' . static::$theme->id . '_' . \IPS\Theme::makeBuiltTemplateLookupHash( $app, $templateLocation, $templateName ) . '_' . \IPS\Theme::cleanGroupName( $templateName ) );
       
        static::
$file = \IPS\Settings::i()->theme_disk_cache_path . "/" . $key . ".php";
    }
   
   
/**
     * Does this template bit exist
     * This checks that it exists and also that the theme key matches
     *
     * @return boolean
     */
   
public function exists()
    {
        if (
file_exists( static::$file ) )
        {
           
/* For FLOCK to work when setting, we need to flock when reading https://bugs.php.net/bug.php?id=52895 */
           
$f = fopen( static::$file, 'r' );
           
flock( $f, LOCK_SH );
            include_once( static::
$file );
           
flock( $f, LOCK_UN );
           
fclose( $f );        
           
           
$class = "\\IPS\\Theme\\Cache\\" . \IPS\Theme::overloadHooks( static::$className, "IPS\\Theme\\Cache" );

            if (
class_exists( $class ) )
            {
                static::
$object = new $class( $this->app, $this->templateLocation, $this->templateName );

                if ( static::
$theme->cache_key != static::$object->cache_key )
                {
                    @
unlink( static::$file );
                   
                   
/* Clear zend opcache if enabled */
                   
if ( function_exists( 'opcache_invalidate' ) )
                    {
                        @
opcache_invalidate( static::$file );
                    }
                   
                    static::
$object = NULL;
       
                    return
false;
                }
               
                return
true;
            }
        }
         
        return
false;
    }
     
     
/**
     * Return the template object
     *
     * @throws \UnderflowException if the template bit does not exist
     * @return boolean
     */
   
public function get()
    {
        if ( ! static::
$object and ! $this->exists() )
        {
            throw new \
UnderflowException;
        }
       
        return static::
$object;
    }
     
     
/**
     * Write the template object
     * @param    string    $template    PHP $template data to write
     *
     * @throws \RuntimeException If the template bit cannot be written
     * @return void
     */
     
public function set( $template )
     {
        if ( !
is_writable( \IPS\Settings::i()->theme_disk_cache_path ) )
        {
            throw new \
RuntimeException;
        }
       
       
$template = "<?php\n" . $template;
       
$result = (bool) @\file_put_contents( static::$file, $template, LOCK_EX );

       
/* Sometimes LOCK_EX is unavailable and throws file_put_contents(): Exclusive locks are not supported for this stream.
            While we would prefer an exclusive lock, it would be better to write the file if possible. */
       
if( ! $result )
        {
            @
unlink( static::$file );
           
$result = (bool) @\file_put_contents( static::$file, $template );
        }
       
       
/* Clear zend opcache if enabled */
       
if ( function_exists( 'opcache_invalidate' ) )
        {
            @
opcache_invalidate( static::$file );
        }
    }
}