From 348fb25264f6cc9251f5ae9cb8c7a8a1013e2d67 Mon Sep 17 00:00:00 2001 From: xue <> Date: Wed, 13 Sep 2006 12:37:23 +0000 Subject: Merge from 3.0 branch till 1409. --- framework/Web/THttpResponse.php | 10 +- framework/Web/UI/TTemplateManager.php | 109 +++++++++++++++-- framework/Web/UI/WebControls/TLiteralColumn.php | 154 ++++++++++++++++++++++++ 3 files changed, 262 insertions(+), 11 deletions(-) create mode 100644 framework/Web/UI/WebControls/TLiteralColumn.php (limited to 'framework/Web') diff --git a/framework/Web/THttpResponse.php b/framework/Web/THttpResponse.php index 90d2c0ef..ad935103 100644 --- a/framework/Web/THttpResponse.php +++ b/framework/Web/THttpResponse.php @@ -32,13 +32,15 @@ Prado::using('System.Web.THttpResponseAdapter'); * By default, THttpResponse is registered with {@link TApplication} as the * response module. It can be accessed via {@link TApplication::getResponse()}. * - * THttpRequest may be configured in application configuration file as follows + * THttpResponse may be configured in application configuration file as follows + * * + * * where {@link getCacheExpire CacheExpire}, {@link getCacheControl CacheControl} - * and {@link getBufferOutput BufferOutput} are configurable properties of THttpResponse. + * and {@link getBufferOutput BufferOutput} are optional properties of THttpResponse. * - * When sending headers the Charset set in {@link TGlobalization::getCharset()} - * is use when Charset is null or empty in THttpResponse. + * THttpResponse sends charset header if either {@link setCharset() Charset} + * or {@link TGlobalization::setCharset() TGlobalization.Charset} is set. * * @author Qiang Xue * @version $Id$ diff --git a/framework/Web/UI/TTemplateManager.php b/framework/Web/UI/TTemplateManager.php index 58afed3c..8c4983bf 100644 --- a/framework/Web/UI/TTemplateManager.php +++ b/framework/Web/UI/TTemplateManager.php @@ -85,12 +85,28 @@ class TTemplateManager extends TModule $array=$cache->get(self::TEMPLATE_CACHE_PREFIX.$fileName); if(is_array($array)) { - list($template,$timestamp)=$array; - if(filemtime($fileName)<$timestamp) + list($template,$timestamps)=$array; + if($this->getApplication()->getMode()===TApplicationMode::Performance) + return $template; + $cacheValid=true; + foreach($timestamps as $tplFile=>$timestamp) + { + if(!is_file($tplFile) || filemtime($tplFile)>$timestamp) + { + $cacheValid=false; + break; + } + } + if($cacheValid) return $template; } $template=new TTemplate(file_get_contents($fileName),dirname($fileName),$fileName); - $cache->set(self::TEMPLATE_CACHE_PREFIX.$fileName,array($template,time())); + $includedFiles=$template->getIncludedFiles(); + $timestamps=array(); + $timestamps[$fileName]=filemtime($fileName); + foreach($includedFiles as $includedFile) + $timestamps[$includedFile]=filemtime($includedFile); + $cache->set(self::TEMPLATE_CACHE_PREFIX.$fileName,array($template,$timestamps)); return $template; } } @@ -206,6 +222,9 @@ class TTemplate extends TApplicationComponent implements ITemplate */ private $_hashCode=''; private $_tplControl=null; + private $_includedFiles=array(); + private $_includeAtLine=array(); + private $_includeLines=array(); /** @@ -540,6 +559,7 @@ class TTemplate extends TApplicationComponent implements ITemplate */ protected function parse($input) { + $input=$this->preprocess($input); $tpl=&$this->_tpl; $n=preg_match_all(self::REGEX_RULES,$input,$matches,PREG_SET_ORDER|PREG_OFFSET_CAPTURE); $expectPropEnd=false; @@ -732,10 +752,7 @@ class TTemplate extends TApplicationComponent implements ITemplate $line=$this->_startingLine+1; else $line=$this->_startingLine+count(explode("\n",substr($input,0,$matchEnd+1))); - if(empty($this->_tplFile)) - throw new TConfigurationException('template_format_invalid2',$line,$e->getMessage(),$input); - else - throw new TConfigurationException('template_format_invalid',$this->_tplFile,$line,$e->getMessage()); + $this->handleException($e,$line,$input); } if($this->_directive===null) @@ -949,6 +966,84 @@ class TTemplate extends TApplicationComponent implements ITemplate else throw new TConfigurationException('template_component_required',$type); } + + /** + * @return array list of included external template files + */ + public function getIncludedFiles() + { + return $this->_includedFiles; + } + + /** + * Handles template parsing exception. + * This method rethrows the exception caught during template parsing. + * It adjusts the error location by giving out correct error line number and source file. + * @param Exception template exception + * @param int line number + * @param string template string if no source file is used + */ + protected function handleException($e,$line,$input=null) + { + $srcFile=$this->_tplFile; + if(($n=count($this->_includedFiles))>0) // need to adjust error row number and file name + { + for($i=$n-1;$i>=0;--$i) + { + if($this->_includeAtLine[$i]<=$line) + { + if($line<$this->_includeAtLine[$i]+$this->_includeLines[$i]) + { + $line=$line-$this->_includeAtLine[$i]+1; + $srcFile=$this->_includedFiles[$i]; + break; + } + else + $line=$line-$this->_includeLines[$i]+1; + } + } + } + if(empty($srcFile)) + throw new TConfigurationException('template_format_invalid2',$line,$e->getMessage(),$input); + else + throw new TConfigurationException('template_format_invalid',$srcFile,$line,$e->getMessage()); + } + + /** + * Preprocesses the template string by including external templates + * @param string template string + * @return string expanded template string + */ + protected function preprocess($input) + { + if($n=preg_match_all('/<%include(.*?)%>/',$input,$matches,PREG_SET_ORDER|PREG_OFFSET_CAPTURE)) + { + for($i=0;$i<$n;++$i) + { + $filePath=Prado::getPathOfNamespace(trim($matches[$i][1][0]),TTemplateManager::TEMPLATE_FILE_EXT); + if($filePath!==null && is_file($filePath)) + $this->_includedFiles[]=$filePath; + else + { + $errorLine=count(explode("\n",substr($input,0,$matches[$i][0][1]+1))); + $this->handleException(new TConfigurationException('template_include_invalid',trim($matches[$i][1][0])),$errorLine,$input); + } + } + $base=0; + for($i=0;$i<$n;++$i) + { + $ext=file_get_contents($this->_includedFiles[$i]); + $length=strlen($matches[$i][0][0]); + $offset=$base+$matches[$i][0][1]; + $this->_includeAtLine[$i]=count(explode("\n",substr($input,0,$offset))); + $this->_includeLines[$i]=count(explode("\n",$ext)); + $input=substr_replace($input,$ext,$offset,$length); + $base+=strlen($ext)-$length; + } + } + + return $input; + } } ?> diff --git a/framework/Web/UI/WebControls/TLiteralColumn.php b/framework/Web/UI/WebControls/TLiteralColumn.php new file mode 100644 index 00000000..e78c4e6d --- /dev/null +++ b/framework/Web/UI/WebControls/TLiteralColumn.php @@ -0,0 +1,154 @@ + + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id: TLiteralColumn.php 1397 2006-09-07 07:55:53Z wei $ + * @package System.Web.UI.WebControls + */ + +/** + * TDataGridColumn class file + */ +Prado::using('System.Web.UI.WebControls.TDataGridColumn'); + +/** + * TLiteralColumn class + * + * TLiteralColumn represents a static text column that is bound to a field in a data source. + * The cells in the column will be displayed with static texts using the data indexed by + * {@link setDataField DataField}. You can customize the display by + * setting {@link setDataFormatString DataFormatString}. + * + * If {@link setDataField DataField} is not specified, the cells will be filled + * with {@link setText Text}. + * + * If {@link setEncode Encode} is true, the static texts will be HTML-encoded. + * + * @author Qiang Xue + * @version $Id: TLiteralColumn.php 1397 2006-09-07 07:55:53Z wei $ + * @package System.Web.UI.WebControls + * @since 3.0.5 + */ +class TLiteralColumn extends TDataGridColumn +{ + /** + * @return string the field name from the data source to bind to the column + */ + public function getDataField() + { + return $this->getViewState('DataField',''); + } + + /** + * @param string the field name from the data source to bind to the column + */ + public function setDataField($value) + { + $this->setViewState('DataField',$value,''); + } + + /** + * @return string the formatting string used to control how the bound data will be displayed. + */ + public function getDataFormatString() + { + return $this->getViewState('DataFormatString',''); + } + + /** + * @param string the formatting string used to control how the bound data will be displayed. + */ + public function setDataFormatString($value) + { + $this->setViewState('DataFormatString',$value,''); + } + + /** + * @return string static text to be displayed in the column. Defaults to empty. + */ + public function getText() + { + return $this->getViewState('Text',''); + } + + /** + * @param string static text to be displayed in the column. + */ + public function setText($value) + { + $this->setViewState('Text',$value,''); + } + + /** + * @return boolean whether the rendered text should be HTML-encoded. Defaults to false. + */ + public function getEncode() + { + return $this->getViewState('Encode',false); + } + + /** + * @param boolean whether the rendered text should be HTML-encoded. + */ + public function setEncode($value) + { + $this->setViewState('Encode',TPropertyValue::ensureBoolean($value),false); + } + + /** + * Initializes the specified cell to its initial values. + * This method overrides the parent implementation. + * @param TTableCell the cell to be initialized. + * @param integer the index to the Columns property that the cell resides in. + * @param string the type of cell (Header,Footer,Item,AlternatingItem,EditItem,SelectedItem) + */ + public function initializeCell($cell,$columnIndex,$itemType) + { + parent::initializeCell($cell,$columnIndex,$itemType); + if($itemType===TListItemType::Item || $itemType===TListItemType::AlternatingItem || $itemType===TListItemType::EditItem || $itemType===TListItemType::SelectedItem) + { + if($this->getDataField()!=='') + $cell->attachEventHandler('OnDataBinding',array($this,'dataBindColumn')); + else + { + if(($dataField=$this->getDataField())!=='') + $control->attachEventHandler('OnDataBinding',array($this,'dataBindColumn')); + else + { + $text=$this->getText(); + if($this->getEncode()) + $text=THttpUtility::htmlEncode($text); + $cell->setText($text); + } + } + } + } + + /** + * Databinds a cell in the column. + * This method is invoked when datagrid performs databinding. + * It populates the content of the cell with the relevant data from data source. + */ + public function dataBindColumn($sender,$param) + { + $item=$sender->getNamingContainer(); + $data=$item->getDataItem(); + $formatString=$this->getDataFormatString(); + if(($field=$this->getDataField())!=='') + $value=$this->formatDataValue($formatString,$this->getDataFieldValue($data,$field)); + else + $value=$this->formatDataValue($formatString,$data); + if($sender instanceof TTableCell) + { + if($this->getEncode()) + $value=THttpUtility::htmlEncode($value); + $sender->setText($value); + } + } +} + +?> \ No newline at end of file -- cgit v1.2.3