/** * Hydrate an entity. * * Encapsulates hydration, authorization, pre-validation API events, and * validation procedures into one method. * * @throws Exception\ValidationException * @param Request $request * @param EntityInterface $entity * @param ErrorStore $errorStore */ protected function hydrateEntity(Request $request, EntityInterface $entity, ErrorStore $errorStore) { $operation = $request->getOperation(); // Before everything, check whether the current user has access to this // entity in its original state. $this->authorize($entity, $operation); // Trigger the operation's api.validate.data.pre event. $event = new Event(Event::API_VALIDATE_DATA_PRE, $this, ['services' => $this->getServiceLocator(), 'entity' => $entity, 'request' => $request, 'errorStore' => $errorStore]); $this->getEventManager()->trigger($event); // Validate the request. $this->validateRequest($request, $errorStore); if ($errorStore->hasErrors()) { $validationException = new Exception\ValidationException(); $validationException->setErrorStore($errorStore); throw $validationException; } $this->hydrate($request, $entity, $errorStore); // Trigger the operation's api.validate.entity.pre event. $event = new Event(Event::API_VALIDATE_ENTITY_PRE, $this, ['services' => $this->getServiceLocator(), 'entity' => $entity, 'request' => $request, 'errorStore' => $errorStore]); $this->getEventManager()->trigger($event); // Validate the entity. $this->validateEntity($entity, $errorStore); if ($errorStore->hasErrors()) { if (Request::UPDATE == $operation) { // Refresh the entity from the database, overriding any local // changes that have not yet been persisted $this->getEntityManager()->refresh($entity); } $validationException = new Exception\ValidationException(); $validationException->setErrorStore($errorStore); throw $validationException; } }