Sure,
PHP Code:
interface IVisitor {
public function render();
public function visit( IComposite $composite );
public function __construct( IRequestHandler $request_handler );
}
PHP Code:
// plain vanilla visitor as stated in earlier post...
//
class HtmlVisitor implements IVisitor {
private $request_handler;
public function __construct( IRequestHandler $request_handler ) {
$this -> request_handler = $request_handler;
}
public function render() {
echo( $this -> template['page'] );
}
public function visit( IComposite $composite ) {
// at the moment, just have a controller return a template file
// via a file_get_contents( 'filename-template.tpl' );
// for simplicity
$template = $composite -> execute( $this -> request_handler );
// ...
// do what is required to recurse composite, and it's child composites
// at this point
}
}
Now, for example we have a given Controller (which implements IComposite Interface) that instead of returning a HTML template via the file_get_contents( ... ), instead it's template is a fragment of XML, so you need to transform it HTML yes? Okay...
PHP Code:
class XmlVisitor implements IVisitor {
private $request_handler;
private $visitor;
public function __construct( IRequestHandler $request_handler ) {
$this -> request_handler = $request_handler;
}
public function render() {
// not implemented
}
public function visit( IComposite $composite ) { // edited due to error...
// template is XML format
$template = $composite -> execute( $this -> request_handler );
// do transformation at this point
//
// note two things, due to the implementation of the IVisitor, the
// composite (controller) needs to know 'how' to return the transformed
// XML (HTML) to the IVisitor, and not return the original XML it's self
//
// I have left this to the controller, thus to simplify the IVisitors, since it's
// not every composite that would be handling XML anyways...
//
// if you [I]do[/I] have other composites that use XML, again just use this visitor
// on them, and voila, things are taken care of for you :)
}
}
Sorry for the bad explamation, but if there is anything you don't fully understand, I can go into more detail for you? Typically, a Controller that uses XML would look like this,
PHP Code:
// ...
public function __construct() {
$this -> transformed = false;
}
public function execute( IRequestHandler $request_handler ) {
// ...
if( $this -> transformed ) {
return $this -> getHtml();
} else {
$this -> transformed = true;
// ... return the XML instead
}
// ...
}
// ...
EDIT:
This is from memory, and looking back on the notes I made at the time, and the script, I made an error, but it has now been corrected
The error that I had made, was the need for the Decorated Interface, but looking again there was no need for decoration 
Once the XML in any given Composite has been transformed, the result is put back to the Composite in question... Due to the recursiveness of the HtmlVisitor::visit( IComposite $composite ) class method, regardless of any Composite being visited by another visitor or not, the Composite that had the XML transformed to HTML is still visited by the HtmlVisitor implementation.
In each Composite, to identify a given Composite, I have an ID for that Composite, ie
PHP Code:
class BodyActionHandler extends BaseActionHandler {
protected $id = 'body';
// ...
class FooterActionHandler extends BaseActionHandler {
protected $id = 'footer';
// ... etc, for each Composite ...
So now that I've fixed the leak, I can get sleep a lot more easily
Bookmarks