/** * Use a specific object revision * * @param Revision $revision Revision to be used * @return ObjectInterface Object * @throws OutOfBoundsException If a revision beyond the latest one is requested */ public function useRevision(Revision $revision) { // If a revision beyond the latest one is requested if (!$revision->isCurrent() && $revision->getRevision() > $this->latestRevision->getRevision()) { throw new OutOfBoundsException(sprintf('Invalid object revision "%s"', $revision->getRevision()), OutOfBoundsException::INVALID_OBJECT_REVISION); } // Determine whether the current revision was requested $currentRevision = $this->getCurrentRevision(); $isCurrentRevision = $revision->isCurrent() || $currentRevision->equals($revision); if ($isCurrentRevision) { $revision = $currentRevision; } // If the requested revision is not already used if (!$this->getRevision()->equals($revision)) { /** @var ManagerInterface $objectManager */ $objectManager = Kernel::create(Service::class)->getObjectManager(); /** @var Revision $newRevision */ $newRevision = $isCurrentRevision ? Revision::current() : $revision; /** @var RepositoryLocator $newRevisionLocator */ $newRevisionLocator = $this->locator->setRevision($newRevision); // Instantiate the requested revision resource $revisionResource = $objectManager->loadObjectResource($newRevisionLocator, SelectorInterface::ALL); // Load the revision resource data $this->loadRevisionData($revisionResource->getPayload(), $revisionResource->getPropertyData()); // Update the object locator $this->updateLocator(); } return $this; }
/** * Load a particular object revision from a repository * * @param RepositoryLocatorInterface $locator Repository object locator * @param int $visibility Object visibility * @return ObjectInterface Object */ protected function loadObjectRevision(RepositoryLocatorInterface $locator, $visibility = SelectorInterface::ALL) { // Create the current revision locator /** @var RepositoryLocatorInterface $currentLocator */ $currentLocator = $locator->setRevision(Revision::current()); // Load the object resource respecting visibility constraints $objectResource = $this->loadObjectResource($currentLocator, $visibility); // Instantiate the object $object = ObjectFactory::createFromResource($currentLocator, $objectResource); // Use and return the requested object revision return $object->useRevision($locator->getRevision()); }
/** * Publish an object in the repository * * @param ObjectInterface $object */ protected function publishObject(ObjectInterface $object) { $objectRepoLocator = $object->getRepositoryLocator(); // If the object had been persisted as a draft: Remove the draft resource $objectDraftLocator = $objectRepoLocator->setRevision($object->getRevision()->setDraft(true)); $absObjectDraftPath = $this->getAbsoluteResourcePath($objectDraftLocator); if (@file_exists($absObjectDraftPath)) { unlink($absObjectDraftPath); } // If it's not the first object revision: Rotate the previous revision resource $objectRevisionNumber = $object->getRevision()->getRevision(); if ($objectRevisionNumber > 1) { // Build the "current" object repository locator $currentRevision = Revision::current(); $curObjectResPath = $this->getAbsoluteResourcePath($objectRepoLocator->setRevision($currentRevision)); // Build the previous object repository locator /** @var Revision $previousRevision */ $previousRevision = Kernel::create(Revision::class, [$objectRevisionNumber - 1]); $prevObjectResPath = $this->getAbsoluteResourcePath($objectRepoLocator->setRevision($previousRevision)); // Rotate the previous revision's resource path if (file_exists($curObjectResPath)) { rename($curObjectResPath, $prevObjectResPath); } } }