diff options
| -rw-r--r-- | framework/3rdParty/PhpShell/php-shell-init.php | 2 | ||||
| -rw-r--r-- | framework/Data/ActiveRecord/Scaffold/TScaffoldEditView.php | 11 | ||||
| -rw-r--r-- | framework/Data/ActiveRecord/Scaffold/TScaffoldListView.php | 77 | ||||
| -rw-r--r-- | framework/Data/ActiveRecord/TActiveRecord.php | 12 | ||||
| -rw-r--r-- | framework/Data/ActiveRecord/TActiveRecordCriteria.php | 5 | ||||
| -rw-r--r-- | framework/Data/ActiveRecord/TActiveRecordGateway.php | 14 | ||||
| -rw-r--r-- | framework/Data/ActiveRecord/Vendor/TDbMetaData.php | 13 | ||||
| -rw-r--r-- | framework/Data/TDbCommand.php | 6 | ||||
| -rwxr-xr-x | framework/prado-cli.php | 13 | 
9 files changed, 137 insertions, 16 deletions
| diff --git a/framework/3rdParty/PhpShell/php-shell-init.php b/framework/3rdParty/PhpShell/php-shell-init.php index e8da5a7d..20c6af75 100644 --- a/framework/3rdParty/PhpShell/php-shell-init.php +++ b/framework/3rdParty/PhpShell/php-shell-init.php @@ -69,7 +69,7 @@ function __shell_default_error_handler($errno, $errstr, $errfile, $errline, $err      throw new Exception(sprintf("%s:%d\r\n%s", $errfile, $errline, $errstr));
  }
 -set_error_handler("__shell_default_error_handler");
 +//set_error_handler("__shell_default_error_handler");
  $__shell = new PHP_Shell();
  $__shell_exts = PHP_Shell_Extensions::getInstance();
 diff --git a/framework/Data/ActiveRecord/Scaffold/TScaffoldEditView.php b/framework/Data/ActiveRecord/Scaffold/TScaffoldEditView.php index a792aeb9..14b4098a 100644 --- a/framework/Data/ActiveRecord/Scaffold/TScaffoldEditView.php +++ b/framework/Data/ActiveRecord/Scaffold/TScaffoldEditView.php @@ -17,9 +17,11 @@ Prado::using('System.Data.ActiveRecord.Scaffold.TScaffoldBase');  /**
   * Template control for editing an Active Record instance.
 + * The <b>RecordClass</b> determines the Active Record class to be edited.
 + * A particular record can be edited by specifying the {@link setRecordPk RecordPk}
 + * value (may be an array for composite keys).
   *
   * The default editor input controls are created based on the column types.
 - *
   * The editor layout can be specified by a renderer. A renderer is an external
   * template control that implements IScaffoldEditRenderer.
   *
 @@ -33,9 +35,10 @@ Prado::using('System.Data.ActiveRecord.Scaffold.TScaffoldBase');   * (the edit view instance is the <b>Parent</b> of the IScaffoldEditRenderer in most
   * cases.
   *
 - * The <b>RecordClass</b> determines the Active Record class to be edited.
 - * A particular record can be edited by specifying the {@link setRecordPk RecordPk}
 - * value (may be an array for composite keys).
 + * Cosmetic changes to the default editor should be done using Cascading Stylesheets.
 + * For example, a particular field/property can be hidden by specifying "display:none" for
 + * the corresponding style (each field/property has unique Css class name as "property_xxx", where
 + * xxx is the property name).
   *
   * @author Wei Zhuo <weizho[at]gmail[dot]com>
   * @version $Id$
 diff --git a/framework/Data/ActiveRecord/Scaffold/TScaffoldListView.php b/framework/Data/ActiveRecord/Scaffold/TScaffoldListView.php index 2ac3fe99..62bf351b 100644 --- a/framework/Data/ActiveRecord/Scaffold/TScaffoldListView.php +++ b/framework/Data/ActiveRecord/Scaffold/TScaffoldListView.php @@ -16,7 +16,15 @@  Prado::using('System.Data.ActiveRecord.Scaffold.TScaffoldBase');
  /**
 - * TScaffoldListView displays instance of Active Record class.
 + * TScaffoldListView displays a list of Active Records.
 + *
 + * The {@link getHeader Header} property is a TRepeater displaying the
 + * Active Record property/field names. The {@link getSort Sort} property
 + * is a drop down list displaying the combination of properties and its possible
 + * ordering. The {@link getPager Pager} property is a TPager control that
 + * determines the number of records display in one page (e.g. Page..
 + *
 + *
   *
   * @author Wei Zhuo <weizho[at]gmail[dot]com>
   * @version $Id$
 @@ -25,6 +33,9 @@ Prado::using('System.Data.ActiveRecord.Scaffold.TScaffoldBase');   */
  class TScaffoldListView extends TScaffoldBase
  {
 +	/**
 +	 * Initialize the sort drop down list in non post back mode (i.e. GET requests).
 +	 */
  	public function onLoad($param)
  	{
  		parent::onLoad($param);
 @@ -32,6 +43,9 @@ class TScaffoldListView extends TScaffoldBase  			$this->initializeSort();
  	}
 +	/**
 +	 * Initialize the sort drop down list and the column names repeater.
 +	 */
  	protected function initializeSort()
  	{
  		$table = $this->getTableMetaData();
 @@ -50,12 +64,18 @@ class TScaffoldListView extends TScaffoldBase  		$this->_header->dataBind();
  	}
 +	/**
 +	 * Loads and display the data.
 +	 */
  	public function onPreRender($param)
  	{
  		parent::onPreRender($param);
  		$this->loadRecordData();
  	}
 +	/**
 +	 * Fetch the records and data bind it to the list.
 +	 */
  	protected function loadRecordData()
  	{
  		$this->_list->setVirtualItemCount($this->getRecordFinder()->count());
 @@ -65,6 +85,9 @@ class TScaffoldListView extends TScaffoldBase  		$this->_list->dataBind();
  	}
 +	/**
 +	 * @return TActiveRecordCriteria sort/search/paging criteria
 +	 */
  	protected function getRecordCriteria()
  	{
  		$total = $this->_list->getVirtualItemCount();
 @@ -81,26 +104,41 @@ class TScaffoldListView extends TScaffoldBase  		return $criteria;
  	}
 +	/**
 +	 * @param string search condition, the SQL string after the WHERE clause.
 +	 */
  	public function setSearchCondition($value)
  	{
  		$this->setViewState('SearchCondition', $value);
  	}
 +	/**
 +	 * @param string SQL search condition for list display.
 +	 */
  	public function getSearchCondition()
  	{
  		return $this->getViewState('SearchCondition');
  	}
 +	/**
 +	 * @param array search parameters
 +	 */
  	public function setSearchParameters($value)
  	{
  		$this->setViewState('SearchParameters', TPropertyValue::ensureArray($value),array());
  	}
 +	/**
 +	 * @return array search parameters
 +	 */
  	public function getSearchParameters()
  	{
  		return $this->getViewState('SearchParameters', array());
  	}
 +	/**
 +	 * Continue bubbling the "edit" command, "delete" command is handled in this class.
 +	 */
  	public function bubbleEvent($sender, $param)
  	{
  		switch(strtolower($param->getCommandName()))
 @@ -114,6 +152,9 @@ class TScaffoldListView extends TScaffoldBase  		return true;
  	}
 +	/**
 +	 * Initialize the edit view control form when EditViewID is set.
 +	 */
  	protected function initializeEdit($sender, $param)
  	{
  		if(($ctrl=$this->getEditViewControl())!==null)
 @@ -127,6 +168,9 @@ class TScaffoldListView extends TScaffoldBase  		}
  	}
 +	/**
 +	 * Deletes an Active Record.
 +	 */
  	protected function deleteRecord($sender, $param)
  	{
  		if($param instanceof TRepeaterCommandEventParameter)
 @@ -136,6 +180,9 @@ class TScaffoldListView extends TScaffoldBase  		}
  	}
 +	/**
 +	 * Initialize the default display for each Active Record item.
 +	 */
  	protected function listItemCreated($sender, $param)
  	{
  		$item = $param->getItem();
 @@ -147,6 +194,10 @@ class TScaffoldListView extends TScaffoldBase  		}
  	}
 +	/**
 +	 * Sets the Record primary key to the current repeater item's CustomData.
 +	 * Binds the inner repeater with properties of the current Active Record.
 +	 */
  	protected function populateField($sender, $param)
  	{
  		$item = $param->getItem();
 @@ -161,45 +212,69 @@ class TScaffoldListView extends TScaffoldBase  		}
  	}
 +	/**
 +	 * Updates repeater page index with the pager new index value.
 +	 */
  	protected function pageChanged($sender, $param)
  	{
  		$this->_list->setCurrentPageIndex($param->getNewPageIndex());
  	}
 +	/**
 +	 * @return TRepeater Repeater control for Active Record instances.
 +	 */
  	public function getList()
  	{
  		$this->ensureChildControls();
  		return $this->getRegisteredObject('_list');
  	}
 +	/**
 +	 * @return TPager List pager control.
 +	 */
  	public function getPager()
  	{
  		$this->ensureChildControls();
  		return $this->getRegisteredObject('_pager');
  	}
 +	/**
 +	 * @return TDropDownList Control that displays and controls the record ordering.
 +	 */
  	public function getSort()
  	{
  		$this->ensureChildControls();
  		return $this->getRegisteredObject('_sort');
  	}
 +	/**
 +	 * @return TRepeater Repeater control for record property names.
 +	 */
  	public function getHeader()
  	{
  		$this->ensureChildControls();
  		return $this->getRegisteredObject('_header');
  	}
 +	/**
 +	 * @return string TScaffoldEditView control ID for editing selected Active Record.
 +	 */
  	public function getEditViewID()
  	{
  		return $this->getViewState('EditViewID');
  	}
 +	/**
 +	 * @param string TScaffoldEditView control ID for editing selected Active Record.
 +	 */
  	public function setEditViewID($value)
  	{
  		$this->setViewState('EditViewID', $value);
  	}
 +	/**
 +	 * @return TScaffoldEditView control for editing selected Active Record, null if EditViewID is not set.
 +	 */
  	protected function getEditViewControl()
  	{
  		if(($id=$this->getEditViewID())!==null)
 diff --git a/framework/Data/ActiveRecord/TActiveRecord.php b/framework/Data/ActiveRecord/TActiveRecord.php index bdb03596..ea33035d 100644 --- a/framework/Data/ActiveRecord/TActiveRecord.php +++ b/framework/Data/ActiveRecord/TActiveRecord.php @@ -172,6 +172,16 @@ abstract class TActiveRecord extends TComponent  	 */
  	public function save()
  	{
 +		$this->commitChanges();
 +	}
 +
 +	/**
 +	 * Commit changes to the record, may insert, update or delete depending
 +	 * on the record state given in TObjectStateRegistery.
 +	 * @return boolean true if changes were made.
 +	 */
 +	protected function commitChanges()
 +	{
  		$registry = $this->getRecordManager()->getObjectStateRegistry();
  		$gateway = $this->getRecordManager()->getRecordGateway();
  		if(!$this->_readOnly)
 @@ -190,7 +200,7 @@ abstract class TActiveRecord extends TComponent  	{
  		$registry = $this->getRecordManager()->getObjectStateRegistry();
  		$registry->registerRemoved($this);
 -		return $this->save();
 +		return $this->commitChanges();
  	}
  	/**
 diff --git a/framework/Data/ActiveRecord/TActiveRecordCriteria.php b/framework/Data/ActiveRecord/TActiveRecordCriteria.php index 968a2691..6adfe4ce 100644 --- a/framework/Data/ActiveRecord/TActiveRecordCriteria.php +++ b/framework/Data/ActiveRecord/TActiveRecordCriteria.php @@ -153,6 +153,11 @@ class TActiveRecordCriteria extends TComponent  	{
  		return $this->getCondition();
  	}
 +
 +	public function repr()
 +	{
 +		return var_export($this->getParameters()->toArray(),true);
 +	}
  }
  ?>
\ No newline at end of file diff --git a/framework/Data/ActiveRecord/TActiveRecordGateway.php b/framework/Data/ActiveRecord/TActiveRecordGateway.php index 7bcd0eb2..1486e9c3 100644 --- a/framework/Data/ActiveRecord/TActiveRecordGateway.php +++ b/framework/Data/ActiveRecord/TActiveRecordGateway.php @@ -143,11 +143,12 @@ class TActiveRecordGateway extends TComponent  		$meta = $this->getMetaData($record);
  		$command = $meta->getFindByPkCommand($record->getDbConnection(),$keys);
  		$this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$keys);
 +		Prado::trace(get_class($record).'::FindRecordByPk('.var_export($keys,true).')', 'System.Data.ActiveRecord');
  		return $meta->postQueryRow($command->queryRow());
  	}
  	/**
 -	 * Returns records matching the list of given primary keys. 
 +	 * Returns records matching the list of given primary keys.
  	 * @param TActiveRecord active record instance.
  	 * @param array list of primary name value pairs
  	 * @return array matching data.
 @@ -157,9 +158,10 @@ class TActiveRecordGateway extends TComponent  		$meta = $this->getMetaData($record);
  		$command = $meta->getFindInPksCommand($record->getDbConnection(), $keys);
  		$this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$keys);
 +		Prado::trace(get_class($record).'::FindRecordsByPks('.var_export($keys,true).')', 'System.Data.ActiveRecord');
  		return $meta->postQuery($command->query());
  	}
 -	
 +
  	/**
  	 * Returns record data matching the given critera. If $iterator is true, it will
 @@ -174,6 +176,7 @@ class TActiveRecordGateway extends TComponent  		$meta = $this->getMetaData($record);
  		$command = $meta->getFindByCriteriaCommand($record->getDbConnection(),$criteria);
  		$this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$criteria);
 +		Prado::trace(get_class($record).'::FindRecordsByCriteria('.is_string($criteria) ? $criteria : $criteria->repr().')', 'System.Data.ActiveRecord');
  		return $iterator ? $meta->postQuery($command->query()) : $meta->postQueryRow($command->queryRow());
  	}
 @@ -189,6 +192,7 @@ class TActiveRecordGateway extends TComponent  		$meta = $this->getMetaData($record);
  		$command = $meta->getFindBySqlCommand($record->getDbConnection(),$sql,$parameters);
  		$this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$parameters);
 +		Prado::trace(get_class($record).'::FindRecordsBySql('.var_export($parameters,true).')', 'System.Data.ActiveRecord');
  		return $meta->postQuery($command->query());
  	}
 @@ -203,6 +207,7 @@ class TActiveRecordGateway extends TComponent  		$meta = $this->getMetaData($record);
  		$command = $meta->getCountRecordsCommand($record->getDbConnection(),$criteria);
  		$this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$criteria);
 +		Prado::trace(get_class($record).'::CountRecords('.is_string($criteria) ? $criteria : $criteria->repr().')', 'System.Data.ActiveRecord');
  		return intval($command->queryScalar());
  	}
 @@ -216,6 +221,7 @@ class TActiveRecordGateway extends TComponent  		$meta = $this->getMetaData($record);
  		$command = $meta->getInsertCommand($record->getDbConnection(),$record);
  		$this->raiseCommandEvent(TActiveRecordStatementType::Insert,$command,$record);
 +		Prado::trace(get_class($record).'::Insert()', 'System.Data.ActiveRecord');
  		$rowsAffected = $command->execute();
  		if($rowsAffected===1)
  			$meta->updatePostInsert($record->getDbConnection(),$record);
 @@ -232,6 +238,7 @@ class TActiveRecordGateway extends TComponent  		$meta = $this->getMetaData($record);
  		$command = $meta->getUpdateCommand($record->getDbConnection(),$record);
  		$this->raiseCommandEvent(TActiveRecordStatementType::Update,$command,$record);
 +		Prado::trace(get_class($record).'::Update()', 'System.Data.ActiveRecord');
  		return $command->execute();
  	}
 @@ -245,6 +252,7 @@ class TActiveRecordGateway extends TComponent  		$meta = $this->getMetaData($record);
  		$command = $meta->getDeleteCommand($record->getDbConnection(),$record);
  		$this->raiseCommandEvent(TActiveRecordStatementType::Delete,$command,$record);
 +		Prado::trace(get_class($record).'::Delete()', 'System.Data.ActiveRecord');
  		return $command->execute();
  	}
 @@ -258,6 +266,7 @@ class TActiveRecordGateway extends TComponent  		$meta = $this->getMetaData($record);
  		$command = $meta->getDeleteByPkCommand($record->getDBConnection(),$keys);
  		$this->raiseCommandEvent(TActiveRecordStatementType::Delete,$command,$record,$keys);
 +		Prado::trace(get_class($record).'::DeleteRecordsByPk('.var_export($keys,true).')', 'System.Data.ActiveRecord');
  		return $command->execute();
  	}
 @@ -272,6 +281,7 @@ class TActiveRecordGateway extends TComponent  		$meta = $this->getMetaData($record);
  		$command = $meta->getDeleteByCriteriaCommand($record->getDBConnection(),$criteria);
  		$this->raiseCommandEvent(TActiveRecordStatementType::Delete,$command,$record,$criteria);
 +		Prado::trace(get_class($record).'::DeleteRecordsByCriteria('.is_string($criteria) ? $criteria : $criteria->repr().')', 'System.Data.ActiveRecord');
  		return $command->execute();
  	}
 diff --git a/framework/Data/ActiveRecord/Vendor/TDbMetaData.php b/framework/Data/ActiveRecord/Vendor/TDbMetaData.php index 3a959ba4..a3a13120 100644 --- a/framework/Data/ActiveRecord/Vendor/TDbMetaData.php +++ b/framework/Data/ActiveRecord/Vendor/TDbMetaData.php @@ -212,15 +212,26 @@ abstract class TDbMetaData extends TComponent  	/**
  	 * Gets the columns that can be inserted into the database.
 +	 * Missing properties are assumed to be null.
  	 * @param TActiveRecord record object to be inserted.
  	 * @return array name value pairs of fields to be added.
 +	 * @throws TActiveRecordException if property is null and table column is
 +	 * defined as not null unless primary key column.
  	 */
  	protected function getInsertableColumns($record)
  	{
  		$columns = array();
  		foreach($this->getColumns() as $name=>$column)
  		{
 -			$value = $record->{$name};
 +			try
 +			{
 +				$value = $record->{$name};
 +			}
 +			catch (TInvalidOperationException $e) //ignore missing properties
 +			{
 +				$value = null;
 +			}
 +
  			if($column->getNotNull() && $value===null && !$column->getIsPrimaryKey())
  			{
  				throw new TActiveRecordException(
 diff --git a/framework/Data/TDbCommand.php b/framework/Data/TDbCommand.php index 9cf5b0a0..102bdf34 100644 --- a/framework/Data/TDbCommand.php +++ b/framework/Data/TDbCommand.php @@ -180,6 +180,7 @@ class TDbCommand extends TComponent  	{
  		try
  		{
 +			Prado::trace('Execute Command: '.$this->getDebugStatementText(), 'System.Data');
  			if($this->_statement instanceof PDOStatement)
  			{
  				$this->_statement->execute();
 @@ -197,7 +198,7 @@ class TDbCommand extends TComponent  	/**
  	 * @return String prepared SQL text for debugging purposes.
  	 */
 -	protected function getDebugStatementText()
 +	public function getDebugStatementText()
  	{
  		if(Prado::getApplication()->getMode() === TApplicationMode::Debug)
  			return $this->_statement instanceof PDOStatement ?
 @@ -215,6 +216,7 @@ class TDbCommand extends TComponent  	{
  		try
  		{
 +			Prado::trace('Query: '.$this->getDebugStatementText(), 'System.Data');
  			if($this->_statement instanceof PDOStatement)
  				$this->_statement->execute();
  			else
 @@ -239,6 +241,7 @@ class TDbCommand extends TComponent  	{
  		try
  		{
 +			Prado::trace('Query Row: '.$this->getDebugStatementText(), 'System.Data');
  			if($this->_statement instanceof PDOStatement)
  				$this->_statement->execute();
  			else
 @@ -264,6 +267,7 @@ class TDbCommand extends TComponent  	{
  		try
  		{
 +			Prado::trace('Query Scalar: '.$this->getDebugStatementText(), 'System.Data');
  			if($this->_statement instanceof PDOStatement)
  				$this->_statement->execute();
  			else
 diff --git a/framework/prado-cli.php b/framework/prado-cli.php index 0cd33a74..5ccef4bc 100755 --- a/framework/prado-cli.php +++ b/framework/prado-cli.php @@ -631,6 +631,8 @@ class PradoCommandLineActiveRecordGen extends PradoCommandLineAction  		if($this->_soap)  		{  			$prop .= <<<EOD + +  	/**  	 * @var $type $name  	 * @soapproperty @@ -657,6 +659,7 @@ class $class extends TActiveRecord  	public static $table;  $props +  	public static function finder()  	{  		return self::getRecordFinder('$class'); @@ -685,15 +688,15 @@ if(class_exists('PHP_Shell_Commands', false))  	    public function generate($l)  	    { -			$args = explode(" ", trim($l)); -			if(count($args) > 2) +			$input = explode(" ", trim($l)); +			if(count($input) > 2)  			{  				$app_dir = '.';  				if(Prado::getApplication()!==null)  					$app_dir = dirname(Prado::getApplication()->getBasePath()); -				$args = array($args[0],$args[1], $args[2],$app_dir); -				if(count($args)>3) -					$args = array($args[0],$args[1], $args[2],$app_dir,'soap'); +				$args = array($input[0],$input[1], $input[2],$app_dir); +				if(count($input)>3) +					$args = array($input[0],$input[1], $input[2],$app_dir,'soap');  				$cmd = new PradoCommandLineActiveRecordGen;  				$cmd->performAction($args);  			} | 
