<?php
/**
* This file implements the WidgetContainer class.
*
* This file is part of the evoCore framework - {@link http://evocore.net/}
* See also {@link http://sourceforge.net/projects/evocms/}.
*
* @copyright (c)2003-2014 by Francois Planque - {@link http://fplanque.com/}
*
* @package evocore
*
* @version $Id: _widgetcontainer.class.php 10060 2016-03-09 10:40:31Z yura $
*/
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
load_class( '_core/model/dataobjects/_dataobject.class.php', 'DataObject' );
/**
* WidgetContainer class
*
* Represents a container in a web page which may contains many widgets
*
* @package evocore
*/
class WidgetContainer extends DataObject
{
var $code;
var $skin_type;
var $name;
var $coll_ID;
var $order;
var $main;
var $item_ID;
var $Blog = NULL;
/**
* Constructor
*
* @param object data row from db
*/
function __construct( $db_row = NULL )
{
// Call parent constructor:
parent::__construct( 'T_widget__container', 'wico_', 'wico_ID' );
if( ! is_null($db_row) )
{
$this->ID = $db_row->wico_ID;
$this->code = $db_row->wico_code;
$this->skin_type = $db_row->wico_skin_type;
$this->name = $db_row->wico_name;
$this->coll_ID = $db_row->wico_coll_ID;
$this->order = $db_row->wico_order;
$this->main = $db_row->wico_main;
$this->item_ID = isset( $db_row->wico_item_ID ) ? $db_row->wico_item_ID : NULL;
}
}
/**
* Get this class db table config params
*
* @return array
*/
static function get_class_db_config()
{
static $widget_container_db_config;
if( !isset( $widget_container_db_config ) )
{
$widget_container_db_config = array_merge( parent::get_class_db_config(),
array(
'dbtablename' => 'T_widget__container',
'dbprefix' => 'wico_',
'dbIDname' => 'wico_ID',
)
);
}
return $widget_container_db_config;
}
/**
* Get delete cascade settings
*
* @return array
*/
static function get_delete_cascades()
{
return array(
array( 'table'=>'T_widget__widget', 'fk'=>'wi_wico_ID', 'msg'=>T_('%d widget in this container') ),
);
}
/**
* Insert object into DB based on previously recorded changes.
*
* @return boolean true on success
*/
function dbinsert()
{
global $DB;
if( $this->ID != 0 )
{
debug_die( 'Existing object cannot be inserted!' );
}
$DB->begin();
if( ( !isset( $this->order ) ) || ( $this->order <= 0 ) )
{ // Set the order of the container only if it was not defined explicitly
$SQL = new SQL( 'Get max order of '.( $this->get( 'coll_ID' ) == 0 ? 'shared containers' : 'containers in collection #'.$this->get( 'coll_ID' ) ) );
$SQL->SELECT( 'MAX( wico_order )' );
$SQL->FROM( 'T_widget__container' );
$SQL->WHERE( 'wico_coll_ID '.( $this->get( 'coll_ID' ) == 0 ? 'IS NULL' : '= '.$this->get( 'coll_ID' ) ) );
$this->set( 'order', $DB->get_var( $SQL ) + 1 );
}
$res = parent::dbinsert();
$DB->commit();
return $res;
}
/**
* Inserts or Updates depending on object state.
*
* @uses dbinsert()
* @uses dbupdate()
* @return boolean true on success, false on failure
*/
function dbsave()
{
global $DB;
$DB->begin();
$result = true;
// Page Container:
if( isset( $this->container_ityp_ID ) )
{ // We should create new Item automatically for selected Item Type on the form of Page Container:
$ItemTypeCache = & get_ItemTypeCache();
if( ( $widget_page_ItemType = & $ItemTypeCache->get_by_ID( $this->container_ityp_ID, false, false ) ) &&
( $widget_page_ItemType->get( 'usage' ) == 'widget-page' ) &&
( $widget_container_Blog = & $this->get_Blog() ) )
{ // Allow to create new Item only with usage "Widget Page" of Item Type:
load_class( 'items/model/_item.class.php', 'Item' );
$widget_page_Item = new Item();
$widget_page_Item->set( 'ityp_ID', $widget_page_ItemType->ID );
$widget_page_Item->set( 'title', 'Widget Page for container "'.$this->get( 'name' ).'"' );
$widget_page_Item->set( 'main_cat_ID', $widget_container_Blog->get_default_cat_ID() );
if( $widget_page_Item->dbinsert() )
{ // Update widget container with new inserted item ID:
$this->set( 'item_ID', $widget_page_Item->ID );
$result_message = sprintf( T_('New item %s has been created.'), '#'.$widget_page_Item->ID.'('.$widget_page_Item->get_title().')' );
}
else
{ // New Item cannot be createed by some reason:
$result = false;
}
}
else
{ // Wrong Item Type has been selected:
$result = false;
}
}
if( $result&& ( $result = parent::dbsave() ) )
{ // If container has been saved successfully:
$DB->commit();
if( isset( $result_message ) )
{ // Display message only after success widget container saving:
global $Messages;
$Messages->add( $result_message, 'success' );
}
}
else
{ // Rollback changes because of some error above:
$DB->rollback();
}
return $result;
}
/**
* Load data from Request form fields.
*
* @return boolean true if loaded data seems valid.
*/
function load_from_Request()
{
if( empty( $this->ID ) )
{ // For new creating container we shoud get a type from hidden field:
$container_type = param( 'container_type', 'string' );
}
else
{ // For existing container we should get current type and don't change it:
// (Only shared container may be changed to sub-container and reverse)
$container_type = $this->get_type();
}
$wico_coll_ID = param( 'wico_coll_ID', 'integer', NULL );
$this->set( 'coll_ID', ( empty( $wico_coll_ID ) ? NULL : $wico_coll_ID ), true );
switch( $container_type )
{
case 'shared':
case 'shared-sub':
// Only shared containers may be switched between main and sub:
$this->set( 'main', param( 'wico_container_type', 'string' ) == 'sub' ? '0' : '1' );
set_param( 'container_type', $this->get_type() );
// Shared container cannot be linked to any collection:
$this->set( 'coll_ID', NULL, true );
break;
case 'page':
// Page container cannot be a sub-container:
$this->set( 'main', '1' );
$container_page_type = param( 'container_page_type', 'string', NULL );
param_check_not_empty( 'container_page_type', T_('Please select page container type.') );
switch( $container_page_type )
{
case 'type':
$container_ityp_ID = param( 'container_ityp_ID', 'integer', true );
param_check_not_empty( 'container_ityp_ID', sprintf( T_('The field «%s» cannot be empty.'), T_('For a new page of type') ) );
// Set temp var to know what Item Type use on creating new Item in the WidgetContainer::dbsave():
$this->container_ityp_ID = $container_ityp_ID;
break;
case 'item':
$wico_item_ID = param( 'wico_item_ID', 'integer', true );
if( param_check_not_empty( 'wico_item_ID', sprintf( T_('The field «%s» cannot be empty.'), T_('For an existing page') ) ) )
{
$this->set_from_Request( 'item_ID' );
// Check for corrent Item:
$ItemCache = &get_ItemCache();
if( ! ( $widget_page_Item = & $ItemCache->get_by_ID( $wico_item_ID, false, false ) ) ||
$widget_page_Item->get_type_setting( 'usage' ) != 'widget-page' )
{ // Display error for unavailable item:
param_error( 'wico_item_ID', T_('Item can be used for page container only with Item Type usage "Widget Page"!') );
}
if( $widget_page_Item->get_blog_ID() != $wico_coll_ID )
{ // Display error for Item from another Collection:
param_error( 'wico_item_ID', T_('Item cannot be used from another collection!') );
}
}
break;
}
break;
}
param_string_not_empty( 'wico_name', sprintf( T_('The field «%s» cannot be empty.'), T_('Name') ) );
$this->set_from_Request( 'name' );
param_string_not_empty( 'wico_code', sprintf( T_('The field «%s» cannot be empty.'), T_('Code') ) );
param_check_regexp( 'wico_code', '#^[A-Za-z0-9\-_]{1,32}$#', sprintf( T_('The field "%s" must be from %d to %d letters, digits or signs %s.'), T_('Code'), 1, 32, '<code>_</code>, <code>-</code>' ) );
$this->set_from_Request( 'code' );
if( $this->ID == 0 )
{ // Allow to set skin type only on creating new widget container:
param( 'wico_skin_type', 'string', '' );
param_check_not_empty( 'wico_skin_type', sprintf( T_('The field «%s» cannot be empty.'), T_('Skin type') ) );
$this->set_from_Request( 'skin_type' );
}
if( $this->ID > 0 )
{ // Field "Order" is required for existing container:
param_string_not_empty( 'wico_order', sprintf( T_('The field «%s» cannot be empty.'), T_('Order') ) );
}
else
{ // Order is set automatically only if it was not defined explicitly:
param( 'wico_order', 'integer', 0 );
}
$this->set_from_Request( 'order' );
if( ! param_errors_detected() )
{ // Widget container code must be unique for collection, Check it only when no errors on the form:
if( $wico_ID = $this->dbexists( array( 'wico_code', 'wico_coll_ID', 'wico_skin_type' ), array( $this->get( 'code' ), $this->get( 'coll_ID' ), $this->get( 'skin_type' ) ) ) )
{ // We have a duplicate entry:
param_error( 'ufdf_code',
sprintf( T_('Another widget container already uses this code for this skin type. Do you want to <a %s>edit the existing widget container</a>?'),
'href="?ctrl=widgets&blog='.$this->get( 'coll_ID' ).'&action=edit_container&wico_ID='.$wico_ID.'"' ) );
}
}
return !param_errors_detected();
}
/**
* Get a member param by its name
*
* @param mixed Name of parameter
* @return mixed Value of parameter
*/
function get( $parname )
{
switch( $parname )
{
case 'type':
return $this->get_type();
default:
return parent::get( $parname );
}
}
/**
* Get the Collection object for this Widget Container
*
* @return object Collection
*/
function & get_Blog()
{
if( $this->Blog === NULL )
{ // Load collection once:
$BlogCache = & get_BlogCache();
$this->Blog = & $BlogCache->get_by_ID( $this->coll_ID, false, false );
}
return $this->Blog;
}
/**
* Get widget container type
*
* @return string Container type: 'main', 'sub', 'page', 'shared', 'shared-sub'
*/
function get_type()
{
if( $this->get( 'coll_ID' ) )
{ // Collection/skin container:
if( $this->get( 'item_ID' ) !== NULL )
{ // Page container:
return 'page';
}
elseif( $this->get( 'main' ) )
{ // Main container:
return 'main';
}
else
{ // Sub container:
return 'sub';
}
}
else
{ // Shared container for ALL collections:
if( $this->get( 'main' ) )
{ // Shared main container:
return 'shared';
}
else
{ // Shared sub-container:
return 'shared-sub';
}
}
}
/**
* Get title of container type
*
* @param string Type key: 'main', 'sub', 'page', 'shared', 'shared-sub', NULL - to use current type of this container
* @return string
*/
function get_type_title( $type = NULL )
{
if( $type === NULL )
{ // Use current type of this container:
$type = $this->get_type();
}
switch( $type )
{
case 'main':
return T_('Skin container');
case 'sub':
return $this->ID ? T_('Sub-container') : T_('New sub-container');
case 'page':
return $this->ID ? T_('Page container') : T_('New page container');
case 'shared':
return $this->ID ? T_('Shared main container') : T_('New shared main container');
case 'shared-sub':
return $this->ID ? T_('Shared sub-container') : T_('New shared sub-container');
}
}
}
?>