File size: 7.96Kb
<?php
/**
* CWidget class file.
*
* @author Qiang Xue <[email protected]>
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* CWidget is the base class for widgets.
*
* A widget is a self-contained component that may generate presentation
* based on model data. It can be viewed as a micro-controller that embeds
* into the controller-managed views.
*
* Compared with {@link CController controller}, a widget has neither actions nor filters.
*
* Usage is described at {@link CBaseController} and {@link CBaseController::widget}.
*
* @property CBaseController $owner Owner/creator of this widget. It could be either a widget or a controller.
* @property string $id Id of the widget.
* @property CController $controller The controller that this widget belongs to.
* @property string $viewPath The directory containing the view files for this widget.
*
* @author Qiang Xue <[email protected]>
* @package system.web.widgets
* @since 1.0
*/
class CWidget extends CBaseController
{
/**
* @var string the prefix to the IDs of the {@link actions}.
* When a widget is declared an action provider in {@link CController::actions},
* a prefix can be specified to differentiate its action IDs from others.
* The same prefix should then also be used to configure this property
* when the widget is used in a view of the controller.
*/
public $actionPrefix;
/**
* @var mixed the name of the skin to be used by this widget. Defaults to 'default'.
* If this is set as false, no skin will be applied to this widget.
* @see CWidgetFactory
* @since 1.1
*/
public $skin='default';
/**
* @var array view paths for different types of widgets
*/
private static $_viewPaths;
/**
* @var integer the counter for generating implicit IDs.
*/
private static $_counter=0;
/**
* @var string id of the widget.
*/
private $_id;
/**
* @var CBaseController owner/creator of this widget. It could be either a widget or a controller.
*/
private $_owner;
/**
* Returns a list of actions that are used by this widget.
* The structure of this method's return value is similar to
* that returned by {@link CController::actions}.
*
* When a widget uses several actions, you can declare these actions using
* this method. The widget will then become an action provider, and the actions
* can be easily imported into a controller.
*
* Note, when creating URLs referring to the actions listed in this method,
* make sure the action IDs are prefixed with {@link actionPrefix}.
*
* @return array
*
* @see actionPrefix
* @see CController::actions
*/
public static function actions()
{
return array();
}
/**
* Constructor.
* @param CBaseController $owner owner/creator of this widget. It could be either a widget or a controller.
*/
public function __construct($owner=null)
{
$this->_owner=$owner===null?Yii::app()->getController():$owner;
}
/**
* Returns the owner/creator of this widget.
* @return CBaseController owner/creator of this widget. It could be either a widget or a controller.
*/
public function getOwner()
{
return $this->_owner;
}
/**
* Returns the ID of the widget or generates a new one if requested.
* @param boolean $autoGenerate whether to generate an ID if it is not set previously
* @return string id of the widget.
*/
public function getId($autoGenerate=true)
{
if($this->_id!==null)
return $this->_id;
elseif($autoGenerate)
return $this->_id='yw'.self::$_counter++;
}
/**
* Sets the ID of the widget.
* @param string $value id of the widget.
*/
public function setId($value)
{
$this->_id=$value;
}
/**
* Returns the controller that this widget belongs to.
* @return CController the controller that this widget belongs to.
*/
public function getController()
{
if($this->_owner instanceof CController)
return $this->_owner;
else
return Yii::app()->getController();
}
/**
* Initializes the widget.
* This method is called by {@link CBaseController::createWidget}
* and {@link CBaseController::beginWidget} after the widget's
* properties have been initialized.
*/
public function init()
{
}
/**
* Executes the widget.
* This method is called by {@link CBaseController::endWidget}.
*/
public function run()
{
}
/**
* Returns the directory containing the view files for this widget.
* The default implementation returns the 'views' subdirectory of the directory containing the widget class file.
* If $checkTheme is set true, the directory "ThemeID/views/ClassName" will be returned when it exists.
* @param boolean $checkTheme whether to check if the theme contains a view path for the widget.
* @return string the directory containing the view files for this widget.
*/
public function getViewPath($checkTheme=false)
{
$className=get_class($this);
if(isset(self::$_viewPaths[$className]))
return self::$_viewPaths[$className];
else
{
if($checkTheme && ($theme=Yii::app()->getTheme())!==null)
{
$path=$theme->getViewPath().DIRECTORY_SEPARATOR;
if(strpos($className,'\\')!==false) // namespaced class
$path.=str_replace('\\','_',ltrim($className,'\\'));
else
$path.=$className;
if(is_dir($path))
return self::$_viewPaths[$className]=$path;
}
$class=new ReflectionClass($className);
return self::$_viewPaths[$className]=dirname($class->getFileName()).DIRECTORY_SEPARATOR.'views';
}
}
/**
* Looks for the view script file according to the view name.
* This method will look for the view under the widget's {@link getViewPath viewPath}.
* The view script file is named as "ViewName.php". A localized view file
* may be returned if internationalization is needed. See {@link CApplication::findLocalizedFile}
* for more details.
* The view name can also refer to a path alias if it contains dot characters.
* @param string $viewName name of the view (without file extension)
* @return string the view file path. False if the view file does not exist
* @see CApplication::findLocalizedFile
*/
public function getViewFile($viewName)
{
if(($renderer=Yii::app()->getViewRenderer())!==null)
$extension=$renderer->fileExtension;
else
$extension='.php';
if(strpos($viewName,'.')) // a path alias
$viewFile=Yii::getPathOfAlias($viewName);
else
{
$viewFile=$this->getViewPath(true).DIRECTORY_SEPARATOR.$viewName;
if(is_file($viewFile.$extension))
return Yii::app()->findLocalizedFile($viewFile.$extension);
elseif($extension!=='.php' && is_file($viewFile.'.php'))
return Yii::app()->findLocalizedFile($viewFile.'.php');
$viewFile=$this->getViewPath(false).DIRECTORY_SEPARATOR.$viewName;
}
if(is_file($viewFile.$extension))
return Yii::app()->findLocalizedFile($viewFile.$extension);
elseif($extension!=='.php' && is_file($viewFile.'.php'))
return Yii::app()->findLocalizedFile($viewFile.'.php');
else
return false;
}
/**
* Renders a view.
*
* The named view refers to a PHP script (resolved via {@link getViewFile})
* that is included by this method. If $data is an associative array,
* it will be extracted as PHP variables and made available to the script.
*
* @param string $view name of the view to be rendered. See {@link getViewFile} for details
* about how the view script is resolved.
* @param array $data data to be extracted into PHP variables and made available to the view script
* @param boolean $return whether the rendering result should be returned instead of being displayed to end users
* @return string the rendering result. Null if the rendering result is not required.
* @throws CException if the view does not exist
* @see getViewFile
*/
public function render($view,$data=null,$return=false)
{
if(($viewFile=$this->getViewFile($view))!==false)
return $this->renderFile($viewFile,$data,$return);
else
throw new CException(Yii::t('yii','{widget} cannot find the view "{view}".',
array('{widget}'=>get_class($this), '{view}'=>$view)));
}
}