diff options
Diffstat (limited to 'framework/zii/widgets/CDetailView.php')
| -rw-r--r-- | framework/zii/widgets/CDetailView.php | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/framework/zii/widgets/CDetailView.php b/framework/zii/widgets/CDetailView.php new file mode 100644 index 0000000..5cfb74d --- /dev/null +++ b/framework/zii/widgets/CDetailView.php @@ -0,0 +1,242 @@ +<?php +/** + * CDetailView class file. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.yiiframework.com/ + * @copyright Copyright © 2008-2011 Yii Software LLC + * @license http://www.yiiframework.com/license/ + */ + +/** + * CDetailView displays the detail of a single data model. + * + * CDetailView is best used for displaying a model in a regular format (e.g. each model attribute + * is displayed as a row in a table.) The model can be either an instance of {@link CModel} + * or an associative array. + * + * CDetailView uses the {@link attributes} property to determines which model attributes + * should be displayed and how they should be formatted. + * + * A typical usage of CDetailView is as follows: + * <pre> + * $this->widget('zii.widgets.CDetailView', array( + * 'data'=>$model, + * 'attributes'=>array( + * 'title', // title attribute (in plain text) + * 'owner.name', // an attribute of the related object "owner" + * 'description:html', // description attribute in HTML + * array( // related city displayed as a link + * 'label'=>'City', + * 'type'=>'raw', + * 'value'=>CHtml::link(CHtml::encode($model->city->name), + * array('city/view','id'=>$model->city->id)), + * ), + * ), + * )); + * </pre> + * + * @property CFormatter $formatter The formatter instance. Defaults to the 'format' application component. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id: CDetailView.php 3427 2011-10-25 00:03:52Z alexander.makarow $ + * @package zii.widgets + * @since 1.1 + */ +class CDetailView extends CWidget +{ + private $_formatter; + + /** + * @var mixed the data model whose details are to be displayed. This can be either a {@link CModel} instance + * (e.g. a {@link CActiveRecord} object or a {@link CFormModel} object) or an associative array. + */ + public $data; + /** + * @var array a list of attributes to be displayed in the detail view. Each array element + * represents the specification for displaying one particular attribute. + * + * An attribute can be specified as a string in the format of "Name:Type:Label". + * Both "Type" and "Label" are optional. + * + * "Name" refers to the attribute name. It can be either a property (e.g. "title") or a sub-property (e.g. "owner.username"). + * + * "Label" represents the label for the attribute display. If it is not given, "Name" will be used to generate the appropriate label. + * + * "Type" represents the type of the attribute. It determines how the attribute value should be formatted and displayed. + * It is defaulted to be 'text'. + * "Type" should be recognizable by the {@link formatter}. In particular, if "Type" is "xyz", then the "formatXyz" method + * of {@link formatter} will be invoked to format the attribute value for display. By default when {@link CFormatter} is used, + * these "Type" values are valid: raw, text, ntext, html, date, time, datetime, boolean, number, email, image, url. + * For more details about these types, please refer to {@link CFormatter}. + * + * An attribute can also be specified in terms of an array with the following elements: + * <ul> + * <li>label: the label associated with the attribute. If this is not specified, the following "name" element + * will be used to generate an appropriate label.</li> + * <li>name: the name of the attribute. This can be either a property or a sub-property of the model. + * If the below "value" element is specified, this will be ignored.</li> + * <li>value: the value to be displayed. If this is not specified, the above "name" element will be used + * to retrieve the corresponding attribute value for display. Note that this value will be formatted according + * to the "type" option as described below.</li> + * <li>type: the type of the attribute that determines how the attribute value would be formatted. + * Please see above for possible values. + * <li>cssClass: the CSS class to be used for this item. This option is available since version 1.1.3.</li> + * <li>template: the template used to render the attribute. If this is not specified, {@link itemTemplate} + * will be used instead. For more details on how to set this option, please refer to {@link itemTemplate}. + * This option is available since version 1.1.1.</li> + * <li>visible: whether the attribute is visible. If set to <code>false</code>, the table row for the attribute will not be rendered. + * This option is available since version 1.1.5.</li> + * </ul> + */ + public $attributes; + /** + * @var string the text to be displayed when an attribute value is null. Defaults to "Not set". + */ + public $nullDisplay; + /** + * @var string the name of the tag for rendering the detail view. Defaults to 'table'. + * @see itemTemplate + */ + public $tagName='table'; + /** + * @var string the template used to render a single attribute. Defaults to a table row. + * These tokens are recognized: "{class}", "{label}" and "{value}". They will be replaced + * with the CSS class name for the item, the label and the attribute value, respectively. + * @see itemCssClass + */ + public $itemTemplate="<tr class=\"{class}\"><th>{label}</th><td>{value}</td></tr>\n"; + /** + * @var array the CSS class names for the items displaying attribute values. If multiple CSS class names are given, + * they will be assigned to the items sequentially and repeatedly. + * Defaults to <code>array('odd', 'even')</code>. + */ + public $itemCssClass=array('odd','even'); + /** + * @var array the HTML options used for {@link tagName} + */ + public $htmlOptions=array('class'=>'detail-view'); + /** + * @var string the base script URL for all detail view resources (e.g. javascript, CSS file, images). + * Defaults to null, meaning using the integrated detail view resources (which are published as assets). + */ + public $baseScriptUrl; + /** + * @var string the URL of the CSS file used by this detail view. Defaults to null, meaning using the integrated + * CSS file. If this is set false, you are responsible to explicitly include the necessary CSS file in your page. + */ + public $cssFile; + + /** + * Initializes the detail view. + * This method will initialize required property values. + */ + public function init() + { + if($this->data===null) + throw new CException(Yii::t('zii','Please specify the "data" property.')); + if($this->attributes===null) + { + if($this->data instanceof CModel) + $this->attributes=$this->data->attributeNames(); + else if(is_array($this->data)) + $this->attributes=array_keys($this->data); + else + throw new CException(Yii::t('zii','Please specify the "attributes" property.')); + } + if($this->nullDisplay===null) + $this->nullDisplay='<span class="null">'.Yii::t('zii','Not set').'</span>'; + $this->htmlOptions['id']=$this->getId(); + + if($this->baseScriptUrl===null) + $this->baseScriptUrl=Yii::app()->getAssetManager()->publish(Yii::getPathOfAlias('zii.widgets.assets')).'/detailview'; + + if($this->cssFile!==false) + { + if($this->cssFile===null) + $this->cssFile=$this->baseScriptUrl.'/styles.css'; + Yii::app()->getClientScript()->registerCssFile($this->cssFile); + } + } + + /** + * Renders the detail view. + * This is the main entry of the whole detail view rendering. + */ + public function run() + { + $formatter=$this->getFormatter(); + echo CHtml::openTag($this->tagName,$this->htmlOptions); + + $i=0; + $n=is_array($this->itemCssClass) ? count($this->itemCssClass) : 0; + + foreach($this->attributes as $attribute) + { + if(is_string($attribute)) + { + if(!preg_match('/^([\w\.]+)(:(\w*))?(:(.*))?$/',$attribute,$matches)) + throw new CException(Yii::t('zii','The attribute must be specified in the format of "Name:Type:Label", where "Type" and "Label" are optional.')); + $attribute=array( + 'name'=>$matches[1], + 'type'=>isset($matches[3]) ? $matches[3] : 'text', + ); + if(isset($matches[5])) + $attribute['label']=$matches[5]; + } + + if(isset($attribute['visible']) && !$attribute['visible']) + continue; + + $tr=array('{label}'=>'', '{class}'=>$n ? $this->itemCssClass[$i%$n] : ''); + if(isset($attribute['cssClass'])) + $tr['{class}']=$attribute['cssClass'].' '.($n ? $tr['{class}'] : ''); + + if(isset($attribute['label'])) + $tr['{label}']=$attribute['label']; + else if(isset($attribute['name'])) + { + if($this->data instanceof CModel) + $tr['{label}']=$this->data->getAttributeLabel($attribute['name']); + else + $tr['{label}']=ucwords(trim(strtolower(str_replace(array('-','_','.'),' ',preg_replace('/(?<![A-Z])[A-Z]/', ' \0', $attribute['name']))))); + } + + if(!isset($attribute['type'])) + $attribute['type']='text'; + if(isset($attribute['value'])) + $value=$attribute['value']; + else if(isset($attribute['name'])) + $value=CHtml::value($this->data,$attribute['name']); + else + $value=null; + + $tr['{value}']=$value===null ? $this->nullDisplay : $formatter->format($value,$attribute['type']); + + echo strtr(isset($attribute['template']) ? $attribute['template'] : $this->itemTemplate,$tr); + + $i++; + + } + + echo CHtml::closeTag($this->tagName); + } + + /** + * @return CFormatter the formatter instance. Defaults to the 'format' application component. + */ + public function getFormatter() + { + if($this->_formatter===null) + $this->_formatter=Yii::app()->format; + return $this->_formatter; + } + + /** + * @param CFormatter $value the formatter instance + */ + public function setFormatter($value) + { + $this->_formatter=$value; + } +} |
