Hi, today, I want to share a good tip to have access to an object attribute of an unknown class from eZpublish templates. This case is rare, but when you have an object with unknown attribute, or from an unknown PHP class, and you want to access an attribute by its name, if the object does not extends a datatype, the classic "object.attribute" operator in template language cannot work. The problem is that this operator call methods like attributes(), hasAttribute($attr) or attribute($attr) to explore the attributes. In your case, the object has no such methods, you cannot modify the class to add them (for some reasons, for example if the object comes from PHP SOAP), and then you need a wrapper to simulate a datatype.
I propose a DummyDatatype wrapper class, used by a template operator, like this :
class DummyDataType {
var $Object = false;
function DummyDataType($object = false) {
$this->Operators = array( 'ddt' );
$this->NamedOperators = array(
'ddt'=> array( 'attribut' => array(
'type' => 'Object',
'required' => true,
'default' => null))
);
$this->Object = $object;
}
function modify( $tpl, $operatorName, $operatorParameters,
$rootNamespace, $currentNamespace,
&$operatorValue, $namedParameters) {
switch ( $operatorName ) {
case 'ddt':
$this->Object = ($operatorValue != null)?
$operatorValue : $namedParameters['attribut'];
$operatorValue = $this;
break;
default :
$tpl->warning($operatorName,
"Unknown operator '$operatorName'");
break;
}
}
function operatorList() {
return $this->Operators;
}
function namedParameterPerOperator() {
return true;
}
function namedParameterList() {
return $this->NamedOperators;
}
function attributes() {
$obj = $this->Object;
$result = array();
foreach($obj as $key => $value) {
$result[] = $key;
}
return $result;
//TODO: test this in all cases (string,integer,...)
}
function hasAttribute( $attr ) {
if ($this->Object == false) return false;
return isset( $this->Object->$attr );
}
function attribute( $attr ) {
if (isset( $this->Object )) {
if ( isset( $this->Object->$attr ) )
return $this->Object->$attr;
}
eZDebug::writeError("Attribute '$attr' does not exist",
'DummyDataType::attribute');
$attributeData = null;
return $attributeData;
}
}
With this class, used like a template operator in an extension, you can explore an object, whatever his class,
by calling this:
my_object|ddt('my_attribute').0 {* an array *}
my_object|ddt('sub_object')|ddt('a_datatype_object').content...
{* object containing datatype object, with content attribute *}This class could be useful for some rare cases, but is a smart solution, so keep a bookmark on it ;)