Source for file _widget.class.php
Documentation is available at _widget.class.php
* This file implements the Widget class.
* This file is part of the evoCore framework - {@link http://evocore.net/}
* See also {@link http://sourceforge.net/projects/evocms/}.
* @copyright (c)2003-2010 by Francois PLANQUE - {@link http://fplanque.net/}
* {@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
* {@internal Below is a list of authors who have contributed to design/coding of this file: }}
* @author fplanque: Francois PLANQUE.
* @version $Id: _widget.class.php,v 1.75 2010/02/08 17:54:47 efy-yury Exp $
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
load_class( '_core/model/dataobjects/_dataobject.class.php', 'DataObject' );
* A ComponentWidget is a displayable entity that can be placed into a Container on a web page.
* @var string Type of the plugin ("core" or "plugin")
* Indicates whether the widget is enabled.
* Array of params which have been customized for this widget instance
* This is saved to the DB as a serialized string ($params)
* Array of params used during display()
* (false if this Widget is not handled by a Plugin)
* @param object data row from db
// Call parent constructor:
{ // We are creating an object here:
// Using parent:: instead of $this-> in order to fix http://forums.b2evolution.net//viewtopic.php?p=94778
parent::set( 'type', $type );
parent::set( 'code', $code );
{ // We are loading an object:
$this->ID =
$db_row->wi_ID;
$this->coll_ID =
$db_row->wi_coll_ID;
$this->type =
$db_row->wi_type;
$this->code =
$db_row->wi_code;
$this->params =
$db_row->wi_params;
$this->order =
$db_row->wi_order;
$this->enabled =
$db_row->wi_enabled;
* Get ref to Plugin handling this Widget
if( $this->type !=
'plugin' )
$this->Plugin =
& $Plugins->get_by_code( $this->code );
// Loop through all widget params:
* Should be overriden by core widgets
if( $this->type ==
'plugin' )
// Make sure Plugin is loaded:
return T_('Inactive / Uninstalled plugin');
* Get a very short desc. Used in the widget list.
* MAY be overriden by core widgets. Example: menu link widget.
* Get a clean description to display in the widget list
if( $this->type ==
'plugin' )
return '<strong>'.
$name.
'</strong> ('.
T_('Plugin').
')';
if( $name ==
$short_desc ||
empty($short_desc) )
return '<strong>'.
$name.
'</strong>';
return '<strong>'.
$short_desc.
'</strong> ('.
$name.
')';
* Should be overriden by core widgets
if( $this->type ==
'plugin' )
// Make sure Plugin is loaded:
return $this->Plugin->short_desc;
return T_('Inactive / Uninstalled plugin');
* Get definitions for editable params
* @see Plugin::GetDefaultSettings()
* @param local params like 'for_editing' => true
'widget_css_class' =>
array(
'label' =>
'<span class="dimmed">'.
T_( 'CSS Class' ).
'</span>',
'note' =>
T_( 'Replaces $wi_class$ in your skins containers.'),
'label' =>
'<span class="dimmed">'.
T_( 'DOM ID' ).
'</span>',
'note' =>
T_( 'Replaces $wi_ID$ in your skins containers.'),
if( $this->type ==
'plugin' )
// Make sure Plugin is loaded:
{ // Param array has not been loaded yet
{ // No saved param values were found:
{ // We have a value for this param:
if( isset
( $params[$parname]['defaultvalue'] ) )
{ // We ahve a default value:
return $params[$parname]['defaultvalue'] ;
* @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 )
if( isset
( $params[$parname] ) )
{ // This is a widget specific param:
// This is what'll be saved to the DB:
return $this->set_param( $parname, 'string', $parvalue, $make_null );
* @todo Document default params and default values.
* This might link to a wiki page, too.
* @param array MUST contain at least the basic display params
{ // Params have been initialized before...
// Generate widget defaults array:
$widget_defaults =
array();
foreach( $defs as $parname =>
$parmeta )
if( isset
( $parmeta['defaultvalue'] ) )
$widget_defaults[ $parname ] =
$parmeta['defaultvalue'];
$widget_defaults[ $parname ] =
NULL;
// Load DB configuration:
// Merge basic defaults < widget defaults < container params < DB params
// note: when called with skin_widget it falls back to basic defaults < widget defaults < calltime params < array()
'block_start' =>
'<div class="$wi_class$">',
'block_display_title' =>
true,
'block_title_start' =>
'<h3>',
'block_title_end' =>
'</h3>',
'link_default_class' =>
'default',
'item_selected_start' =>
'<li class="selected">',
'item_selected_end' =>
'</li>',
'item_selected_text' =>
'%s',
'grid_start' =>
'<table cellspacing="1" class="widget_grid">',
'grid_end' =>
'</table>',
'grid_colstart' =>
'<tr>',
'grid_colend' =>
'</tr>',
'grid_cellstart' =>
'<td>',
'grid_cellend' =>
'</td>',
'thumb_size' =>
'crop-80x80',
// 'thumb_size' => 'fit-160x120',
'link_selected_class' =>
'selected',
'link_type' =>
'canonic', // 'canonic' | 'context' (context will regenrate URL injecting/replacing a single filter)
'item_selected_text_start' =>
'',
'item_selected_text_end' =>
'',
'notes_start' =>
'<div class="notes">',
'tag_cloud_start' =>
'<p class="tag_cloud">',
'tag_cloud_end' =>
'</p>',
$params['block_start'] =
'<div class="debug_widget"><div class="debug_widget_name"><span class="debug_container_action"><a href="'
.
$admin_url.
'?ctrl=widgets&action=edit&wi_ID='.
$this->ID.
'">Edit</a></span>'.
$this->get_name().
'</div><div class="$wi_class$">';
$params['block_end'] =
'</div></div>';
// Customize params to the current widget:
// add additional css classes if required
$widget_css_class =
'widget_'.
$this->type.
'_'.
$this->code.
( empty( $params[ 'widget_css_class' ] ) ?
'' :
' '.
$params[ 'widget_css_class' ] );
// add custom id if required, default to generic id for validation purposes
$widget_ID =
( !empty($params[ 'widget_ID' ]) ?
$params[ 'widget_ID' ] :
'widget_'.
$this->type.
'_'.
$this->code.
'_'.
$this->ID );
$this->disp_params =
str_replace( array( '$wi_ID$', '$wi_class$' ), array( $widget_ID, $widget_css_class ), $params );
* Should be overriden by core widgets
* @todo fp> handle custom params for each widget
* @param array MUST contain at least the basic display params
$this->init_display( $params ); // just in case it hasn't been done before
// Call plugin (will return false if Plugin is not enabled):
// Plugin failed (happens when a plugin has been disabled for example):
echo
"Widget $this->type : $this->code did not provide a display() method! ";
* Wraps display in a cacheable block.
* @todo dh> I think Widgets need to provide caching, e.g.
* by returning something in cache_keys (so
* ComponentWidget::get_cache_keys() should return
* an empty list or false by default).
* fp> I don't understand what you mean.
* @param array MUST contain at least the basic display params
* @param array of extra keys to be used for cache keying
if( ! $Blog->get_setting('cache_enabled_widgets') )
{ // We do NOT want caching for this collection
{ // Instantiate BlockCache:
$Timer->resume( 'BlockCache' );
// TODO: dh> I think disp_params (after being processed in init_display) should get considered for the cache key, too.
$this->BlockCache =
new BlockCache( 'widget', $keys );
if( ! $this->BlockCache->check() )
{ // Cache miss, we have to generate:
$Timer->pause( 'BlockCache' );
// Save collected cached data if needed:
$this->BlockCache->end_collect();
$Timer->pause( 'BlockCache' );
* Maybe be overriden by some widgets, depending on what THEY depend on..
* @return array of keys this widget depends on
'wi_ID' =>
$this->ID, // Have the widget settings changed ?
'set_coll_ID' =>
$Blog->ID, // Have the settings of the blog changed ? (ex: new skin)
* Note: a container can prevent display of titles with 'block_display_title'
* This is useful for the lists in the headers
* fp> I'm not sur if this param should be overridable by widgets themselves (priority problem)
* Maybe an "auto" setting.
if( $this->disp_params['block_display_title'] &&
!empty( $title ) )
* List of collections/blogs
* @param array MUST contain at least the basic display params
{ // Load blogs of same owner
$blog_array =
$BlogCache->load_owner_blogs( $Blog->owner_user_ID, 'ID' );
{ // Load all public blogs
$blog_array =
$BlogCache->load_public( 'ID' );
// 3.3? if( $this->disp_params['list_type'] == 'list' )
// fp> TODO: init default value for $this->disp_params['list_type'] to avoid error
foreach( $blog_array as $l_blog_ID )
{ // Loop through all public blogs:
$l_Blog =
& $BlogCache->get_by_ID( $l_blog_ID );
if( $Blog &&
$l_blog_ID ==
$Blog->ID )
{ // This is the blog being displayed on this page:
$link_class =
$this->disp_params['link_selected_class'];
$link_class =
$this->disp_params['link_default_class'];;
echo
'<a href="'.
$l_Blog->gen_blogurl().
'" class="'.
$link_class.
'" title="'
.
$l_Blog->dget( 'name', 'htmlattr' ).
'">';
if( $Blog &&
$l_blog_ID ==
$Blog->ID )
{ // This is the blog being displayed on this page:
printf( $this->disp_params['item_selected_text'], $l_Blog->dget( 'shortname', 'htmlbody' ) );
-In FF3/XP with skin evoCamp, I click to drop down and it already reloads the page on the same blog.
-Missing appropriate CSS so it displays at least half nicely in most of teh default skins
foreach( $blog_array as $l_blog_ID )
{ // Loop through all public blogs:
$l_Blog = & $BlogCache->get_by_ID( $l_blog_ID );
$select_options .= '<option value="'.$l_blog_ID.'"';
if( $Blog && $l_blog_ID == $Blog->ID )
$select_options .= ' selected="selected"';
$select_options .= '>'.$l_Blog->dget( 'shortname', 'formvalue' ).'</option>'."\n";
if( !empty($select_options) )
echo '<form action="'.$baseurl.'" method="get">';
echo '<select name="blog" onchange="this.form.submit();">'.$select_options.'</select>';
echo '<noscript><input type="submit" value="'.T_('Go').'" /></noscript></form>';
* Insert object into DB based on previously recorded changes.
* @return boolean true on success
debug_die( 'Existing object cannot be inserted!' );
$order_max =
$DB->get_var(
WHERE wi_coll_ID = '.
$this->coll_ID.
'
AND wi_sco_name = '.
$DB->quote($this->sco_name), 0, 0, 'Get current max order' );
$this->set( 'order', $order_max+
1 );
* Update the DB based on previously recorded changes
// This widget has been modified, cached content depending on it should be invalidated:
* $Log: _widget.class.php,v $
* Revision 1.75 2010/02/08 17:54:47 efy-yury
* Revision 1.74 2009/12/22 08:02:11 fplanque
* Revision 1.73 2009/12/22 03:31:10 blueyed
* todo about cachable block handling
* Revision 1.72 2009/12/06 18:07:43 fplanque
* Fix simplified list widgets.
* Revision 1.71 2009/12/01 04:19:25 fplanque
* even more invalidation dimensions
* Revision 1.70 2009/12/01 03:45:37 fplanque
* multi dimensional invalidation
* Revision 1.69 2009/11/30 23:27:13 fplanque
* added a dimension to cache invalidation
* Revision 1.68 2009/11/30 23:16:24 fplanque
* basic cache invalidation is working now
* Revision 1.67 2009/11/30 04:31:38 fplanque
* BlockCache Proof Of Concept
* Revision 1.66 2009/10/03 21:00:50 tblue246
* Revision 1.65 2009/09/26 12:00:44 tblue246
* Revision 1.64 2009/09/25 07:33:15 efy-cantor
* replace get_cache to get_*cache
* Revision 1.63 2009/08/30 17:27:03 fplanque
* better NULL param handling all over the app
* Revision 1.62 2009/08/06 14:55:45 fplanque
* Revision 1.61 2009/08/03 13:19:11 tblue246
* Fixed http://forums.b2evolution.net//viewtopic.php?p=94778
* Revision 1.60 2009/07/02 21:50:13 fplanque
* commented out unfinished code
* Revision 1.59 2009/06/18 07:36:06 yabs
* bugfix : $type is already a param ;)
* Revision 1.58 2009/05/28 06:49:05 sam2kb
* Blog list widget can be either a "regular list" or a "select menu"
* See http://forums.b2evolution.net/viewtopic.php?t=18794
* Revision 1.57 2009/04/02 22:55:50 blueyed
* ComponentWidget::disp_coll_list: add 'item_text' and 'item_selected_text' params, where %s gets replaced by theshort name. ('%s' being the default)
* Revision 1.56 2009/03/15 22:48:16 fplanque
* refactoring... final step :)
* Revision 1.55 2009/03/15 20:35:18 fplanque
* Universal Item List proof of concept
* Revision 1.54 2009/03/14 03:28:00 fplanque
* Revision 1.53 2009/03/14 03:02:56 fplanque
* Moving towards an universal item list widget, step 1
* Revision 1.52 2009/03/13 02:32:07 fplanque
* Removed stupid widget_name param.
* Revision 1.51 2009/03/13 00:54:38 fplanque
* calling it "sidebar links"
* Revision 1.50 2009/03/08 23:57:46 fplanque
* Revision 1.49 2009/03/04 01:19:41 fplanque
* Revision 1.48 2009/02/25 17:18:03 waltercruz
* Linkroll stuff, take #2
* Revision 1.47 2009/02/23 08:14:16 yabs
* Added check for excerpts
* Revision 1.46 2009/02/22 23:40:09 fplanque
* Revision 1.45 2009/02/22 14:42:03 waltercruz
* A basic implementation that merges disp_cat_item_list2(links) and disp_cat_item_list(linkblog). Will delete disp_cat_item_list2 as soon fplanque says that the merge it's ok
* Revision 1.44 2009/02/22 14:15:48 waltercruz
* Revision 1.43 2009/02/21 22:22:23 fplanque
* Revision 1.42 2009/02/07 11:09:00 yabs
* extra settings for linkblog
* Revision 1.41 2009/02/05 21:33:34 tblue246
* Allow the user to enable/disable widgets.
* * Fix CSS for the widget state bullet @ JS widget UI.
* * Maybe find a better solution than modifying get_Cache() to get only enabled widgets... :/
* * Buffer JS requests when toggling the state of a widget??
* Revision 1.40 2009/01/24 00:43:25 waltercruz
* Revision 1.39 2009/01/24 00:29:27 waltercruz
* Implementing links in the blog itself, not in a linkblog, first attempt
* Revision 1.38 2008/09/24 08:44:12 fplanque
* Fixed and normalized order params for widgets (Comments not done yet)
* Revision 1.37 2008/09/23 09:04:33 fplanque
* moved media index to a widget
* Revision 1.36 2008/06/30 20:46:05 blueyed
* Revision 1.35 2008/04/24 02:01:04 fplanque
* Revision 1.34 2008/02/08 22:24:46 fplanque
* Revision 1.33 2008/01/21 09:35:36 fplanque
* Revision 1.32 2008/01/19 14:17:27 yabs
* bugfix : http://forums.b2evolution.net/viewtopic.php?t=13868
* Revision 1.31 2008/01/12 18:21:50 blueyed
* - use $timestamp_min, $timestamp_max for ItemListLight instances (fixes displaying of posts from the future in coll_post_list widget
* - typo, todo, fix indent