In order to implement lazy loading, Orient has implemented some sort of metaprogramming when hydrating objects.
At run-time, when the Mapper hydrates a record of class User:
use Congow\Orient\ODM\Mapper\Annotations\Property;
class User
{
/**
* Property(type="link")
*/
protected $address;
public function setAddress(Address $address)
{
$this->address = $address;
}
public function getAddress()
{
return $this->address;
}
}
it returns an object of type UserProxy, making it possible to retrieve a record and its associated records lazily.
A proxy is, basically, a class which extends all the public methods of a record class and checks if a property is returned as an object of type Congow\Orient\ODM\Proxy\AbstractProxy, which means that it should contain an object with the logic of retrieving a record.
Proxies look like:
class AddressProxy extends Address
{
public function getType()
{
$parent = parent::getType();
if (!is_null($parent)) {
if ($parent instanceOf \Congow\Orient\ODM\Proxy\AbstractProxy) {
return $parent();
}
return $parent;
}
}
}
Objects of type AbstractProxy, when called as functions through PHP’s magic __invoke() method, contain the business logic to do a query and retrieve the related record(s):
public function __invoke()
{
return $mapper->find($rid);
}
Proxies are created once you hydrate an object of class X ( XProxy ): they are never automatically re-generated, so you’ll need to delete the proxy classes once you modify a public method of the X class.
To set the directory in which you’re going to generate proxies you only need to do a couple things: first, you need to setup the autoloader:
$classLoader = new SplClassLoader('Congow\Orient\Proxy', "/abs/path/to/proxies");
$classLoader->register();
then, once you instantiate a Mapper, you nedd to pass it the proxies directory:
$mapper = new Mapper($adapter, "/abs/path/to/proxies")
Remember to create, under /abs/path/to/proxies, the subdirectories:
Congow
|
|_ Orient
|
|_ Proxy
because proxies will be autoloaded in /abs/path/to/proxies/Congow/Orient/Proxy directory.
A final hint, if you are using a caching system in your software, you may want to put the proxies there.
In Symfony2, for example, a good location for proxies might be app/cache.