Skip to main content

Decorating Member Objects

We can use a collection decorator to dynamically decorate the members of the collection on the fly.

In this example, we will be using an example of a one-to-many association between PartnerCompany and BusinessContract entities. The PartnerCompany entity has a collection of BusinessContract entities.

BusinessContract Entity & Superclass

use Doctrine\ORM\Mapping as ORM;

interface BusinessContractInterface {
// ...
}

#[ORM\Entity()]
class BusinessContract implements BusinessContractInterface {
// ...
}

Decorator for BusinessContract

class BusinessContractDecorator implements BusinessContractInterface {
public function __construct(private BusinessContractInterface $wrapped)
{
}

// ...
}

Decorator for the BusinessContract Collection

use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Selectable;
use Rekalogika\Collections\Decorator\Decorator\CollectionDecorator;

/**
* @extends CollectionDecorator<array-key,BusinessContractInterface>
*/
class BusinessContractCollectionDecorator extends CollectionDecorator
{
#[\Override]
public function get(string|int $key): BusinessContractInterface
{
return new BusinessContractDecorator(
$this->getWrapped()->get($key)
);
}

#[\Override]
public function getIterator(): \Traversable
{
foreach ($this->getWrapped() as $key => $value) {
yield $key => new BusinessContractDecorator($value);
}
}

// We should override all the other methods that returns
// BusinessContractInterface, but for conciseness, we skip them here.
}

Usage in the PartnerCompany Object

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity()]
class PartnerCompany
{
/**
* @var Collection<array-key,BusinessContractInterface>
*/
#[ORM\OneToMany(targetEntity: BusinessContract::class)]
private Collection $businessContracts;

public function __construct()
{
$this->businessContracts = new ArrayCollection();
}

public function getBusinessContracts(): BusinessContractCollectionDecorator
{
return new BusinessContractCollectionDecorator($this->businessContracts);
}
}

Class Diagram

Now for a bird eye view of our classes.

File classesFile classes