<?php
/**
* This file implements the subcontainer Widget class, and it is used to embed a widget container into a widget
*
* This file is part of the evoCore framework - {@link http://evocore.net/}
* See also {@link http://sourceforge.net/projects/evocms/}.
*
* @copyright (c)2003-2016 by Francois Planque - {@link http://fplanque.com/}
*
* {@internal License choice
* - If you have received this file as part of a package, please find the license.txt file in
* the same folder or the closest folder above for complete license terms.
* - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
* then you must choose one of the following licenses before using the file:
* - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
* - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
* }}
*
* @package evocore
*
* {@internal Below is a list of authors who have contributed to design/coding of this file: }}
* @author asimo: Evo Factory / Attila Simo
*/
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
load_class( 'widgets/model/_widget.class.php', 'ComponentWidget' );
/**
* ComponentWidget Class
*
* A ComponentWidget is a displayable entity that can be placed into a Container on a web page.
*
* @package evocore
*/
class subcontainer_Widget extends ComponentWidget
{
var $icon = 'cube';
/**
* Constructor
*/
function __construct( $db_row = NULL )
{
// Call parent constructor:
parent::__construct( $db_row, 'core', 'subcontainer' );
}
/**
* Get help URL
*
* @return string URL
*/
function get_help_url()
{
return get_manual_url( 'embed-sub-container-widget' );
}
/**
* Get name of widget
*/
function get_name()
{
return T_('Sub-Container');
}
/**
* Get a very short desc. Used in the widget list.
*/
function get_short_desc()
{
return format_to_output( $this->disp_params['title'] );
}
/**
* Get short description
*/
function get_desc()
{
return T_('Allows to re-use a block of widgets in several places.');
}
/**
* Get definitions for editable params
*
* @param $params
*/
function get_param_definitions( $params )
{
$WidgetContainerCache = & get_WidgetContainerCache();
$r = array_merge( array(
'title' => array(
'label' => T_('Block title'),
'size' => 60,
),
'container' => array(
'label' => T_('Sub-Container'),
'note' => T_('All widgets from this Sub-Container will be displayed.'),
'type' => 'select',
'options' => $WidgetContainerCache->get_subcontainers_option_array( $this->get_container_param( 'skin_type' ) ),
'defaultvalue' => ''
),
), parent::get_param_definitions( $params ) );
if( isset( $r['allow_blockcache'] ) )
{ // Disable "allow blockcache"
$r['allow_blockcache']['defaultvalue'] = false;
$r['allow_blockcache']['disabled'] = 'disabled';
$r['allow_blockcache']['note'] = T_('This widget cannot be cached in the block cache.');
}
return $r;
}
/**
* Update the DB based on previously recorded changes
*/
function dbupdate()
{
global $DB;
$DB->begin();
$result = true;
if( $this->get_param( 'container' ) == '!create_new' )
{ // This is a request to create new sub-container:
$new_container_code = $this->create_auto_subcontainer();
if( $new_container_code === false )
{ // Stop updating if new container cannot be created:
$result = false;
}
else
{ // Use new created sub-container for this updating widget:
$this->set( 'container', $new_container_code );
}
}
// Do update only if all requested sub-containers have been created successfully:
$result = $result && parent::dbupdate();
if( $result )
{
$DB->commit();
}
else
{
$DB->rollback();
}
return $result;
}
/**
* Display the widget!
*
* @param array MUST contain at least the basic display params
*/
function display( $params )
{
global $Blog, $Timer, $displayed_subcontainers, $Session;
// Get container type "coll"/"shared" and real container code from stored value:
$code_data = explode( ':', $this->disp_params['container'], 2 );
if( count( $code_data ) != 2 || ! in_array( $code_data[0], array( 'coll', 'shared' ) ) )
{ // Invalid container code:
$this->display_error_message( 'Widget "'.$this->get_name().'" has a wrong container code "'.$this->disp_params['container'].'".' );
return false;
}
$subcontainer_coll_ID = ( $code_data[0] == 'coll' ? $this->get_coll_ID() : NULL );
$subcontainer_code = $code_data[1];
if( ! isset( $displayed_subcontainers ) )
{ // Initialize the dispalyed subcontainers array at first usage:
// Use this array to avoid embedded containers display in infinite loop
$displayed_subcontainers = array();
}
elseif( in_array( $subcontainer_code, $displayed_subcontainers ) )
{ // Do not try do display the same subcontainer which were already displayed to avoid infinite display:
$WidgetContainerCache = & get_WidgetContainerCache();
if( $WidgetContainer = & $WidgetContainerCache->get_by_coll_skintype_code( $subcontainer_coll_ID, $this->get_container_param( 'skin_type' ), $subcontainer_code ) )
{
$subcontainer_name = $WidgetContainer->get( 'name' );
}
else
{
$subcontainer_name = $subcontainer_code;
}
echo '<div class="alert alert-danger">'.sprintf( T_('Cannot include container "%s" because it would create an infinite loop.'), $subcontainer_name ).'</div>';
return;
}
// Add this subcontainer to the displayed_containers array:
$displayed_subcontainers[] = $subcontainer_code;
$this->init_display( $params );
// START DISPLAY:
echo $this->disp_params['block_start'];
// Display title if requested
$this->disp_title();
echo $this->disp_params['block_body_start'];
// Get enabled widgets of the container:
$EnabledWidgetCache = & get_EnabledWidgetCache();
$container_widgets = & $EnabledWidgetCache->get_by_coll_container( $subcontainer_coll_ID, $subcontainer_code, true );
if( ! empty( $container_widgets ) )
{
if( isset( $params['override_params_for_'.$this->code] ) )
{ // Use specific widget params if they are defined for this widget by code:
$params = array_merge( $params, $params['override_params_for_'.$this->code] );
}
foreach( $container_widgets as $ComponentWidget )
{ // Let the Widget display itself (with contextual params):
$widget_timer_name = 'Widget->display('.$ComponentWidget->code.')';
$Timer->start( $widget_timer_name );
// Clear the display params in order to use new custom if they are defined for this widget from skin side by param "override_params_for_subcontainer_row":
// (otherwise the params will be used from first initialized widget container by $subcontainer_code)
$ComponentWidget->disp_params = NULL;
$ComponentWidget->display_with_cache( $params );
$Timer->pause( $widget_timer_name );
}
}
elseif( is_logged_in() && $Session->get( 'designer_mode_'.$Blog->ID ) )
{ // Display text for empty container on designer mode:
echo '<div class="red">'.T_('Empty Sub-Container').'</div>';
}
echo $this->disp_params['block_body_end'];
echo $this->disp_params['block_end'];
// Remove the last item which must be this container from the end of the displayed containers:
array_pop( $displayed_subcontainers );
return true;
}
/**
* Get Sub-Container
*
* @return object|false
*/
function & get_sub_WidgetContainer()
{
// Get container type "coll"/"shared" and real container code from stored value:
$code_data = explode( ':', $this->get_param( 'container' ), 2 );
if( count( $code_data ) != 2 || ! in_array( $code_data[0], array( 'coll', 'shared' ) ) )
{ // Invalid container code:
$r = false;
return $r;
}
$subcontainer_coll_ID = ( $code_data[0] == 'coll' ? $this->get_coll_ID() : NULL );
$subcontainer_code = $code_data[1];
$WidgetContainerCache = & get_WidgetContainerCache();
$WidgetContainer = & $WidgetContainerCache->get_by_coll_skintype_code( $subcontainer_coll_ID, $this->get_container_param( 'skin_type' ), $subcontainer_code );
return $WidgetContainer;
}
}
?>