diff --git a/README.md b/README.md index 2974d45..58de9d7 100644 --- a/README.md +++ b/README.md @@ -386,6 +386,49 @@ The `$this->getContext(...)` call is a convenient alternative to `$this->context Unlike a normal interactor, the `call()` method on an organizer is already implemented. When called, this organizer will perform interactors in the order they were pushed onto the queue in the `organize()` method. +### Sharing an attribute between Contexts + +Suppose you have to retrieve the User (using a `Deefour\Interactor\Interactor`) and then share this user attribute with CreateVehicleContext. You are able to achieve this by using `share()` method from `Deefour\Interactor\CompositeContext`. + +```php +use Deefour\Interactor\Organizer; + +class RegisterUser extends Organizer +{ + /** + * Constructor. + * + * @param RegisterUserContext $context A composite context for the organizer. + */ + public function __construct(RegisterUserContext $context) + { + parent::__construct($context); + } + + /** + * Create the new user and their first vehicle. + */ + public function organize() + { + $createUserInteractor = new CreateUser($this->getContext(CreateUserContext::class)); + $createUserContext = $createUserInteractor->call(); + + /** + * Shares attribute 'user' from CreateUserContext with CreateVehicleContext. + */ + $this->context()->share( + CreateUserContext::class, + CreateVehicleContext::class, + 'user' + ); + + $this->addInteractor(new CreateVehicle($this->getContext(CreateVehicleContext::class))); + } +} +``` + +This way, the Interactor `CreateVehicle` is able to get the `User` from `CreateVehicleContext`, if necessary. + ### Executing an Organizer An organizer is executed like any other interactor. Call the `call()` method to kick things off after instantiation. diff --git a/src/CompositeContext.php b/src/CompositeContext.php index 7d7c77f..fe70208 100644 --- a/src/CompositeContext.php +++ b/src/CompositeContext.php @@ -31,6 +31,25 @@ public function __construct(array $contexts) parent::__construct($contexts); } + /** + * Shares $attribute from $contextSrc with $contextDest + * + * @param string $contextSrc The context FQCN to get $attribute from (source) + * @param string $contextDest The context FQCN to share $attribute with (destination) + * @param string $attribute The attribute name as a string + * + * @return void + */ + public function share($contextSrc, $contextDest, $attribute) + { + $contextSrc = $this->get($contextSrc); + $contextDest = $this->get($contextDest); + + if (isset($contextSrc) && isset($contextDest) && isset($contextSrc->{$attribute})) { + $contextDest->{$attribute}($contextSrc->{$attribute}); + } + } + /** * Type-check each context in the source array provided to the composite. * Throw an exception if an argument does not subclass the base context.