Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/1.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
webhdx committed Nov 9, 2021
2 parents 91be40a + db2e63e commit 4ef0f00
Show file tree
Hide file tree
Showing 9 changed files with 520 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ private function handleApiLoading(ContainerBuilder $container, FileLoader $loade
$coreLoader->load('user_preference.yml');
$coreLoader->load('events.yml');
$coreLoader->load('thumbnails.yml');
$coreLoader->load('content_location_mapper.yml');

// Public API services
$loader->load('papi.yml');
Expand Down
7 changes: 3 additions & 4 deletions eZ/Publish/Core/Repository/Mapper/Readme.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Mappers

Collection of light mappers meant for internal use in Repository
and/or RepositoryServices.
Collection of light mappers meant for internal use by Ibexa packages only.

Given their use they can not rely on Repository or RepositoryServices as
that will lead to cyclic dependencies, they can only rely on SPI and other helpers.
Given their use they should not rely on Repository or RepositoryServices as
that will lead to cyclic dependencies, they should only rely on SPI and other helpers.
1 change: 1 addition & 0 deletions eZ/Publish/Core/settings/containerBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
$loader->load('policies.yml');
$loader->load('events.yml');
$loader->load('thumbnails.yml');
$loader->load('content_location_mapper.yml');

// Cache settings (takes same env variables as ezplatform does, only supports "singleredis" setup)
if (getenv('CUSTOM_CACHE_POOL') === 'singleredis') {
Expand Down
14 changes: 14 additions & 0 deletions eZ/Publish/Core/settings/content_location_mapper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
services:
_defaults:
autoconfigure: true
autowire: true
public: true

Ibexa\Core\Repository\Mapper\ContentLocationMapper\InMemoryContentLocationMapper: ~

Ibexa\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper: '@Ibexa\Core\Repository\Mapper\ContentLocationMapper\InMemoryContentLocationMapper'

Ibexa\Core\Repository\Mapper\ContentLocationMapper\DecoratedLocationService:
decorates: ezpublish.api.service.inner_location
arguments:
$innerService: '@.inner'
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Core\Repository\Mapper\ContentLocationMapper;

/**
* @internal For internal use by Ibexa packages only
*/
interface ContentLocationMapper
{
public function hasMapping(int $locationId): bool;

public function getMapping(int $locationId): int;

public function setMapping(int $locationId, int $contentId): void;

public function removeMapping(int $locationId): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Core\Repository\Mapper\ContentLocationMapper;

use eZ\Publish\API\Repository\LocationService as RepositoryLocationService;
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
use eZ\Publish\API\Repository\Values\Content\Location;
use eZ\Publish\API\Repository\Values\Content\LocationList;
use eZ\Publish\SPI\Repository\Decorator\LocationServiceDecorator;

/**
* Service decorator hooking ContentLocationMapper to load* calls.
*
* @internal
*/
final class DecoratedLocationService extends LocationServiceDecorator
{
/** @var \Ibexa\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper */
private $contentLocationMapper;

public function __construct(
RepositoryLocationService $innerService,
ContentLocationMapper $contentLocationMapper
) {
parent::__construct($innerService);

$this->contentLocationMapper = $contentLocationMapper;
}

public function loadLocation(
int $locationId,
?array $prioritizedLanguages = null,
?bool $useAlwaysAvailable = null
): Location {
$location = $this->innerService->loadLocation(
$locationId,
$prioritizedLanguages,
$useAlwaysAvailable
);

$this->contentLocationMapper->setMapping(
$locationId,
$location->contentId
);

return $location;
}

public function loadLocationList(
array $locationIds,
?array $prioritizedLanguages = null,
?bool $useAlwaysAvailable = null
): iterable {
$locationList = $this->innerService->loadLocationList(
$locationIds,
$prioritizedLanguages,
$useAlwaysAvailable
);

$this->setLocationMappings($locationList);

return $locationList;
}

public function loadLocations(
ContentInfo $contentInfo,
?Location $rootLocation = null,
?array $prioritizedLanguages = null
): iterable {
$locations = $this->innerService->loadLocations(
$contentInfo,
$rootLocation,
$prioritizedLanguages
);

$this->setLocationMappings($locations);

return $locations;
}

public function loadLocationChildren(
Location $location,
int $offset = 0,
int $limit = 25,
?array $prioritizedLanguages = null
): LocationList {
$locationChildren = $this->innerService->loadLocationChildren(
$location,
$offset,
$limit,
$prioritizedLanguages
);

$this->setLocationMappings($locationChildren->locations);

return $locationChildren;
}

public function loadAllLocations(
int $offset = 0,
int $limit = 25
): array {
$locations = $this->innerService->loadAllLocations(
$offset,
$limit
);

$this->setLocationMappings($locations);

return $locations;
}

/**
* @param iterable<\eZ\Publish\API\Repository\Values\Content\Location>
*/
private function setLocationMappings(iterable $locationList): void
{
foreach ($locationList as $location) {
$this->contentLocationMapper->setMapping(
$location->id,
$location->contentId
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Core\Repository\Mapper\ContentLocationMapper;

/**
* Retrieves Content ID from Location ID.
*
* Helps in scenarios where you need to retrieve Content IDs from
* a large location list. You'd normally do LocationService::loadLocation call
* for every Location ID which requires a lot of memory.
*
* It works by tracing all loadLocation calls via Service\LocationService decorator
* and updating the map accordingly. Currently, in memory cache mechanism is used but
* can be further optimized by implementing persistence cache.
*
* @internal For internal use by Ibexa packages only
*/
final class InMemoryContentLocationMapper implements ContentLocationMapper
{
/** @var Array<int, int> */
private $map;

/**
* @param int[] $map
*/
public function __construct(array $map = [])
{
$this->map = $map;
}

public function hasMapping(int $locationId): bool
{
return isset($this->map[$locationId]);
}

public function getMapping(int $locationId): int
{
return $this->map[$locationId];
}

public function setMapping(int $locationId, int $contentId): void
{
$this->map[$locationId] = $contentId;
}

public function removeMapping(int $locationId): void
{
unset($this->map[$locationId]);
}
}
Loading

0 comments on commit 4ef0f00

Please sign in to comment.