summaryrefslogtreecommitdiff
path: root/framework
diff options
context:
space:
mode:
Diffstat (limited to 'framework')
-rw-r--r--framework/Web/UI/THtmlWriter.php5
-rw-r--r--framework/Web/UI/WebControls/TDataSourceControl.php82
-rw-r--r--framework/Web/UI/WebControls/TDataSourceView.php173
-rw-r--r--framework/Web/UI/WebControls/TRepeatInfo.php332
-rw-r--r--framework/Web/UI/WebControls/TWebControl.php17
5 files changed, 609 insertions, 0 deletions
diff --git a/framework/Web/UI/THtmlWriter.php b/framework/Web/UI/THtmlWriter.php
index d9c0732b..abfc666c 100644
--- a/framework/Web/UI/THtmlWriter.php
+++ b/framework/Web/UI/THtmlWriter.php
@@ -177,6 +177,11 @@ class THtmlWriter extends TComponent implements ITextWriter
$this->_writer->write($str.self::CHAR_NEWLINE);
}
+ public function writeBreak()
+ {
+ $this->_writer->write('<br/>');
+ }
+
public function writeAttribute($name,$value,$encode=false)
{
$this->_writer->write(' '.$name.='"'.($encode?THttpUtility::htmlEncode($value):$value).'"');
diff --git a/framework/Web/UI/WebControls/TDataSourceControl.php b/framework/Web/UI/WebControls/TDataSourceControl.php
new file mode 100644
index 00000000..6814e872
--- /dev/null
+++ b/framework/Web/UI/WebControls/TDataSourceControl.php
@@ -0,0 +1,82 @@
+<?php
+
+interface IDataSource
+{
+ public function getView($viewName);
+ public function getViewNames();
+ public function onDataSourceChanged($param);
+}
+
+abstract class TDataSourceControl extends TControl implements IDataSource
+{
+ public function getView($viewName);
+
+ public function getViewNames()
+ {
+ return array();
+ }
+
+ protected function onDataSourceChanged($param)
+ {
+ $this->raiseEvent('DataSourceChanged',$this,$param);
+ }
+
+ public function focus()
+ {
+ throw new TNotSupportedException('datasourcecontrol_focus_unsupported');
+ }
+
+ public function getEnableTheming()
+ {
+ return false;
+ }
+
+ public function setEnableTheming($value)
+ {
+ throw new TNotSupportedException('datasourcecontrol_enabletheming_unsupported');
+ }
+
+ public function getSkinID()
+ {
+ return '';
+ }
+
+ public function setSkinID($value)
+ {
+ throw new TNotSupportedException('datasourcecontrol_skinid_unsupported');
+ }
+
+ public function getVisible()
+ {
+ return false;
+ }
+
+ public function setVisible($value)
+ {
+ throw new TNotSupportedException('datasourcecontrol_visible_unsupported');
+ }
+}
+
+class TReadOnlyDataSource extends TDataSourceControl
+{
+ private $_dataSource;
+ private $_dataMember;
+
+ public function __construct($dataSource,$dataMember)
+ {
+ if(!is_array($dataSource) && !($dataSource instanceof IDataSource) && !($dataSource instanceof Traversable))
+ throw new TInvalidDataTypeException('readonlydatasource_datasource_invalid');
+ $this->_dataSource=$dataSource;
+ $this->_dataMember=$dataMember;
+ }
+
+ public function getView($viewName)
+ {
+ if($this->_dataSource instanceof IDataSource)
+ return $this->_dataSource->getView($viewName);
+ else
+ return new TReadOnlyDataSourceView($this,$this->_dataMember,$this->_dataSource);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TDataSourceView.php b/framework/Web/UI/WebControls/TDataSourceView.php
new file mode 100644
index 00000000..e988af15
--- /dev/null
+++ b/framework/Web/UI/WebControls/TDataSourceView.php
@@ -0,0 +1,173 @@
+<?php
+
+class TDataSourceSelectParameters extends TComponent
+{
+ private $_retrieveTotalRowCount=false;
+ private $_startRowIndex=0;
+ private $_totalRowCount=0;
+ private $_maximumRows=0;
+
+ public function getStartRowIndex()
+ {
+ return $this->_startRowIndex;
+ }
+
+ public function setStartRowIndex($value)
+ {
+ if(($value=TPropertyValue::ensureInteger($value))<0)
+ $value=0;
+ $this->_startRowIndex=$value;
+ }
+
+ public function getMaximumRows()
+ {
+ return $this->_maximumRows;
+ }
+
+ public function setMaximumRows($value)
+ {
+ if(($value=TPropertyValue::ensureInteger($value))<0)
+ $value=0;
+ $this->_maximumRows=$value;
+ }
+
+ public function getRetrieveTotalRowCount()
+ {
+ return $this->_retrieveTotalRowCount;
+ }
+
+ public function setRetrieveTotalRowCount($value)
+ {
+ $this->_retrieveTotalRowCount=TPropertyValue::ensureBoolean($value);
+ }
+
+ public function getTotalRowCount()
+ {
+ return $this->_totalRowCount;
+ }
+
+ public function setTotalRowCount($value)
+ {
+ if(($value=TPropertyValue::ensureInteger($value))<0)
+ $value=0;
+ $this->_totalRowCount=$value;
+ }
+}
+
+abstract class TDataSourceView extends TComponent
+{
+ private $_owner;
+ private $_name;
+
+ public function __construct(IDataSource $owner,$viewName)
+ {
+ $this->_owner=$owner;
+ $this->_name=$viewName;
+ }
+
+ /**
+ * Performs DB selection based on specified parameters.
+ * @param ???
+ * @return Traversable
+ */
+ public function select($parameters);
+
+ /**
+ * Inserts a DB record.
+ * @param array|TMap
+ * @return integer affected rows
+ */
+ public function insert($values)
+ {
+ throw new TNotSupportedException('datasourceview_insert_unsupported');
+ }
+
+ /**
+ * Updates DB record(s) with the specified keys and new values
+ * @param array|TMap keys for specifying the records to be updated
+ * @param array|TMap new values
+ * @return integer affected rows
+ */
+ public function update($keys,$values)
+ {
+ throw new TNotSupportedException('datasourceview_update_unsupported');
+ }
+
+ /**
+ * Deletes DB row(s) with the specified keys.
+ * @param array|TMap keys for specifying the rows to be deleted
+ * @return integer affected rows
+ */
+ public function delete($keys)
+ {
+ throw new TNotSupportedException('datasourceview_delete_unsupported');
+ }
+
+ public function getCanDelete()
+ {
+ return false;
+ }
+
+ public function getCanInsert()
+ {
+ return false;
+ }
+
+ public function getCanPage()
+ {
+ return false;
+ }
+
+ public function getCanGetRowCount()
+ {
+ return false;
+ }
+
+ public function getCanSort()
+ {
+ return false;
+ }
+
+ public function getCanUpdate()
+ {
+ return false;
+ }
+
+ public function getName()
+ {
+ return $this->_name;
+ }
+
+ public function getDataSource()
+ {
+ return $this->_owner;
+ }
+
+ protected function onDataSourceViewChanged($param)
+ {
+ $this->raiseEvent('DataSourceViewChanged',$this,$param);
+ }
+}
+
+class TReadOnlyDataSourceView extends TDataSourceView
+{
+ private $_dataSource=null;
+
+ public function __construct(IDataSource $owner,$viewName,$dataSource)
+ {
+ parent::__construct($owner,$viewName);
+ if($dataSource===null || is_array($dataSource))
+ $this->_dataSource=new TMap($dataSource);
+ else if($dataSource instanceof Traversable)
+ $this->_dataSource=$dataSource;
+ else
+ throw new TInvalidDataTypeException('readonlydatasourceview_datasource_invalid');
+ }
+
+ public function select($parameters)
+ {
+ return $this->_dataSource;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TRepeatInfo.php b/framework/Web/UI/WebControls/TRepeatInfo.php
new file mode 100644
index 00000000..414f5db9
--- /dev/null
+++ b/framework/Web/UI/WebControls/TRepeatInfo.php
@@ -0,0 +1,332 @@
+<?php
+
+interface IRepeatInfoUser
+{
+ public function getItemStyle($itemType,$index);
+ public function renderItem($writer,$repeatInfo,$itemType,$index);
+ public function getHasFooter();
+ public function getHasHeader();
+ public function getHasSeparators();
+ public function getRepeatedItemCount();
+}
+
+class TRepeatInfo extends TComponent
+{
+ private $_caption='';
+ private $_captionAlign='NotSet';
+ private $_repeatColumns=0;
+ private $_repeatDirection='Vertical';
+ private $_repeatLayout='Table';
+
+ public function getCaption()
+ {
+ return $this->_caption;
+ }
+
+ public function setCaption($value)
+ {
+ $this->_caption=$value;
+ }
+
+ public function getCaptionAlign()
+ {
+ return $this->_captionAlign;
+ }
+
+ public function setCaptionAlign($value)
+ {
+ $this->_captionAlign=TPropertyValue::ensureEnum($value,array('NotSet','Top','Bottom','Left','Right'));
+ }
+
+ public function getRepeatColumns()
+ {
+ return $this->_repeatColumns;
+ }
+
+ public function setRepeatColumns($value)
+ {
+ $this->_repeatColumns=TPropertyValue::ensureInteger($value);
+ }
+
+ public function getRepeatDirection()
+ {
+ return $this->_repeatDirection;
+ }
+
+ public function setRepeatDirection($value)
+ {
+ $this->_repeatDirection=TPropertyValue::ensureEnum($value,array('Horizontal','Vertical'));
+ }
+
+ public function getRepeatLayout()
+ {
+ return $this->_repeatLayout;
+ }
+
+ public function setRepeatLayout($value)
+ {
+ $this->_repeatLayout=TPropertyValue::ensureEnum($value,array('Table','Flow'));
+ }
+
+ public function renderRepeater($writer, IRepeatInfoUser $user)
+ {
+ if($this->_repeatLayout==='Table')
+ {
+ $control=new TTable;
+ if($this->_caption!=='')
+ {
+ $control->setCaption($this->_caption);
+ $control->setCaptionAlign($this->_captionAlign);
+ }
+ }
+ else
+ $control=new TWebControl;
+ $control->setID($user->getClientID());
+ $control->copyBaseAttributes($user);
+ if($user->getHasStyle())
+ $control->getStyle()->copyFrom($user->getStyle());
+ $control->renderBeginTag($writer);
+
+ if($this->_repeatDirection==='Vertical')
+ $this->renderVerticalContents($writer,$user);
+ else
+ $this->renderHorizontalContents($writer,$user);
+
+ $control->renderEndTag();
+ }
+
+ protected function renderHorizontalContents($writer,$user)
+ {
+ $tableLayout=($this->_repeatLayout==='Table');
+ $hasSeparators=$user->getHasSeparators();
+ $itemCount=$user->getRepeatedItemCount();
+ $columns=$this->_repeatColumns===0?$itemCount:$this->_repeatColumns;
+ $totalColumns=$hasSeparators?$columns+$columns:$columns;
+ $needBreak=$columns<$itemCount;
+
+ if($user->getHasHeader())
+ $this->renderHeader($writer,$user,$tableLayout,$totalColumns,$needBreak);
+
+ // render items
+ if($tableLayout)
+ {
+ $column=0;
+ for($i=0;$i<$itemCount;++$i)
+ {
+ if($column==0)
+ $writer->renderBeginTag('tr');
+ if(($style=$user->getItemStyle('Item',$i))!==null)
+ $style->addAttributesToRender($writer);
+ $writer->renderBeginTag('td');
+ $user->renderItem($writer,$this,'Item',$i);
+ $writer->renderEndTag();
+ if($hasSeparators && $i!=$itemCount-1)
+ {
+ if(($style=$user->getItemStyle('Separator',$i))!==null)
+ $style->addAttributesToRender($writer);
+ $writer->renderBeginTag('td');
+ $user->renderItem($writer,$this,'Separator',$i);
+ $writer->renderEndTag();
+ }
+ $column++;
+ if($i==$itemCount-1)
+ {
+ $restColumns=$columns-$column;
+ if($hasSeparators)
+ $restColumns=$restColumns?$restColumns+$restColumns+1:1;
+ for($j=0;$j<$restColumns;++$j)
+ $writer->write('<td></td>');
+ }
+ if($column==$columns || $i==$itemCount-1)
+ {
+ $writer->renderEndTag();
+ $column=0;
+ }
+ }
+ }
+ else
+ {
+ $column=0;
+ for($i=0;$i<$itemCount;++$i)
+ {
+ $user->renderItem($writer,$this,'Item',$i);
+ if($hasSeparators && $i!=$itemCount-1)
+ $user->renderItem($writer,$this,'Separator',$i);
+ $column++;
+ if($column==$columns || $i==$itemCount-1)
+ {
+ if($needBreak)
+ $writer->writeBreak();
+ $column=0;
+ }
+ }
+ }
+
+ if($user->getHasFooter())
+ $this->renderFooter($writer,$user,$tableLayout,$totalColumns,$needBreak);
+ }
+
+ protected function renderVerticalContents($writer,$user)
+ {
+ $tableLayout=($this->_repeatLayout==='Table');
+ $hasSeparators=$user->getHasSeparators();
+ $itemCount=$user->getRepeatedItemCount();
+ if($this->_repeatColumns<=1)
+ {
+ $rows=$itemCount;
+ $columns=1;
+ $lastColumns=1;
+ }
+ else
+ {
+ $columns=$this->_repeatColumns;
+ $rows=(int)(($itemCount+$columns-1)/$columns);
+ if($rows==0 && $itemCount>0)
+ $rows=1;
+ if(($lastColumns=$itemCount%$columns)==0)
+ $lastColumns=$columns;
+ }
+ $totalColumns=$hasSeparators?$columns+$columns:$columns;
+
+ if($user->getHasHeader())
+ $this->renderHeader($writer,$user,$tableLayout,$totalColumns,false);
+
+ if($tableLayout)
+ {
+ $renderedItems=0;
+ for($row=0;$row<$rows;++$row)
+ {
+ $index=$row;
+ $writer->renderBeginTag('tr');
+ for($col=0;$col<$columns;++$col)
+ {
+ if($renderedItems>=$itemCount)
+ break;
+ if($col>0)
+ {
+ $index+=$rows;
+ if($col-1>=$lastColumns)
+ $index--;
+ }
+ if($index>=$itemCount)
+ continue;
+ $renderedItems++;
+ if(($style=$user->getItemStyle('Item',$index))!==null)
+ $style->addAttributesToRender($writer);
+ $writer->renderBeginTag('td');
+ $user->renderItem($writer,$this,'Item',$index);
+ $writer->renderEndTag();
+ if(!$hasSeparators)
+ continue;
+ if($renderedItems<$itemCount-1)
+ {
+ if($columns==1)
+ {
+ $writer->renderEndTag();
+ $writer->renderBeginTag('tr');
+ }
+ if(($style=$user->getItemStyle('Separator',$index))!==null)
+ $style->addAttributesToRender($writer);
+ $writer->renderBeginTag('td');
+ $user->renderItem($writer,$this,'Separator',$index);
+ $writer->renderEndTag();
+ }
+ else if($columns>1)
+ $writer->write('<td></td>');
+ }
+ if($row==$rows-1)
+ {
+ $restColumns=$columns-$lastColumns;
+ if($hasSeparators)
+ $restColumns+=$restColumns;
+ for($col=0;$col<$restColumns;++$col)
+ $writer->write('<td></td>');
+ }
+ $writer->renderEndTag();
+ }
+ }
+ else
+ {
+ $renderedItems=0;
+ for($row=0;$row<$rows;++$row)
+ {
+ $index=$row;
+ $writer->renderBeginTag('tr');
+ for($col=0;$col<$columns;++$col)
+ {
+ if($renderedItems>=$itemCount)
+ break;
+ if($col>0)
+ {
+ $index+=$rows;
+ if($col-1>=$lastColumns)
+ $index--;
+ }
+ if($index>=$itemCount)
+ continue;
+ $user->renderItem($writer,$this,'Item',$index);
+ if(!$hasSeparators)
+ continue;
+ if($renderedItems<$itemCount-1)
+ {
+ if($columns==1)
+ $writer->writeBreak();
+ $user->renderItem($writer,$this,'Separator',$index);
+ }
+ else if($columns>1)
+ $writer->write('<td></td>');
+ }
+ if($row<$rows-1 || $user->getHasFooter())
+ $writer->writeBreak();
+ }
+ }
+
+ if($user->getHasFooter())
+ $this->renderFooter($writer,$user,$tableLayout,$totalColumns,false);
+
+ }
+
+ protected function renderHeader($writer,$user,$tableLayout,$columns,$needBreak)
+ {
+ if($tableLayout)
+ {
+ $writer->renderBeginTag('tr');
+ if($columns>1)
+ $writer->addAttribute('colspan',"$columns");
+ $writer->addAttribute('scope','col');
+ if(($style=$user->getItemStyle('Header',-1))!==null)
+ $style->addAttributesToRender($writer);
+ $writer->renderBeginTag('th');
+ $user->renderItem($writer,$this,'Header',-1)
+ $writer->renderEndTag();
+ $writer->renderEndTag();
+ }
+ else
+ {
+ $user->renderItem($writer,$this,'Header',-1)
+ if($needBreak)
+ $writer->writeBreak();
+ }
+ }
+
+ protected function renderFooter($writer,$user,$tableLayout,$columns)
+ {
+ if($tableLayout)
+ {
+ $writer->renderBeginTag('tr');
+ if($columns>1)
+ $writer->addAttribute('colspan',"$columns");
+ $writer->addAttribute('scope','col');
+ if(($style=$user->getItemStyle('Header',-1))!==null)
+ $style->addAttributesToRender($writer);
+ $writer->renderBeginTag('td');
+ $user->renderItem($writer,$this,'Header',-1)
+ $writer->renderEndTag();
+ $writer->renderEndTag();
+ }
+ else
+ $user->renderItem($writer,$this,'Header',-1)
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TWebControl.php b/framework/Web/UI/WebControls/TWebControl.php
index 6e2a2c89..e86b9161 100644
--- a/framework/Web/UI/WebControls/TWebControl.php
+++ b/framework/Web/UI/WebControls/TWebControl.php
@@ -40,6 +40,23 @@ Prado::using('System.Web.UI.WebControls.TStyle');
class TWebControl extends TControl
{
/**
+ * Copies basic control attributes from another control.
+ * Properties including AccessKey, ToolTip, TabIndex, Enabled
+ * and Attributes are copied.
+ * @param TWebControl source control
+ */
+ public function copyBaseAttributes(TWebControl $control)
+ {
+ $this->setAccessKey($control->getAccessKey());
+ $this->setToolTip($control->getToolTip());
+ $this->setTabIndex($control->getTabIndex());
+ if(!$control->getEnabled())
+ $this->setEnabled(false);
+ if($control->getHasAttributes())
+ $this->getAttributes()->copyFrom($control->getAttributes());
+ }
+
+ /**
* @return string the access key of the control
*/
public function getAccessKey()