A Chaining Breakthrough!

To further steal the great foundation of jQuery method chaining, I have realized a way to use a “back” function that will regress backward through the chained functions and return the last object that was manipulated. Wow, that makes it sound confusing but it is not. Imagine the following chained code.

$objSelect->addTable('table');

Previously this would have returned the original sqlSelect object. But what if we wanted to manipulate the sqlTableReference before moving on? Maybe we want to add a JOIN element or set an alias for the table. This would be impossible using the chaining methods. We would need to¬†explicitly create the table separately with its own chaining methods, then pass that create sqlTableReference object to the sqlSelect object. Let us try returning the created, or passing, sqlTableReference when users call the addTable method on the sqlSelect object. This will allow further manipulation of that table object. Great. Now we need to get “back” to the original sqlSelect object so we can add maybe an sqlSelectExpression or an sqlConditionGroup. Simply call the new back() chaining method to get back to the original object.

$objSelect->addTable('table')
		->setAlias('tbl')
		->back()
		->addWhere($objConditionGroup);

Going further in, we may need to regress all the way back to the beginning, to the absolute original object that started the line of code. Call the end() chaining method and get there!

$objSelect->addTable('table')
		->setJoin('INNER')
		->addOn($objConditionGroup)
		->back()
		->back();

// OR JUST CALL end()
$objSelect->addTable('table')
		->setJoin('INNER')
		->addOn($objConditionGroup)
		->end();

So far this is all I have used to accomplish this. There has been little testing but the first tests work incredibly. I have placed the following code within an abstract class from which all chaining classes are extended.

abstract class sqlMethodChainer
{

	private $objCaller;

	public function setCaller(&$objCaller)
	{
		$this->objCaller = $objCaller;
		return $this;
	}


	public function back()
	{
		return $this->objCaller;
	}

	public function end()
	{
		$obj = $this;
		while (is_object($obj) && method_exists($obj, 'back')) {
			$obj = $obj->back();
		}
		return $obj;
	}
}

Leave a Reply