diff options
Diffstat (limited to 'framework/Web')
-rw-r--r-- | framework/Web/THttpResponse.php | 10 | ||||
-rw-r--r-- | framework/Web/UI/TTemplateManager.php | 109 | ||||
-rw-r--r-- | framework/Web/UI/WebControls/TLiteralColumn.php | 154 |
3 files changed, 262 insertions, 11 deletions
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
+ *
* <module id="response" CacheExpire="20" CacheControl="nocache" BufferOutput="true" />
+ *
* 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 <qiang.xue@gmail.com>
* @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 @@ +<?php
+/**
+ * TLiteralColumn class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @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 <qiang.xue@gmail.com>
+ * @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 |