Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bundle/Controller/LocationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public function swapAction(Request $request): Response
$currentLocation = $data->getCurrentLocation();
$newLocation = $data->getNewLocation();

$childCount = $this->locationService->getLocationChildCount($currentLocation);
$childCount = $this->locationService->getLocationChildCount($currentLocation, 1);
$contentType = $newLocation?->getContent()->getContentType();

if (!$contentType?->isContainer() && $childCount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
* subtree_operations:
* copy_subtree:
* limit: 200
* query_subtree:
* limit: 500
* ```
*/
final class SubtreeOperations extends AbstractParser
Expand All @@ -35,15 +37,25 @@ public function mapConfig(
mixed $currentScope,
ContextualizerInterface $contextualizer
): void {
if (!isset($scopeSettings['subtree_operations']['copy_subtree']['limit'])) {
if (!isset($scopeSettings['subtree_operations'])) {
return;
}

$contextualizer->setContextualParameter(
'subtree_operations.copy_subtree.limit',
$currentScope,
$scopeSettings['subtree_operations']['copy_subtree']['limit']
);
if (isset($scopeSettings['subtree_operations']['copy_subtree']['limit'])) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those changes should be reflected in Ibexa\Tests\Bundle\AdminUi\DependencyInjection\Configuration\Parser\SubtreeOperationsTest.

$contextualizer->setContextualParameter(
'subtree_operations.copy_subtree.limit',
$currentScope,
$scopeSettings['subtree_operations']['copy_subtree']['limit']
);
}

if (isset($scopeSettings['subtree_operations']['query_subtree']['limit'])) {
$contextualizer->setContextualParameter(
'subtree_operations.query_subtree.limit',
$currentScope,
$scopeSettings['subtree_operations']['query_subtree']['limit']
);
}
}

public function addSemanticConfig(NodeBuilder $nodeBuilder): void
Expand All @@ -60,6 +72,12 @@ public function addSemanticConfig(NodeBuilder $nodeBuilder): void
->end()
->end()
->end()
->arrayNode('query_subtree')
->children()
->integerNode('limit')
->info('Limit the total count of items queried for when calculating the number of direct children a node has. -1 for no limit.')
->end()
->end()
->end()
->end();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ parameters:

# Subtree Operations
ibexa.site_access.config.admin_group.subtree_operations.copy_subtree.limit: 100
ibexa.site_access.config.admin_group.subtree_operations.query_subtree.limit: 500

# Notifications
ibexa.site_access.config.admin_group.notification_count.interval: 30000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
}]) %}

{% set body_row_cols = body_row_cols|merge([
{ content: location.childCount },
{ content: location.childCount is null ? (sub_item_query_limit ~ '+') : location.childCount },
]) %}

{% set body_rows = body_rows|merge([{ cols: body_row_cols }]) %}
Expand Down
13 changes: 10 additions & 3 deletions src/lib/Form/TrashLocationOptionProvider/HasChildren.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Ibexa\AdminUi\Specification\Location\HasChildren as HasChildrenSpec;
use Ibexa\Contracts\Core\Repository\LocationService;
use Ibexa\Contracts\Core\Repository\Values\Content\Location;
use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
use JMS\TranslationBundle\Annotation\Desc;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormInterface;
Expand All @@ -20,7 +21,8 @@
{
public function __construct(
private LocationService $locationService,
private TranslatorInterface $translator
private TranslatorInterface $translator,
private ConfigResolverInterface $configResolver
) {
}

Expand All @@ -31,10 +33,15 @@ public function supports(Location $location): bool

public function addOptions(FormInterface $form, Location $location): void
{
$childCount = $this->locationService->getLocationChildCount($location);
$limit = (int) $this->configResolver->getParameter('subtree_operations.query_subtree.limit');

$useLimit = $limit > 0;
$childCount = $this->locationService->getLocationChildCount($location, $useLimit ? $limit + 1 : null);

$translatorParameters = [
'%children_count%' => $childCount,
'%children_count%' => ($useLimit && $childCount >= $limit) ?
sprintf('%d+', $limit) :
$childCount,
'%content%' => $location->getContent()->getName(),
];

Expand Down
2 changes: 1 addition & 1 deletion src/lib/Specification/Location/HasChildren.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function __construct(private readonly LocationService $locationService)
*/
public function isSatisfiedBy(mixed $item): bool
{
$childCount = $this->locationService->getLocationChildCount($item);
$childCount = $this->locationService->getLocationChildCount($item, 1);

return 0 < $childCount;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function isSatisfiedBy(mixed $item): bool
return false;
}

return $this->copyLimit >= $this->locationService->getSubtreeSize($item);
return $this->copyLimit >= $this->locationService->getSubtreeSize($item, $this->copyLimit + 1);
}

private function isContainer(Location $location): bool
Expand Down
6 changes: 6 additions & 0 deletions src/lib/Tab/LocationView/LocationsTab.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,18 @@ public function getTemplateParameters(array $contextParameters = []): array
);
}

$subItemQueryLimit = $this->configResolver->getParameter('subtree_operations.query_subtree.limit');
if ($subItemQueryLimit <= 0) {
$subItemQueryLimit = null;
}

$viewParameters = [
'pager' => $pagination,
'pager_options' => [
'pageParameter' => sprintf('[%s]', self::PAGINATION_PARAM_NAME),
],
'locations' => $locations,
'sub_item_query_limit' => $subItemQueryLimit,
'form_content_location_add' => $formLocationAdd->createView(),
'form_content_location_remove' => $formLocationRemove->createView(),
'form_content_location_swap' => $formLocationSwap->createView(),
Expand Down
7 changes: 6 additions & 1 deletion src/lib/UI/Module/Subitems/ContentViewParameterSupplier.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,12 @@ private function createRestLocation(Location $location): RestLocation
{
return new RestLocation(
$location,
$this->locationService->getLocationChildCount($location)
$this->locationService->getLocationChildCount(
$location,
// For the sub items module we only ever use the count to determine if there are children (0 or 1+),
// hence setting a limit of 1 is sufficient here.
1
)
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/UI/Value/Content/Location.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/
class Location extends CoreLocation
{
protected int $childCount;
protected ?int $childCount;

protected bool $main;

Expand Down
9 changes: 7 additions & 2 deletions src/lib/UI/Value/ValueFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
use Ibexa\Contracts\Core\Repository\Values\ObjectState\ObjectStateGroup;
use Ibexa\Contracts\Core\Repository\Values\User\Policy;
use Ibexa\Contracts\Core\Repository\Values\User\RoleAssignment;
use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
use Ibexa\Core\MVC\Symfony\Locale\UserLanguagePreferenceProviderInterface;
use Ibexa\Core\Repository\LocationResolver\LocationResolver;
use RuntimeException;
Expand All @@ -53,7 +54,8 @@ public function __construct(
protected PathService $pathService,
protected DatasetFactory $datasetFactory,
private UserLanguagePreferenceProviderInterface $userLanguagePreferenceProvider,
protected LocationResolver $locationResolver
protected LocationResolver $locationResolver,
protected ConfigResolverInterface $configResolver,
) {
}

Expand Down Expand Up @@ -137,9 +139,12 @@ public function createLocation(Location $location): UIValue\Content\Location
{
$translations = $location->getContent()->getVersionInfo()->getLanguageCodes();
$target = (new Target\Version())->deleteTranslations($translations);
$limit = $this->configResolver->getParameter('subtree_operations.query_subtree.limit');
$useLimit = $limit > 0;
$count = $this->locationService->getLocationChildCount($location, $useLimit ? $limit : null);

return new UIValue\Content\Location($location, [
'childCount' => $this->locationService->getLocationChildCount($location),
'childCount' => $useLimit && $count >= $limit ? null : $count,
'pathLocations' => $this->pathService->loadPathLocations($location),
'userCanManage' => $this->permissionResolver->canUser(
'content',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ public function getExpectedCopySubtreeLimit(): iterable
yield 'disabled = 0' => [0];
}

/**
* @return iterable<string, array{int|null}>
*/
public function getExpectedQuerySubtreeLimit(): iterable
{
yield 'no limit = -1' => [-1];
yield 'custom limit = 1000' => [1000];
yield 'disabled = 0' => [0];
}

protected function setUp(): void
{
$this->parser = new SubtreeOperations();
Expand Down Expand Up @@ -77,4 +87,79 @@ public function testCopySubtreeLimitNotSet(): void

$this->parser->mapConfig($scopeSettings, $currentScope, $this->contextualizer);
}

/**
* @dataProvider getExpectedQuerySubtreeLimit
*/
public function testQuerySubtreeLimit(int $expectedQuerySubtreeLimit): void
{
$scopeSettings = [
'subtree_operations' => [
'query_subtree' => [
'limit' => $expectedQuerySubtreeLimit,
],
],
];
$currentScope = 'admin_group';

$this->contextualizer
->expects(self::once())
->method('setContextualParameter')
->with(
'subtree_operations.query_subtree.limit',
$currentScope,
$expectedQuerySubtreeLimit
);

$this->parser->mapConfig($scopeSettings, $currentScope, $this->contextualizer);
}

public function testQuerySubtreeLimitNotSet(): void
{
$scopeSettings = [
'subtree_operations' => [
'query_subtree' => null,
],
];
$currentScope = 'admin_group';

$this->contextualizer
->expects(self::never())
->method('setContextualParameter');

$this->parser->mapConfig($scopeSettings, $currentScope, $this->contextualizer);
}

public function testBothSubtreeOperationsSet(): void
{
$scopeSettings = [
'subtree_operations' => [
'copy_subtree' => [
'limit' => 200,
],
'query_subtree' => [
'limit' => 500,
],
],
];
$currentScope = 'admin_group';

$this->contextualizer
->expects(self::exactly(2))
->method('setContextualParameter')
->withConsecutive(
[
'subtree_operations.copy_subtree.limit',
$currentScope,
200,
],
[
'subtree_operations.query_subtree.limit',
$currentScope,
500,
]
);

$this->parser->mapConfig($scopeSettings, $currentScope, $this->contextualizer);
}
}
Loading