diff --git a/eZ/Bundle/EzPublishCoreBundle/Command/CleanupVersionsCommand.php b/eZ/Bundle/EzPublishCoreBundle/Command/CleanupVersionsCommand.php new file mode 100644 index 00000000000..a9b4ddb1c03 --- /dev/null +++ b/eZ/Bundle/EzPublishCoreBundle/Command/CleanupVersionsCommand.php @@ -0,0 +1,266 @@ + VersionInfo::STATUS_DRAFT, + self::VERSION_ARCHIVED => VersionInfo::STATUS_ARCHIVED, + self::VERSION_PUBLISHED => VersionInfo::STATUS_PUBLISHED, + ]; + + /** + * @var \eZ\Publish\API\Repository\Repository + */ + private $repository; + + /** + * @var \eZ\Publish\API\Repository\UserService + */ + private $userService; + + /** + * @var \eZ\Publish\API\Repository\ContentService + */ + private $contentService; + + /** + * @var \eZ\Publish\API\Repository\PermissionResolver + */ + private $permissionResolver; + + /** + * @var \eZ\Bundle\EzPublishCoreBundle\ApiLoader\RepositoryConfigurationProvider + */ + private $repositoryConfigurationProvider; + + /** + * @var \Doctrine\DBAL\Driver\Connection + */ + private $connection; + + public function __construct( + Repository $repository, + RepositoryConfigurationProvider $repositoryConfigurationProvider, + Connection $connection + ) { + $this->repository = $repository; + $this->repositoryConfigurationProvider = $repositoryConfigurationProvider; + $this->connection = $connection; + + parent::__construct(); + } + + protected function initialize(InputInterface $input, OutputInterface $output) + { + parent::initialize($input, $output); + + $this->userService = $this->repository->getUserService(); + $this->contentService = $this->repository->getContentService(); + $this->permissionResolver = $this->repository->getPermissionResolver(); + + $this->permissionResolver->setCurrentUserReference( + $this->userService->loadUserByLogin($input->getOption('user')) + ); + } + + protected function configure() + { + $config = $this->repositoryConfigurationProvider->getRepositoryConfig(); + + $this + ->setName('ezplatform:content:cleanup-versions') + ->setDescription('Remove unwanted content versions. It keeps published version untouched. By default, it keeps also the last archived/draft version.') + ->addOption( + 'status', + 't', + InputOption::VALUE_OPTIONAL, + sprintf( + "Select which version types should be removed: '%s', '%s', '%s'.", + self::VERSION_DRAFT, + self::VERSION_ARCHIVED, + self::VERSION_ALL + ), + self::VERSION_ALL + ) + ->addOption( + 'keep', + 'k', + InputOption::VALUE_OPTIONAL, + "Sets number of the most recent versions (both drafts and archived) which won't be removed.", + $config['options']['default_version_archive_limit'] + ) + ->addOption( + 'user', + 'u', + InputOption::VALUE_OPTIONAL, + 'eZ Platform username (with Role containing at least Content policies: remove, read, versionread)', + self::DEFAULT_REPOSITORY_USER + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + if (($keep = (int) $input->getOption('keep')) < 0) { + throw new InvalidArgumentException( + 'status', + 'Keep value can not be negative.' + ); + } + + $status = $input->getOption('status'); + + $contentIds = $this->getObjectsIds($keep, $status); + $contentIdsCount = count($contentIds); + + if ($contentIdsCount === 0) { + $output->writeln('There is no Content matching given criteria.'); + + return; + } + + $output->writeln(sprintf( + 'Found %d Content IDs matching given criteria.', + $contentIdsCount + )); + + $removedVersionsCounter = 0; + + $removeAll = $status === self::VERSION_ALL; + $removeDrafts = $status === self::VERSION_DRAFT; + $removeArchived = $status === self::VERSION_ARCHIVED; + + foreach ($contentIds as $contentId) { + try { + $contentInfo = $this->contentService->loadContentInfo((int) $contentId); + $versions = $this->contentService->loadVersions($contentInfo); + $versionsCount = count($versions); + + $output->writeln(sprintf( + 'Content %d has %d version(s)', + (int) $contentId, + $versionsCount + ), Output::VERBOSITY_VERBOSE); + + $versions = array_filter($versions, function ($version) use ($removeAll, $removeDrafts, $removeArchived) { + if ( + ($removeAll && $version->status !== VersionInfo::STATUS_PUBLISHED) || + ($removeDrafts && $version->status === VersionInfo::STATUS_DRAFT) || + ($removeArchived && $version->status === VersionInfo::STATUS_ARCHIVED) + ) { + return $version; + } + }); + + if ($keep > 0) { + $versions = array_slice($versions, 0, -$keep); + } + + $output->writeln(sprintf( + "Found %d content's (%d) version(s) to remove.", + count($versions), + (int) $contentId + ), Output::VERBOSITY_VERBOSE); + + /** @var \eZ\Publish\API\Repository\Values\Content\VersionInfo $version */ + foreach ($versions as $version) { + $this->contentService->deleteVersion($version); + ++$removedVersionsCounter; + $output->writeln(sprintf( + "Content's (%d) version (%d) has been deleted.", + $contentInfo->id, + $version->id + ), Output::VERBOSITY_VERBOSE); + } + } catch (Exception $e) { + $output->writeln(sprintf( + '%s', + $e->getMessage() + )); + } + } + + $output->writeln(sprintf( + 'Removed %d unwanted contents version(s).', + $removedVersionsCounter + )); + } + + /** + * @param int $keep + * @param string $status + * + * @return array + * + * @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException + */ + protected function getObjectsIds($keep, $status) + { + $query = $this->connection->createQueryBuilder() + ->select('c.id') + ->from('ezcontentobject', 'c') + ->join('c', 'ezcontentobject_version', 'v', 'v.contentobject_id = c.id') + ->groupBy('c.id', 'v.status') + ->having('count(c.id) > :keep'); + $query->setParameter('keep', $keep); + + if ($status !== self::VERSION_ALL) { + $query->where('v.status = :status'); + $query->setParameter('status', $this->mapStatusToVersionInfoStatus($status)); + } else { + $query->andWhere('v.status != :status'); + $query->setParameter('status', $this->mapStatusToVersionInfoStatus(self::VERSION_PUBLISHED)); + } + + $stmt = $query->execute(); + + return $stmt->fetchAll(PDO::FETCH_COLUMN); + } + + /** + * @param string $status + * + * @return int + * + * @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException + */ + private function mapStatusToVersionInfoStatus($status) + { + if (array_key_exists($status, self::VERSION_STATUS)) { + return self::VERSION_STATUS[$status]; + } + + throw new InvalidArgumentException( + 'status', + sprintf( + "Status %s can't be mapped to VersionInfo status.", + $status + ) + ); + } +} diff --git a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Configuration/Parser/Image.php b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Configuration/Parser/Image.php index af64b98e68e..a8c5b5fe01e 100644 --- a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Configuration/Parser/Image.php +++ b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/Configuration/Parser/Image.php @@ -115,12 +115,17 @@ function ($v) { ->end() ->end() ->end() + ->end() + ->scalarNode('image_host') + ->info('Images host. All system images URLs are prefixed with given host if configured.') + ->example('https://ezplatform.com') ->end(); } public function preMap(array $config, ContextualizerInterface $contextualizer) { $contextualizer->mapConfigArray('image_variations', $config); + $contextualizer->mapSetting('image_host', $config); } public function mapConfig(array &$scopeSettings, $currentScope, ContextualizerInterface $contextualizer) diff --git a/eZ/Bundle/EzPublishCoreBundle/Imagine/ResolverFactory.php b/eZ/Bundle/EzPublishCoreBundle/Imagine/ResolverFactory.php new file mode 100644 index 00000000000..96960e30df6 --- /dev/null +++ b/eZ/Bundle/EzPublishCoreBundle/Imagine/ResolverFactory.php @@ -0,0 +1,44 @@ +resolver = $resolver; + $this->proxyResolverClass = $proxyResolverClass; + + if ($configResolver->hasParameter('image_host') && + ($imageHost = $configResolver->getParameter('image_host')) !== '') { + $this->hosts = [$imageHost]; + } + } + + public function createCacheResolver() + { + return new $this->proxyResolverClass($this->resolver, $this->hosts); + } +} diff --git a/eZ/Bundle/EzPublishCoreBundle/Resources/config/default_settings.yml b/eZ/Bundle/EzPublishCoreBundle/Resources/config/default_settings.yml index 97112cb9c4b..996fe2de777 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Resources/config/default_settings.yml +++ b/eZ/Bundle/EzPublishCoreBundle/Resources/config/default_settings.yml @@ -240,6 +240,8 @@ parameters: resize: "-resize {1}" optimize: "-strip" + ezsettings.default.image_host: '' + ### # default ezpage settings ## diff --git a/eZ/Bundle/EzPublishCoreBundle/Resources/config/image.yml b/eZ/Bundle/EzPublishCoreBundle/Resources/config/image.yml index ad33469c1f6..8c8b635c928 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Resources/config/image.yml +++ b/eZ/Bundle/EzPublishCoreBundle/Resources/config/image.yml @@ -1,6 +1,8 @@ parameters: ezpublish.image_alias.imagine.binary_loader.class: eZ\Bundle\EzPublishCoreBundle\Imagine\BinaryLoader + ezpublish.image_alias.imagine.decorated_cache_resolver_factory.class: eZ\Bundle\EzPublishCoreBundle\Imagine\ResolverFactory ezpublish.image_alias.imagine.cache_resolver.class: eZ\Bundle\EzPublishCoreBundle\Imagine\IORepositoryResolver + ezpublish.image_alias.imagine.cache_resolver_decorator.class: Liip\ImagineBundle\Imagine\Cache\Resolver\ProxyResolver ezpublish.image_alias.imagine.cache.alias_generator_decorator.class: eZ\Bundle\EzPublishCoreBundle\Imagine\Cache\AliasGeneratorDecorator ezpublish.image_alias.imagine.variation.imagine_alias_generator.class: eZ\Bundle\EzPublishCoreBundle\Imagine\Variation\ImagineAwareAliasGenerator ezpublish.image_alias.imagine.alias_generator.class: eZ\Bundle\EzPublishCoreBundle\Imagine\AliasGenerator @@ -81,6 +83,18 @@ services: tags: - { name: liip_imagine.cache.resolver, resolver: ezpublish } + ezpublish.image_alias.imagine.cache_resolver_decorator_factory: + class: '%ezpublish.image_alias.imagine.decorated_cache_resolver_factory.class%' + arguments: + - '@ezpublish.config.resolver' + - '@ezpublish.image_alias.imagine.cache_resolver_decorator.inner' + - '%ezpublish.image_alias.imagine.cache_resolver_decorator.class%' + + ezpublish.image_alias.imagine.cache_resolver_decorator: + class: '%ezpublish.image_alias.imagine.cache_resolver_decorator.class%' + factory: 'ezpublish.image_alias.imagine.cache_resolver_decorator_factory:createCacheResolver' + decorates: ezpublish.image_alias.imagine.cache_resolver + ezpublish.image_alias.imagine.cache.alias_generator_decorator: class: '%ezpublish.image_alias.imagine.cache.alias_generator_decorator.class%' arguments: diff --git a/eZ/Bundle/EzPublishCoreBundle/Resources/config/services.yml b/eZ/Bundle/EzPublishCoreBundle/Resources/config/services.yml index b906f670864..576f56aa426 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Resources/config/services.yml +++ b/eZ/Bundle/EzPublishCoreBundle/Resources/config/services.yml @@ -250,6 +250,15 @@ services: tags: - { name: console.command } + ezplatform.core.command.cleanup_versions: + class: eZ\Bundle\EzPublishCoreBundle\Command\CleanupVersionsCommand + arguments: + - "@ezpublish.signalslot.repository" + - "@ezpublish.api.repository_configuration_provider" + - "@ezpublish.persistence.connection" + tags: + - { name: console.command } + ezplatform.core.session.handler.native_redis: class: eZ\Bundle\EzPublishCoreBundle\Session\Handler\NativeSessionHandler arguments: diff --git a/eZ/Publish/Core/Persistence/Cache/ContentHandler.php b/eZ/Publish/Core/Persistence/Cache/ContentHandler.php index 5e650557751..62e33b56a0e 100644 --- a/eZ/Publish/Core/Persistence/Cache/ContentHandler.php +++ b/eZ/Publish/Core/Persistence/Cache/ContentHandler.php @@ -64,13 +64,12 @@ public function copy($contentId, $versionNo = null, $newOwnerId = null) /** * {@inheritdoc} - * - * @todo Add support for setting version number to null in order to reuse cache with loadContentList. */ - public function load($contentId, $versionNo, array $translations = null) + public function load($contentId, $versionNo = null, array $translations = null) { + $versionKey = $versionNo ? "-${versionNo}" : ''; $translationsKey = empty($translations) ? self::ALL_TRANSLATIONS_KEY : implode('|', $translations); - $cacheItem = $this->cache->getItem("ez-content-${contentId}-${versionNo}-${translationsKey}"); + $cacheItem = $this->cache->getItem("ez-content-${contentId}${versionKey}-${translationsKey}"); if ($cacheItem->isHit()) { return $cacheItem->get(); } diff --git a/eZ/Publish/Core/Persistence/Legacy/Content/Gateway.php b/eZ/Publish/Core/Persistence/Legacy/Content/Gateway.php index c1e642eb3ec..14b2675fb31 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Content/Gateway.php +++ b/eZ/Publish/Core/Persistence/Legacy/Content/Gateway.php @@ -144,12 +144,12 @@ abstract public function updateNonTranslatableField( * Returns an array with the relevant data. * * @param mixed $contentId - * @param mixed $version + * @param int|null $version Current version on null value. * @param string[] $translations * * @return array */ - abstract public function load($contentId, $version, array $translations = null); + abstract public function load($contentId, $version = null, array $translations = null); /** * Loads current version for a list of content objects. diff --git a/eZ/Publish/Core/Persistence/Legacy/Content/Gateway/DoctrineDatabase.php b/eZ/Publish/Core/Persistence/Legacy/Content/Gateway/DoctrineDatabase.php index efe7ec7920d..3f7e36403c6 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Content/Gateway/DoctrineDatabase.php +++ b/eZ/Publish/Core/Persistence/Legacy/Content/Gateway/DoctrineDatabase.php @@ -826,11 +826,9 @@ public function updateNonTranslatableField( /** * {@inheritdoc} */ - public function load($contentId, $version, array $translations = null) + public function load($contentId, $version = null, array $translations = null) { - $results = $this->internalLoadContent([$contentId], $version, $translations); - - return $results; + return $this->internalLoadContent([$contentId], $version, $translations); } /** @@ -845,7 +843,7 @@ public function loadContentList(array $contentIds, array $translations = null): * @see load(), loadContentList() * * @param array $contentIds - * @param int $version + * @param int|null $version * @param string[]|null $translations * * @return array diff --git a/eZ/Publish/Core/Persistence/Legacy/Content/Gateway/ExceptionConversion.php b/eZ/Publish/Core/Persistence/Legacy/Content/Gateway/ExceptionConversion.php index 38f83f09c88..2a5fa45394d 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Content/Gateway/ExceptionConversion.php +++ b/eZ/Publish/Core/Persistence/Legacy/Content/Gateway/ExceptionConversion.php @@ -255,17 +255,9 @@ public function updateNonTranslatableField( } /** - * Loads data for a content object. - * - * Returns an array with the relevant data. - * - * @param mixed $contentId - * @param mixed $version - * @param string[] $translations - * - * @return array + * {@inheritdoc} */ - public function load($contentId, $version, array $translations = null) + public function load($contentId, $version = null, array $translations = null) { try { return $this->innerGateway->load($contentId, $version, $translations); diff --git a/eZ/Publish/Core/Persistence/Legacy/Content/Handler.php b/eZ/Publish/Core/Persistence/Legacy/Content/Handler.php index 7b5a5182e09..310d7c8e394 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Content/Handler.php +++ b/eZ/Publish/Core/Persistence/Legacy/Content/Handler.php @@ -303,23 +303,9 @@ public function createDraftFromVersion($contentId, $srcVersion, $userId) } /** - * Returns the raw data of a content object identified by $id, in a struct. - * - * A version to load must be specified. If you want to load the current - * version of a content object use SearchHandler::findSingle() with the - * ContentId criterion. - * - * Optionally a translation filter may be specified. If specified only the - * translations with the listed language codes will be retrieved. If not, - * all translations will be retrieved. - * - * @param int|string $id - * @param int|string $version - * @param string[] $translations - * - * @return \eZ\Publish\SPI\Persistence\Content Content value object + * {@inheritdoc} */ - public function load($id, $version, array $translations = null) + public function load($id, $version = null, array $translations = null) { $rows = $this->contentGateway->load($id, $version, $translations); @@ -329,7 +315,10 @@ public function load($id, $version, array $translations = null) $contentObjects = $this->mapper->extractContentFromRows( $rows, - $this->contentGateway->loadVersionedNameData(array(array('id' => $id, 'version' => $version))) + $this->contentGateway->loadVersionedNameData([[ + 'id' => $id, + 'version' => $rows[0]['ezcontentobject_version_version'], + ]]) ); $content = $contentObjects[0]; unset($rows, $contentObjects); diff --git a/eZ/Publish/Core/Persistence/Legacy/Tests/Content/ContentHandlerTest.php b/eZ/Publish/Core/Persistence/Legacy/Tests/Content/ContentHandlerTest.php index e56a8649418..002a5de4fc3 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Tests/Content/ContentHandlerTest.php +++ b/eZ/Publish/Core/Persistence/Legacy/Tests/Content/ContentHandlerTest.php @@ -256,15 +256,15 @@ public function testPublishFirstVersion() ) ); + $contentRows = [['ezcontentobject_version_version' => 1]]; + $gatewayMock->expects($this->once()) ->method('load') ->with( $this->equalTo(23), $this->equalTo(1), $this->equalTo(null) - )->will( - $this->returnValue(array(42)) - ); + )->willReturn($contentRows); $gatewayMock->expects($this->once()) ->method('loadVersionedNameData') @@ -276,7 +276,7 @@ public function testPublishFirstVersion() $mapperMock->expects($this->once()) ->method('extractContentFromRows') - ->with($this->equalTo(array(42)), $this->equalTo(array(22))) + ->with($this->equalTo($contentRows), $this->equalTo(array(22))) ->will($this->returnValue(array($this->getContentFixtureForDraft()))); $fieldHandlerMock->expects($this->once()) @@ -333,6 +333,8 @@ public function testPublish() ->method('setStatus') ->with(23, VersionInfo::STATUS_ARCHIVED, 1); + $contentRows = [['ezcontentobject_version_version' => 2]]; + $gatewayMock->expects($this->once()) ->method('load') ->with( @@ -340,7 +342,7 @@ public function testPublish() $this->equalTo(2), $this->equalTo(null) ) - ->will($this->returnValue(array(42))); + ->willReturn($contentRows); $gatewayMock->expects($this->once()) ->method('loadVersionedNameData') @@ -352,7 +354,7 @@ public function testPublish() $mapperMock->expects($this->once()) ->method('extractContentFromRows') - ->with($this->equalTo(array(42)), $this->equalTo(array(22))) + ->with($this->equalTo($contentRows), $this->equalTo(array(22))) ->will($this->returnValue(array($this->getContentFixtureForDraft()))); $fieldHandlerMock->expects($this->once()) @@ -484,6 +486,8 @@ public function testLoad() $mapperMock = $this->getMapperMock(); $fieldHandlerMock = $this->getFieldHandlerMock(); + $contentRows = [['ezcontentobject_version_version' => 2]]; + $gatewayMock->expects($this->once()) ->method('load') ->with( @@ -491,7 +495,7 @@ public function testLoad() $this->equalTo(2), $this->equalTo(array('eng-GB')) )->will( - $this->returnValue(array(42)) + $this->returnValue($contentRows) ); $gatewayMock->expects($this->once()) @@ -504,7 +508,7 @@ public function testLoad() $mapperMock->expects($this->once()) ->method('extractContentFromRows') - ->with($this->equalTo(array(42)), $this->equalTo(array(22))) + ->with($this->equalTo($contentRows), $this->equalTo(array(22))) ->will($this->returnValue(array($this->getContentFixtureForDraft()))); $fieldHandlerMock->expects($this->once()) diff --git a/eZ/Publish/Core/Repository/ContentService.php b/eZ/Publish/Core/Repository/ContentService.php index a74481fd96a..51eb4e598e3 100644 --- a/eZ/Publish/Core/Repository/ContentService.php +++ b/eZ/Publish/Core/Repository/ContentService.php @@ -224,6 +224,7 @@ public function loadVersionInfo(ContentInfo $contentInfo, $versionNo = null) */ public function loadVersionInfoById($contentId, $versionNo = null) { + // @todo SPI should also support null to avoid concurrency issues if ($versionNo === null) { $versionNo = $this->loadContentInfo($contentId)->currentVersionNo; } @@ -269,15 +270,10 @@ public function loadContentByContentInfo(ContentInfo $contentInfo, array $langua $useAlwaysAvailable = false; } - // As we have content info we can avoid that current version is looked up using spi in loadContent() if not set - if ($versionNo === null) { - $versionNo = $contentInfo->currentVersionNo; - } - return $this->loadContent( $contentInfo->id, $languages, - $versionNo, + $versionNo,// On purpose pass as-is and not use $contentInfo, to make sure to return actual current version on null $useAlwaysAvailable ); } @@ -348,18 +344,10 @@ public function internalLoadContent($id, array $languages = null, $versionNo = n $isRemoteId = false; } - // Get current version if $versionNo is not defined - if ($versionNo === null) { - if (!isset($spiContentInfo)) { - $spiContentInfo = $this->persistenceHandler->contentHandler()->loadContentInfo($id); - } - - $versionNo = $spiContentInfo->currentVersionNo; - } - $loadLanguages = $languages; $alwaysAvailableLanguageCode = null; // Set main language on $languages filter if not empty (all) and $useAlwaysAvailable being true + // @todo Move use always available logic to SPI load methods, like done in location handler in 7.x if (!empty($loadLanguages) && $useAlwaysAvailable) { if (!isset($spiContentInfo)) { $spiContentInfo = $this->persistenceHandler->contentHandler()->loadContentInfo($id); diff --git a/eZ/Publish/Core/Repository/Tests/Service/Mock/ContentTest.php b/eZ/Publish/Core/Repository/Tests/Service/Mock/ContentTest.php index e3714460fe1..96a28afe030 100644 --- a/eZ/Publish/Core/Repository/Tests/Service/Mock/ContentTest.php +++ b/eZ/Publish/Core/Repository/Tests/Service/Mock/ContentTest.php @@ -518,26 +518,16 @@ public function testInternalLoadContent($id, $languages, $versionNo, $isRemoteId $contentService = $this->getPartlyMockedContentService(); /** @var \PHPUnit\Framework\MockObject\MockObject $contentHandler */ $contentHandler = $this->getPersistenceMock()->contentHandler(); - $realVersionNo = $versionNo; $realId = $id; if ($isRemoteId) { - $realVersionNo = $versionNo ?: 7; $realId = 123; - $spiContentInfo = new SPIContentInfo(array('currentVersionNo' => $realVersionNo, 'id' => $realId)); + $spiContentInfo = new SPIContentInfo(array('currentVersionNo' => $versionNo ?: 7, 'id' => $realId)); $contentHandler ->expects($this->once()) ->method('loadContentInfoByRemoteId') ->with($id) ->will($this->returnValue($spiContentInfo)); - } elseif ($versionNo === null) { - $realVersionNo = 7; - $spiContentInfo = new SPIContentInfo(array('currentVersionNo' => $realVersionNo)); - $contentHandler - ->expects($this->once()) - ->method('loadContentInfo') - ->with($id) - ->will($this->returnValue($spiContentInfo)); } elseif (!empty($languages) && $useAlwaysAvailable) { $spiContentInfo = new SPIContentInfo(array('alwaysAvailable' => false)); $contentHandler @@ -551,7 +541,7 @@ public function testInternalLoadContent($id, $languages, $versionNo, $isRemoteId $contentHandler ->expects($this->once()) ->method('load') - ->with($realId, $realVersionNo, $languages) + ->with($realId, $versionNo, $languages) ->will($this->returnValue($spiContent)); $content = $this->createMock(APIContent::class); $this->getDomainMapperMock() diff --git a/eZ/Publish/SPI/Persistence/Content/Handler.php b/eZ/Publish/SPI/Persistence/Content/Handler.php index 3b2fb22fd93..3572b6f8f2f 100644 --- a/eZ/Publish/SPI/Persistence/Content/Handler.php +++ b/eZ/Publish/SPI/Persistence/Content/Handler.php @@ -51,21 +51,21 @@ public function createDraftFromVersion($contentId, $srcVersion, $userId); /** * Returns the raw data of a content object identified by $id, in a struct. * - * A version to load must be specified. If you want to load the current - * version of a content object use SearchHandler::findSingle() with the - * ContentId criterion. + * If you want to load current version, $version number can be omitted to make sure + * you don't need to rely on search index (async) or having to load in two steps + * (first content info then content, risking changes in between to current version). * * Optionally a translation filter may be specified. If specified only the * translations with the listed language codes will be retrieved. If not, * all translations will be retrieved. * * @param int|string $id - * @param int|string $version + * @param int|null $version * @param string[]|null $translations * * @return \eZ\Publish\SPI\Persistence\Content Content value object */ - public function load($id, $version, array $translations = null); + public function load($id, $version = null, array $translations = null); /** * Return list of unique Content, with content id as key.