Seditio Source
Root |
./othercms/b2evolution_7.2.3/inc/templates/model/_template.class.php
<?php
/**
 * This file implements the Template class.
 *
 * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}.
 * See also {@link https://github.com/b2evolution/b2evolution}.
 *
 * @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}.
*
 * @license http://b2evolution.net/about/license.html GNU General Public License (GPL)
 *
 * @package evocore
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );

load_class( '_core/model/dataobjects/_dataobject.class.php', 'DataObject' );


/**
 * Menu Class
 *
 * @package evocore
 */
class Template extends DataObject
{
    var
$name;
    var
$code;
    var
$translates_tpl_ID;
    var
$locale;
    var
$template_code;
    var
$context;
    var
$owner_grp_ID;

   
/**
     * @var integer Translated template count
     */
   
var $count_translated_templates = NULL;

   
/**
     * @var array Localized child templates
     */
   
var $localized_templates = NULL;

   
/**
     * Constructor
     *
     * @param object table Database row
     */
   
function __construct( $db_row = NULL )
    {
       
// Call parent constructor:
       
parent::__construct( 'T_templates', 'tpl_', 'tpl_ID' );

        if(
$db_row != NULL )
        {    
// Get menu data from DB:
           
$this->ID = $db_row->tpl_ID;
           
$this->name = $db_row->tpl_name;
           
$this->code = $db_row->tpl_code;
           
$this->translates_tpl_ID = $db_row->tpl_translates_tpl_ID;
           
$this->locale = $db_row->tpl_locale;
           
$this->template_code = $db_row->tpl_template_code;
           
$this->context = $db_row->tpl_context;
           
$this->owner_grp_ID = $db_row->tpl_owner_grp_ID;
        }
    }


   
/**
     * Get delete cascade settings
     *
     * @return array
     */
   
static function get_delete_cascades()
    {
        return array(
                array(
'table' => 'T_templates', 'fk' => 'tpl_translates_tpl_ID', 'msg' => T_('%d child templates') ),
            );
    }


   
/**
     * Set param value
     *
     * @param string parameter name
     * @param mixed parameter value
     * @param boolean true to set to NULL if empty value
     * @return boolean true, if a value has been set; false if it has not changed
     */
   
function set( $parname, $parvalue, $make_null = false )
    {
        switch(
$parname )
        {
            case
'code':
               
// Store previous code value before update:
               
$this->previous_code = $this->get( 'code' );
                return
parent::set_param( $parname, 'string', $parvalue, $make_null );
        }

        return
parent::set_param( $parname, 'string', $parvalue, $make_null );
    }


   
/**
     * Load data from Request form fields.
     *
     * @return boolean true if loaded data seems valid.
     */
   
function load_from_Request()
    {
       
// Name:
       
param( 'tpl_name', 'string' );
       
param_check_not_empty( 'tpl_name', T_('Please enter a name for the template.') );
       
$this->set_from_Request( 'name' );

       
// Code:
       
param( 'tpl_code', 'string', NULL );
       
$this->set_from_Request( 'code' );

       
// Parent Menu:
       
$tpl_parent_ID = param( 'tpl_translates_tpl_ID', 'integer', NULL );
        if( isset(
$tpl_translates_tpl_ID ) && $this->has_translated_templates() )
        {
            global
$Messages;
           
$Messages->add( sprintf( T_('This template cannot become a child of another because it has %d children itself.'), $this->count_translated_templates ) );
        }
       
$this->set_from_Request( 'translates_tpl_ID' );

       
// Locale:
       
param( 'tpl_locale', 'string' );
       
$this->set_from_Request( 'locale' );

       
// Template Code:
       
param( 'tpl_template_code', 'html' );
       
param_check_not_empty( 'tpl_template_code' );
       
param_check_html( 'tpl_template_code', T_('Invalid template code content.'), '#', 'quick_template' );
       
$this->set( 'template_code', get_param( 'tpl_template_code' ) );

       
// Context:
       
param( 'tpl_context', 'string', 'custom' );
       
$this->set_from_Request( 'context' );

       
// Owner Group:
       
param( 'tpl_owner_grp_ID', 'integer', NULL );
       
param_check_not_empty( 'tpl_owner_grp_ID', T_('Please select an owner group for the template.') );
       
$this->set_from_Request( 'owner_grp_ID' );

        return !
param_errors_detected();
    }


   
/**
     * Insert object into DB based on previously recorded changes.
     *
     * @return boolean true on success
     */
   
function dbinsert()
    {
        global
$DB, $Messages;

       
$DB->begin();

        if( empty(
$this->code ) )
        {    
// No code specified, create one from name:
           
$tpl_code = param( 'tpl_name', 'string', true );
           
$tpl_code = unique_template_code( $tpl_code );
           
$this->set( 'code', $tpl_code );
        }
        else
        {
           
$original_code = $this->code;
           
$this->set( 'code', unique_template_code( $this->code ) );
            if(
$original_code != $this->code )
            {
               
$Messages->add_to_group( sprintf( T_('Template code has been changed to &laquo;%s&raquo;.'), $this->code ), 'note', T_('Warning: Template code changed:' ) );
            }
        }

       
$result = parent::dbinsert();
        if(
$result )
        {    
           
$DB->commit();
        }
        else
        {
           
$DB->rollback();
        }

        return
$result;
    }


   
/**
     * Update the DB based on previously recorded changes
     */
   
function dbupdate()
    {
        global
$DB, $Messages;

       
$DB->begin();

        if( empty(
$this->code ) )
        {    
// No code specified, create one from name:
           
$this->set( 'code', unique_template_code( $this->name, $this->ID ) );
        }
        else
        {
           
$original_code = $this->code;
           
$this->set( 'code', unique_template_code( $this->code, $this->ID ) );
            if(
$original_code != $this->code )
            {
               
$Messages->add_to_group( sprintf( T_('Template code has been changed to &laquo;%s&raquo;.'), $this->code ), 'note', T_('Warning: Template code changed:' ) );
            }
        }

       
$result = parent::dbupdate();
        if(
$result )
        {    
// If Template has been updated successfully

            // Invalidate caches where template may be used:
           
$template_code = isset( $this->previous_code ) ? $this->previous_code : $this->get( 'code' );
           
$this->invalidate_caches( $template_code );

           
// Commit changes on successful update:
           
$DB->commit();
        }
        else
        {    
// Rollback changes on failed update:
           
$DB->rollback();
        }

        return
$result;
    }


   
/**
     * Delete object from DB.
     *
     * @return boolean true on success
     */
   
function dbdelete()
    {
        global
$DB;

       
$old_template_code = $this->get( 'code' );

       
$result = parent::dbdelete();
        if(
$result )
        {    
// If Template has been deleted successfully

            // Invalidate caches where template may be used:
           
$this->invalidate_caches( $old_template_code );

           
// Commit changes on successful update:
           
$DB->commit();
        }
        else
        {    
// Rollback changes on failed update:
           
$DB->rollback();
        }
    }


   
/**
     * Invalidate caches where template may be used
     *
     * @param string Template code
     */
   
function invalidate_caches( $template_code )
    {
        global
$DB, $Messages;

       
// Invalidate pre-rendered cache of Items which use [include:...:this_template_code] or [cblock:...:this_template_code]:
       
$invalidated_items_num = $DB->query( 'DELETE T_items__prerendering
             FROM T_items__prerendering
             LEFT JOIN T_items__item ON itpr_itm_ID = post_ID
            WHERE post_content LIKE '
.$DB->quote( '%:'.$template_code.'%' ) );
        if(
$invalidated_items_num > 0 )
        {    
// Inform about invalidated cache:
           
$Messages->add_to_group( sprintf( T_('Pre-render caches have been invalidated for %d items that use this template in the %s or %s.'), $invalidated_items_num, '<code>[include:]</code>', '<code>[cblock:]</code>' ), 'note', T_('Cache invalidated:' ) );
        }

       
// BLOCK CACHE INVALIDATION:
       
BlockCache::invalidate_key( 'template_code', $template_code ); // Template has changed
       
BlockCache::invalidate_key( 'master_template', true ); // Any widget which may use Master Template must be invalidated
   
}


   
/**
     * Duplicate template
     *
     * @return boolean True if duplication was successfull, false otherwise
     */
   
function duplicate()
    {
        global
$DB;

       
$DB->begin();

       
$duplicated_template_ID = $this->ID;
       
$this->ID = 0;

       
// Fields that should not be duplicated must be included in the array below:
       
$skipped_fields = array( 'ID' );

       
// Get all fields of the duplicated menu:
       
$source_fields_SQL = new SQL( 'Get all fields of the duplicated template #'.$duplicated_template_ID );
       
$source_fields_SQL->SELECT( '*' );
       
$source_fields_SQL->FROM( 'T_templates' );
       
$source_fields_SQL->WHERE( 'tpl_ID = '.$DB->quote( $duplicated_template_ID ) );
       
$source_fields = $DB->get_row( $source_fields_SQL, ARRAY_A );

       
// Use field values of duplicated template by default:
       
foreach( $source_fields as $source_field_name => $source_field_value )
        {
           
// Cut prefix "tpl_" of each field:
           
$source_field_name = substr( $source_field_name, 4 );
            if(
in_array( $source_field_name, $skipped_fields ) )
            {
// Do not duplicate skipped fields
               
continue;
            }
            if( isset(
$this->$source_field_name ) )
            {    
// Unset current value in order to assign new below, especially to update this in array $this->dbchanges:
               
unset( $this->$source_field_name );
            }
           
$this->set( $source_field_name, $source_field_value );
        }

       
// Call this firstly to find all possible errors before inserting:
        // Also to set new values from submitted form:
       
if( ! $this->load_from_Request() )
        {    
// Error on handle new values from form:
           
$this->ID = $duplicated_template_ID;
           
$DB->rollback();
            return
false;
        }

       
// Try insert new collection in DB:
       
if( ! $this->dbinsert() )
        {    
// Error on insert collection in DB:
           
$this->ID = $duplicated_template_ID;
           
$DB->rollback();
            return
false;
        }

       
// Duplication is successful, commit all above changes:
       
$DB->commit();

       
// Commit changes in cache:
       
$TemplateCache = & get_TemplateCache();
       
$TemplateCache->add( $this );

        return
true;
    }


   
/**
     * Get name of Menu Entry
     *
     * @return string Menu Entry
     */
   
function get_name()
    {
        return
$this->get( 'name' );
    }


   
/**
     * Get localized child templates
     *
     * @param string Locale
     * @return array Array of Template objects
     */
   
function get_localized_templates( $locale )
    {
        global
$DB;

        if( ! isset(
$this->localized_templates[$locale] ) )
        {
           
$TemplateCache = & get_TemplateCache();
           
$TemplateCache->clear( true );
           
$where = 'tpl_translates_tpl_ID = '.$DB->quote( $this->ID ).' AND tpl_locale = '.$DB->quote( $locale );
           
$this->localized_templates[$locale] = $TemplateCache->load_where( $where );
        }

        return
$this->localized_templates[$locale];
    }


   
/**
     * Check if this template has at least one child
     *
     * @return boolean
     */
   
function has_translated_templates()
    {
        global
$DB;

        if(
$this->ID == 0 )
        {    
// New template has no child templates:
           
return false;
        }

        if( !isset(
$this->count_translated_templates ) )
        {
           
$SQL = new SQL( 'Check if template has child templates' );
           
$SQL->SELECT( 'COUNT( tpl_translates_tpl_ID )' );
           
$SQL->FROM( 'T_templates' );
           
$SQL->WHERE( 'tpl_translates_tpl_ID = '.$DB->quote( $this->ID ) );
           
$this->count_translated_templates = $DB->get_var( $SQL );
        }

        return (
$this->count_translated_templates > 0 );
    }
}

?>