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.