Dev:Beans
From ZenMagick Wiki
Contents |
What are beans?
In simple terms, beans are basic objects with getXXX() and setXXX() methods. In ZenMagick, virtually all classes are also beans, because they extend ZMObject which implements bean support.
This means each class can hold custom properties using the same get/set syntax as for actually build in properties. This is useful in many ways, for example to support custom database fields.
Bean definitions
Now, this alone is nothing special - get/set are implemented using PHP's magic __get() and __set() methods and found in a lot of PHP code.
With a given syntax to get/set properties it is now possible to define objects using plain strings. This is similar to serializing objects, just with the difference that bean definitions are more powerful,do not require to have an object first and generally are easier to read and write.
ZMBeanUtils
All methods to handle beans and bean definitions are provided by the class ZMBeanUtils. Perhaps the most important one is
ZMBeanUtils::getBean('Products');
You'll notice the similarity with the loader's make syntax:
ZMLoader::make('Products');
In fact, in this case they result in exactly the same (and ZMBeanUtils is using the loader to actually create objects). However, bean definitions can do a lot more.
To start with, it is worth noting that bean definitions are urlencoded. This is not always required, but in more complex examples it is needed to ensure the definition is parsed correctly.
Breakdown of the bean definition syntax
A bean definition consists of two main parts, with the hash '#' used as separator:
class-definition#parameter-definition
- class definition
- In the simplest version (as seen in the example above), the class definition is just a class name. It can be used with or without the ZM prefix, as eventually the loader will be used to instantiate the object.
- The class definition supports three special prefixes to control special treatment of the class definition (excluding the prefix):
- 'bean::'
This is actually optional and only is important when used in the parameter definition. Only exception is 'bean::null', which will result in a real PHPnull. - 'ref::'
Indicates that the class definition does describe a (singleton) reference. This is the only case where not a new object is created, but an existing singleton is looked up and returned. Again, this is typically used in the parameter definition. - 'set::'
Indicates that the class definition is to be used as setting key to look up the actual class definition. Useful to configure the actual implementation class, for example the used WYSIWYG editor, etc.
- 'bean::'
- parameter-definition
- As already mentioned, bean definitions may be urlencoded. Actually, this only really applies to the parameter definition. The reason should soon become clear.
- As in many other places in the code, the parameter string is just a query style string; example:
foo=bar&doh=fuu. When requesting a bean withZMBeanUtils::getBean()these name/value pairs will be used to call corresponding setXXX() methods on the created object. This means the following line:
ZMBeanUtils::getBean('Product#name=mouse&foo=bar');
- is equivalent to:
$product = ZMLoader::make('Product');
$product->setName('mouse');
$product->setFoo('bar');
- If you now take into account that the special prefixes (bean::, ref::, set::) can be used in parameter values, it means that we can also set objects as values:
ZMBeanUtils::getBean('MyClass#handler=bean::SomeOtherClass');
- as opposed to:
$myClass = ZMLoader::make('MyClass');
$myClass->setHandler(ZMLoader::make('SomeOtherClass'));
- Even more complex examples could include parameter values as beans with their own parameter:
ZMBeanUtils::getBean('MyClass#handler='.urlencode('bean::SomeOtherClass#foo=bar'));
// or:
ZMBeanUtils::getBean('MyClass#handler=bean::SomeOtherClass%23foo%3Dbar');
- would be the same as:
$myClass = ZMLoader::make('MyClass');
$handler = ZMLoader::make('SomeOtherClass');
$handler->setFoo('bar');
$myClass->setHandler($handler);

