Skip to content

[CI] [POC] Added code samples testing with Deptrac #2562

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: 5.0
Choose a base branch
from
Open

Conversation

mnocon
Copy link
Contributor

@mnocon mnocon commented Nov 30, 2024

Target: master, 4.6

Deptrac is a code testing tool for architecture.

I've added a very simple ruleset - code samples should not use classes outside of the Ibexa\Contracts namespace.

This tool should act as a:

  1. sanity check when adding code samples (as it's easy to miss the non-Contracts usage that can be replaced with their Contracts counterpart)
  2. point for discussion with developers (is there a Contracts-compliant way of writing the code sample)

But we will never get rid of all the errors, as they would require architecture changes on the DXP side - so we will have to keep expanding the baseline with new code samples.

Commits:

  • f4593c0 adds the tool configuration
  • da0eced fixes some low hanging fruits and generates the baseline

Generated baseline:
https://github.com/ibexa/documentation-developer/blob/add-deptrac/deptrac.baseline.yaml

@mnocon mnocon force-pushed the add-deptrac branch 2 times, most recently from a226602 to da0eced Compare November 30, 2024 10:20
@mnocon mnocon marked this pull request as ready for review December 2, 2024 10:52
@mnocon mnocon changed the title [CI] Added code samples testing with Deptrac [CI] [POC] Added code samples testing with Deptrac Dec 2, 2024
@ibexa ibexa deleted a comment from github-actions bot Feb 5, 2025
@mnocon mnocon changed the base branch from master to 5.0 May 19, 2025 07:28
Copy link

Preview of modified files

Preview of modified Markdown:

Copy link

code_samples/ change report

Before (on target branch)After (in current PR)

code_samples/api/commerce/src/Command/CartCommand.php

docs/commerce/cart/cart_api.md@25:``` php
docs/commerce/cart/cart_api.md@26:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 91) =]]
docs/commerce/cart/cart_api.md@27:```

001⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
002⫶
003⫶ $output->writeln($cart->getName());

docs/commerce/cart/cart_api.md@34:``` php
docs/commerce/cart/cart_api.md@35:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 10, 11) =]]
docs/commerce/cart/cart_api.md@36:// ...
docs/commerce/cart/cart_api.md@37:
docs/commerce/cart/cart_api.md@38:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 74, 83) =]]
docs/commerce/cart/cart_api.md@39:```

001⫶use Ibexa\Contracts\Cart\Value\CartQuery;
002⫶
003⫶// ...
004⫶
005⫶ $cartQuery = new CartQuery();
006⫶ $cartQuery->setOwnerId(14); // carts created by User ID: 14
007⫶ $cartQuery->setLimit(20); // fetch 20 carts
008⫶
009⫶ $cartsList = $this->cartService->findCarts($cartQuery);
010⫶
011⫶ $cartsList->getCarts(); // array of CartInterface objects
012⫶ $cartsList->getTotalCount(); // number of returned carts

docs/commerce/cart/cart_api.md@45:``` php
docs/commerce/cart/cart_api.md@46:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 8, 9) =]]
docs/commerce/cart/cart_api.md@47:// ...
docs/commerce/cart/cart_api.md@48:
docs/commerce/cart/cart_api.md@49:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 95, 104) =]]
docs/commerce/cart/cart_api.md@50:```

001⫶use Ibexa\Contracts\Cart\Value\CartCreateStruct;
002⫶
003⫶// ...
004⫶
005⫶ $cartCreateStruct = new CartCreateStruct(
006⫶ 'Default cart',
007⫶ $currency // Ibexa\Contracts\ProductCatalog\Values\CurrencyInterface
008⫶ );
009⫶
010⫶ $cart = $this->cartService->createCart($cartCreateStruct);
011⫶
012⫶ $output->writeln($cart->getName()); // prints 'Default cart' to the console

docs/commerce/cart/cart_api.md@58:``` php
docs/commerce/cart/cart_api.md@59:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 9, 10) =]]
docs/commerce/cart/cart_api.md@60:// ...
docs/commerce/cart/cart_api.md@61:
docs/commerce/cart/cart_api.md@62:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 107, 114) =]]
docs/commerce/cart/cart_api.md@63:```

001⫶use Ibexa\Contracts\Cart\Value\CartMetadataUpdateStruct;
002⫶
003⫶// ...
004⫶
005⫶ $cartUpdateMetadataStruct = new CartMetadataUpdateStruct();
006⫶ $cartUpdateMetadataStruct->setName('New name');
007⫶ $cartUpdateMetadataStruct->setCurrency($newCurrency);
008⫶
009⫶ $updatedCart = $this->cartService->updateCartMetadata($cart, $cartUpdateMetadataStruct);
010⫶
011⫶ $output->writeln($updatedCart->getName()); // prints 'New name' to the console

docs/commerce/cart/cart_api.md@82:``` php
docs/commerce/cart/cart_api.md@83:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@84:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 149, 150) =]]
docs/commerce/cart/cart_api.md@85:```

001⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
002⫶
003⫶ $this->cartService->deleteCart($cart);

docs/commerce/cart/cart_api.md@91:``` php
docs/commerce/cart/cart_api.md@92:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@93:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 116, 117) =]]
docs/commerce/cart/cart_api.md@94:```

001⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
002⫶
003⫶ $this->cartService->emptyCart($cart);

docs/commerce/cart/cart_api.md@103:``` php
docs/commerce/cart/cart_api.md@104:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@105:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 119, 120) =]]
docs/commerce/cart/cart_api.md@106:```

001⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
002⫶
003⫶ $violationList = $this->cartService->validateCart($cart); // Symfony\Component\Validator\ConstraintViolationListInterface

docs/commerce/cart/cart_api.md@113:``` php
docs/commerce/cart/cart_api.md@114:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 11, 12) =]]
docs/commerce/cart/cart_api.md@115:// ...
docs/commerce/cart/cart_api.md@116:
docs/commerce/cart/cart_api.md@117:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@118:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 124, 131) =]]
docs/commerce/cart/cart_api.md@119:```

001⫶use Ibexa\Contracts\Cart\Value\EntryAddStruct;
002⫶
003⫶// ...
004⫶
005⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
006⫶
007⫶ $entryAddStruct = new EntryAddStruct($product);
008⫶ $entryAddStruct->setQuantity(10);
009⫶
010⫶ $cart = $this->cartService->addEntry($cart, $entryAddStruct);
011⫶
012⫶ $entry = $cart->getEntries()->first();
013⫶ $output->writeln($entry->getProduct()->getName()); // prints product name to the console

docs/commerce/cart/cart_api.md@125:``` php
docs/commerce/cart/cart_api.md@126:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 11, 12) =]]
docs/commerce/cart/cart_api.md@127:// ...
docs/commerce/cart/cart_api.md@128:
docs/commerce/cart/cart_api.md@129:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@130:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 134, 137) =]]
docs/commerce/cart/cart_api.md@131:```

001⫶use Ibexa\Contracts\Cart\Value\EntryAddStruct;
002⫶
003⫶// ...
004⫶
005⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
006⫶
007⫶ $entry = $cart->getEntries()->first();
008⫶
009⫶ $cart = $this->cartService->removeEntry($cart, $entry); // updated Cart object

docs/commerce/cart/cart_api.md@138:``` php
docs/commerce/cart/cart_api.md@139:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 12, 13) =]]
docs/commerce/cart/cart_api.md@140:// ...
docs/commerce/cart/cart_api.md@141:
docs/commerce/cart/cart_api.md@142:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@143:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 129, 130) =]]
docs/commerce/cart/cart_api.md@144:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 139, 147) =]]
docs/commerce/cart/cart_api.md@145:```

001⫶use Ibexa\Contracts\Cart\Value\EntryUpdateStruct;
002⫶
003⫶// ...
004⫶
005⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
006⫶
007⫶ $entry = $cart->getEntries()->first();
008⫶
009⫶ $entryUpdateStruct = new EntryUpdateStruct(5);
010⫶ $entryUpdateStruct->setQuantity(10);
011⫶
012⫶ $cart = $this->cartService->updateEntry(
013⫶ $cart,
014⫶ $entry,
015⫶ $entryUpdateStruct
016⫶ ); // updated Cart object

docs/commerce/cart/cart_api.md@190:```php
docs/commerce/cart/cart_api.md@191:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 151, 164) =]]
docs/commerce/cart/cart_api.md@192:```

001⫶ // Get the order with items that should be reordered
002⫶ $orderIdentifier = '2e897b31-0d7a-46d3-ba45-4eb65fe02790';
003⫶ $order = $this->orderService->getOrderByIdentifier($orderIdentifier);
004⫶
005⫶ // Get the cart to merge
006⫶ $existingCart = $this->cartResolver->resolveCart();
007⫶
008⫶ $reorderCart = $this
009⫶ ->reorderService
010⫶ ->addToCartFromOrder($order, $this->reorderService->createReorderCart($order));
011⫶
012⫶ // Merge the carts into the target cart and delete the merged carts
013⫶ $reorderCart = $this->cartService->mergeCarts($reorderCart, true, $existingCart);


code_samples/api/migration/src/Command/MigrationCommand.php

docs/content_management/data_migration/data_migration_api.md@13:``` php
docs/content_management/data_migration/data_migration_api.md@14:[[= include_file('code_samples/api/migration/src/Command/MigrationCommand.php', 35, 38) =]]
docs/content_management/data_migration/data_migration_api.md@15:```

001⫶ foreach ($this->migrationService->listMigrations() as $migration) {
002⫶ $output->writeln($migration->getName());
003⫶ }

docs/content_management/data_migration/data_migration_api.md@19:``` php
docs/content_management/data_migration/data_migration_api.md@20:[[= include_file('code_samples/api/migration/src/Command/MigrationCommand.php', 40, 41) =]]
docs/content_management/data_migration/data_migration_api.md@21:```

001⫶ $my_migration = $this->migrationService->findOneByName($migration_name);

docs/content_management/data_migration/data_migration_api.md@27:``` php
docs/content_management/data_migration/data_migration_api.md@28:[[= include_file('code_samples/api/migration/src/Command/MigrationCommand.php', 42, 44) =]]
docs/content_management/data_migration/data_migration_api.md@29:```

001⫶ $this->migrationService->executeOne($my_migration);
002⫶ $this->migrationService->executeAll('admin');

docs/content_management/data_migration/data_migration_api.md@37:``` php
docs/content_management/data_migration/data_migration_api.md@38:[[= include_file('code_samples/api/migration/src/Command/MigrationCommand.php', 28, 34) =]]
docs/content_management/data_migration/data_migration_api.md@39:```

001⫶ $this->migrationService->add(
002⫶ new Migration(
003⫶ 'new_migration.yaml',
004⫶ $string_with_migration_content
005⫶ )
006⫶ );


code_samples/api/public_php_api/src/Command/SegmentCommand.php

docs/users/segment_api.md@17:``` php
docs/users/segment_api.md@18:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 54, 62) =]]
docs/users/segment_api.md@19:```

001⫶ 'group' => $newSegmentGroup,
002⫶ ]);
003⫶
004⫶ $newSegment = $this->segmentationService->createSegment($segmentCreateStruct);
005⫶
006⫶ $segmentGroup = $this->segmentationService->loadSegmentGroupByIdentifier('custom_group');
007⫶
008⫶ $segments = $this->segmentationService->loadSegmentsAssignedToGroup($segmentGroup);

docs/users/segment_api.md@23:``` php
docs/users/segment_api.md@24:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 62, 63) =]]
docs/users/segment_api.md@25:```



docs/users/segment_api.md@31:``` php
docs/users/segment_api.md@32:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 66, 71) =]]
docs/users/segment_api.md@33:```

001⫶ $segment = $this->segmentationService->loadSegmentByIdentifier('segment_1');
002⫶
003⫶ $this->segmentationService->assignUserToSegment($user, $segment);

docs/users/segment_api.md@39:``` php
docs/users/segment_api.md@40:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 64, 65) =]]
docs/users/segment_api.md@41:```

001⫶ $output->writeln('Segment identifier: ' . $segment->getIdentifier() . ', name: ' . $segment->getName());

docs/users/segment_api.md@49:``` php
docs/users/segment_api.md@50:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 38, 45) =]]
docs/users/segment_api.md@51:```

001⫶ protected function execute(InputInterface $input, OutputInterface $output): int
002⫶ {
003⫶ $user = $this->userService->loadUserByLogin('admin');
004⫶ $this->permissionResolver->setCurrentUserReference($user);
005⫶
006⫶ $segmentGroupCreateStruct = new SegmentGroupCreateStruct([
007⫶ 'name' => 'Custom Group',

docs/users/segment_api.md@55:``` php
docs/users/segment_api.md@56:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 46, 53) =]]
docs/users/segment_api.md@57:```

001⫶ 'createSegments' => [],
002⫶ ]);
003⫶
004⫶ $newSegmentGroup = $this->segmentationService->createSegmentGroup($segmentGroupCreateStruct);
005⫶
006⫶ $segmentCreateStruct = new SegmentCreateStruct([
007⫶ 'name' => 'Segment 1',


code_samples/back_office/calendar/src/Calendar/Holidays/EventSourceFactory.php

docs/administration/back_office/customize_calendar.md@71:```php
docs/administration/back_office/customize_calendar.md@72:[[= include_file('code_samples/back_office/calendar/src/Calendar/Holidays/EventSourceFactory.php', 0, 23) =]][[= include_file('code_samples/back_office/calendar/src/Calendar/Holidays/EventSourceFactory.php', 29, 40) =]]
docs/administration/back_office/customize_calendar.md@73:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Calendar\Holidays;
004⫶
005⫶use DateTime;
006⫶use DateTimeInterface;

code_samples/api/commerce/src/Command/CartCommand.php

docs/commerce/cart/cart_api.md@25:``` php
docs/commerce/cart/cart_api.md@26:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 91) =]]
docs/commerce/cart/cart_api.md@27:```

001⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
002⫶
003⫶ $output->writeln($cart->getName());

docs/commerce/cart/cart_api.md@34:``` php
docs/commerce/cart/cart_api.md@35:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 10, 11) =]]
docs/commerce/cart/cart_api.md@36:// ...
docs/commerce/cart/cart_api.md@37:
docs/commerce/cart/cart_api.md@38:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 74, 83) =]]
docs/commerce/cart/cart_api.md@39:```

001⫶use Ibexa\Contracts\Cart\Value\CartQuery;
002⫶
003⫶// ...
004⫶
005⫶ $cartQuery = new CartQuery();
006⫶ $cartQuery->setOwnerId(14); // carts created by User ID: 14
007⫶ $cartQuery->setLimit(20); // fetch 20 carts
008⫶
009⫶ $cartsList = $this->cartService->findCarts($cartQuery);
010⫶
011⫶ $cartsList->getCarts(); // array of CartInterface objects
012⫶ $cartsList->getTotalCount(); // number of returned carts

docs/commerce/cart/cart_api.md@45:``` php
docs/commerce/cart/cart_api.md@46:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 8, 9) =]]
docs/commerce/cart/cart_api.md@47:// ...
docs/commerce/cart/cart_api.md@48:
docs/commerce/cart/cart_api.md@49:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 95, 104) =]]
docs/commerce/cart/cart_api.md@50:```

001⫶use Ibexa\Contracts\Cart\Value\CartCreateStruct;
002⫶
003⫶// ...
004⫶
005⫶ $cartCreateStruct = new CartCreateStruct(
006⫶ 'Default cart',
007⫶ $currency // Ibexa\Contracts\ProductCatalog\Values\CurrencyInterface
008⫶ );
009⫶
010⫶ $cart = $this->cartService->createCart($cartCreateStruct);
011⫶
012⫶ $output->writeln($cart->getName()); // prints 'Default cart' to the console

docs/commerce/cart/cart_api.md@58:``` php
docs/commerce/cart/cart_api.md@59:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 9, 10) =]]
docs/commerce/cart/cart_api.md@60:// ...
docs/commerce/cart/cart_api.md@61:
docs/commerce/cart/cart_api.md@62:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 107, 114) =]]
docs/commerce/cart/cart_api.md@63:```

001⫶use Ibexa\Contracts\Cart\Value\CartMetadataUpdateStruct;
002⫶
003⫶// ...
004⫶
005⫶ $cartUpdateMetadataStruct = new CartMetadataUpdateStruct();
006⫶ $cartUpdateMetadataStruct->setName('New name');
007⫶ $cartUpdateMetadataStruct->setCurrency($newCurrency);
008⫶
009⫶ $updatedCart = $this->cartService->updateCartMetadata($cart, $cartUpdateMetadataStruct);
010⫶
011⫶ $output->writeln($updatedCart->getName()); // prints 'New name' to the console

docs/commerce/cart/cart_api.md@82:``` php
docs/commerce/cart/cart_api.md@83:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@84:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 149, 150) =]]
docs/commerce/cart/cart_api.md@85:```

001⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
002⫶
003⫶ $this->cartService->deleteCart($cart);

docs/commerce/cart/cart_api.md@91:``` php
docs/commerce/cart/cart_api.md@92:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@93:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 116, 117) =]]
docs/commerce/cart/cart_api.md@94:```

001⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
002⫶
003⫶ $this->cartService->emptyCart($cart);

docs/commerce/cart/cart_api.md@103:``` php
docs/commerce/cart/cart_api.md@104:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@105:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 119, 120) =]]
docs/commerce/cart/cart_api.md@106:```

001⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
002⫶
003⫶ $violationList = $this->cartService->validateCart($cart); // Symfony\Component\Validator\ConstraintViolationListInterface

docs/commerce/cart/cart_api.md@113:``` php
docs/commerce/cart/cart_api.md@114:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 11, 12) =]]
docs/commerce/cart/cart_api.md@115:// ...
docs/commerce/cart/cart_api.md@116:
docs/commerce/cart/cart_api.md@117:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@118:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 124, 131) =]]
docs/commerce/cart/cart_api.md@119:```

001⫶use Ibexa\Contracts\Cart\Value\EntryAddStruct;
002⫶
003⫶// ...
004⫶
005⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
006⫶
007⫶ $entryAddStruct = new EntryAddStruct($product);
008⫶ $entryAddStruct->setQuantity(10);
009⫶
010⫶ $cart = $this->cartService->addEntry($cart, $entryAddStruct);
011⫶
012⫶ $entry = $cart->getEntries()->first();
013⫶ $output->writeln($entry->getProduct()->getName()); // prints product name to the console

docs/commerce/cart/cart_api.md@125:``` php
docs/commerce/cart/cart_api.md@126:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 11, 12) =]]
docs/commerce/cart/cart_api.md@127:// ...
docs/commerce/cart/cart_api.md@128:
docs/commerce/cart/cart_api.md@129:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@130:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 134, 137) =]]
docs/commerce/cart/cart_api.md@131:```

001⫶use Ibexa\Contracts\Cart\Value\EntryAddStruct;
002⫶
003⫶// ...
004⫶
005⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
006⫶
007⫶ $entry = $cart->getEntries()->first();
008⫶
009⫶ $cart = $this->cartService->removeEntry($cart, $entry); // updated Cart object

docs/commerce/cart/cart_api.md@138:``` php
docs/commerce/cart/cart_api.md@139:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 12, 13) =]]
docs/commerce/cart/cart_api.md@140:// ...
docs/commerce/cart/cart_api.md@141:
docs/commerce/cart/cart_api.md@142:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 88, 89) =]]
docs/commerce/cart/cart_api.md@143:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 129, 130) =]]
docs/commerce/cart/cart_api.md@144:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 139, 147) =]]
docs/commerce/cart/cart_api.md@145:```

001⫶use Ibexa\Contracts\Cart\Value\EntryUpdateStruct;
002⫶
003⫶// ...
004⫶
005⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
006⫶
007⫶ $entry = $cart->getEntries()->first();
008⫶
009⫶ $entryUpdateStruct = new EntryUpdateStruct(5);
010⫶ $entryUpdateStruct->setQuantity(10);
011⫶
012⫶ $cart = $this->cartService->updateEntry(
013⫶ $cart,
014⫶ $entry,
015⫶ $entryUpdateStruct
016⫶ ); // updated Cart object

docs/commerce/cart/cart_api.md@190:```php
docs/commerce/cart/cart_api.md@191:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 151, 164) =]]
docs/commerce/cart/cart_api.md@192:```

001⫶ // Get the order with items that should be reordered
002⫶ $orderIdentifier = '2e897b31-0d7a-46d3-ba45-4eb65fe02790';
003⫶ $order = $this->orderService->getOrderByIdentifier($orderIdentifier);
004⫶
005⫶ // Get the cart to merge
006⫶ $existingCart = $this->cartResolver->resolveCart();
007⫶
008⫶ $reorderCart = $this
009⫶ ->reorderService
010⫶ ->addToCartFromOrder($order, $this->reorderService->createReorderCart($order));
011⫶
012⫶ // Merge the carts into the target cart and delete the merged carts
013⫶ $reorderCart = $this->cartService->mergeCarts($reorderCart, true, $existingCart);


code_samples/api/migration/src/Command/MigrationCommand.php

docs/content_management/data_migration/data_migration_api.md@13:``` php
docs/content_management/data_migration/data_migration_api.md@14:[[= include_file('code_samples/api/migration/src/Command/MigrationCommand.php', 35, 38) =]]
docs/content_management/data_migration/data_migration_api.md@15:```

001⫶ foreach ($this->migrationService->listMigrations() as $migration) {
002⫶ $output->writeln($migration->getName());
003⫶ }

docs/content_management/data_migration/data_migration_api.md@19:``` php
docs/content_management/data_migration/data_migration_api.md@20:[[= include_file('code_samples/api/migration/src/Command/MigrationCommand.php', 40, 41) =]]
docs/content_management/data_migration/data_migration_api.md@21:```

001⫶ $my_migration = $this->migrationService->findOneByName($migration_name);

docs/content_management/data_migration/data_migration_api.md@27:``` php
docs/content_management/data_migration/data_migration_api.md@28:[[= include_file('code_samples/api/migration/src/Command/MigrationCommand.php', 42, 44) =]]
docs/content_management/data_migration/data_migration_api.md@29:```

001⫶ $this->migrationService->executeOne($my_migration);
002⫶ $this->migrationService->executeAll('admin');

docs/content_management/data_migration/data_migration_api.md@37:``` php
docs/content_management/data_migration/data_migration_api.md@38:[[= include_file('code_samples/api/migration/src/Command/MigrationCommand.php', 28, 34) =]]
docs/content_management/data_migration/data_migration_api.md@39:```

001⫶ $this->migrationService->add(
002⫶ new Migration(
003⫶ 'new_migration.yaml',
004⫶ $string_with_migration_content
005⫶ )
006⫶ );


code_samples/api/public_php_api/src/Command/SegmentCommand.php

docs/users/segment_api.md@17:``` php
docs/users/segment_api.md@18:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 54, 62) =]]
docs/users/segment_api.md@19:```

001⫶ 'group' => $newSegmentGroup,
002⫶ ]);
003⫶
004⫶ $newSegment = $this->segmentationService->createSegment($segmentCreateStruct);
005⫶
006⫶ $segmentGroup = $this->segmentationService->loadSegmentGroupByIdentifier('custom_group');
007⫶
008⫶ $segments = $this->segmentationService->loadSegmentsAssignedToGroup($segmentGroup);

docs/users/segment_api.md@23:``` php
docs/users/segment_api.md@24:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 62, 63) =]]
docs/users/segment_api.md@25:```



docs/users/segment_api.md@31:``` php
docs/users/segment_api.md@32:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 66, 71) =]]
docs/users/segment_api.md@33:```

001⫶ $segment = $this->segmentationService->loadSegmentByIdentifier('segment_1');
002⫶
003⫶ $this->segmentationService->assignUserToSegment($user, $segment);

docs/users/segment_api.md@39:``` php
docs/users/segment_api.md@40:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 64, 65) =]]
docs/users/segment_api.md@41:```

001⫶ $output->writeln('Segment identifier: ' . $segment->getIdentifier() . ', name: ' . $segment->getName());

docs/users/segment_api.md@49:``` php
docs/users/segment_api.md@50:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 38, 45) =]]
docs/users/segment_api.md@51:```

001⫶ protected function execute(InputInterface $input, OutputInterface $output): int
002⫶ {
003⫶ $user = $this->userService->loadUserByLogin('admin');
004⫶ $this->permissionResolver->setCurrentUserReference($user);
005⫶
006⫶ $segmentGroupCreateStruct = new SegmentGroupCreateStruct([
007⫶ 'name' => 'Custom Group',

docs/users/segment_api.md@55:``` php
docs/users/segment_api.md@56:[[= include_file('code_samples/api/public_php_api/src/Command/SegmentCommand.php', 46, 53) =]]
docs/users/segment_api.md@57:```

001⫶ 'createSegments' => [],
002⫶ ]);
003⫶
004⫶ $newSegmentGroup = $this->segmentationService->createSegmentGroup($segmentGroupCreateStruct);
005⫶
006⫶ $segmentCreateStruct = new SegmentCreateStruct([
007⫶ 'name' => 'Segment 1',


code_samples/back_office/calendar/src/Calendar/Holidays/EventSourceFactory.php

docs/administration/back_office/customize_calendar.md@71:```php
docs/administration/back_office/customize_calendar.md@72:[[= include_file('code_samples/back_office/calendar/src/Calendar/Holidays/EventSourceFactory.php', 0, 23) =]][[= include_file('code_samples/back_office/calendar/src/Calendar/Holidays/EventSourceFactory.php', 29, 40) =]]
docs/administration/back_office/customize_calendar.md@73:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Calendar\Holidays;
004⫶
005⫶use DateTime;
006⫶use DateTimeInterface;
007⫶use Ibexa\Calendar\EventSource\InMemoryEventSource;
008⫶use Ibexa\Contracts\Calendar\EventCollection;
009⫶use Ibexa\Contracts\Calendar\EventSource\EventSourceInterface;
007⫶use Ibexa\Contracts\Calendar\EventCollection;
008⫶use Ibexa\Contracts\Calendar\EventSource\EventSourceInterface;
009⫶use Ibexa\Contracts\Calendar\EventSource\InMemoryEventSource;
010⫶
011⫶class EventSourceFactory
012⫶{
013⫶ private EventType $eventType;
014⫶
015⫶ public function __construct(EventType $eventType)
016⫶ {
017⫶ $this->eventType = $eventType;
018⫶ }
019⫶
020⫶ public function createEventSource(): EventSourceInterface
021⫶ {
022⫶ $eventCollectionArray = [];
023⫶ $eventCollectionArray[] = $this->createEvent('April Fools', new DateTime('2024-04-01'));
024⫶ $collection = new EventCollection($eventCollectionArray);
025⫶
026⫶ return new InMemoryEventSource($collection);
027⫶ }
028⫶
029⫶ private function createEvent(string $id, DateTimeInterface $dateTime): Event
030⫶ {
031⫶ return new Event($id, $dateTime, $this->eventType);
032⫶ }
033⫶}

docs/administration/back_office/customize_calendar.md@109:``` php hl_lines="6-9"
docs/administration/back_office/customize_calendar.md@110:[[= include_file('code_samples/back_office/calendar/src/Calendar/Holidays/EventSourceFactory.php', 19, 33) =]]
docs/administration/back_office/customize_calendar.md@111:```

001⫶ public function createEventSource(): EventSourceInterface
002⫶ {
003⫶ $eventCollectionArray = [];
004⫶ $eventCollectionArray[] = $this->createEvent('April Fools', new DateTime('2024-04-01'));
005⫶
006❇️ $items = json_decode(file_get_contents(__DIR__ . \DIRECTORY_SEPARATOR . 'holidays.json'), true);
007❇️ foreach ($items as $item) {
008❇️ $eventCollectionArray[] = $this->createEvent($item['name'], new DateTime($item['date']));
009❇️ }
010⫶
011⫶ $collection = new EventCollection($eventCollectionArray);
012⫶
013⫶ return new InMemoryEventSource($collection);
014⫶ }


code_samples/back_office/calendar/src/Calendar/Holidays/EventType.php

docs/administration/back_office/customize_calendar.md@50:```php hl_lines="20-23"
docs/administration/back_office/customize_calendar.md@51:[[= include_file('code_samples/back_office/calendar/src/Calendar/Holidays/EventType.php') =]]
docs/administration/back_office/customize_calendar.md@52:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Calendar\Holidays;
004⫶
010⫶
011⫶class EventSourceFactory
012⫶{
013⫶ private EventType $eventType;
014⫶
015⫶ public function __construct(EventType $eventType)
016⫶ {
017⫶ $this->eventType = $eventType;
018⫶ }
019⫶
020⫶ public function createEventSource(): EventSourceInterface
021⫶ {
022⫶ $eventCollectionArray = [];
023⫶ $eventCollectionArray[] = $this->createEvent('April Fools', new DateTime('2024-04-01'));
024⫶ $collection = new EventCollection($eventCollectionArray);
025⫶
026⫶ return new InMemoryEventSource($collection);
027⫶ }
028⫶
029⫶ private function createEvent(string $id, DateTimeInterface $dateTime): Event
030⫶ {
031⫶ return new Event($id, $dateTime, $this->eventType);
032⫶ }
033⫶}

docs/administration/back_office/customize_calendar.md@109:``` php hl_lines="6-9"
docs/administration/back_office/customize_calendar.md@110:[[= include_file('code_samples/back_office/calendar/src/Calendar/Holidays/EventSourceFactory.php', 19, 33) =]]
docs/administration/back_office/customize_calendar.md@111:```

001⫶ public function createEventSource(): EventSourceInterface
002⫶ {
003⫶ $eventCollectionArray = [];
004⫶ $eventCollectionArray[] = $this->createEvent('April Fools', new DateTime('2024-04-01'));
005⫶
006❇️ $items = json_decode(file_get_contents(__DIR__ . \DIRECTORY_SEPARATOR . 'holidays.json'), true);
007❇️ foreach ($items as $item) {
008❇️ $eventCollectionArray[] = $this->createEvent($item['name'], new DateTime($item['date']));
009❇️ }
010⫶
011⫶ $collection = new EventCollection($eventCollectionArray);
012⫶
013⫶ return new InMemoryEventSource($collection);
014⫶ }


code_samples/back_office/calendar/src/Calendar/Holidays/EventType.php

docs/administration/back_office/customize_calendar.md@50:```php hl_lines="20-23"
docs/administration/back_office/customize_calendar.md@51:[[= include_file('code_samples/back_office/calendar/src/Calendar/Holidays/EventType.php') =]]
docs/administration/back_office/customize_calendar.md@52:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Calendar\Holidays;
004⫶
005⫶use Ibexa\Calendar\EventAction\EventActionCollection;
006⫶use Ibexa\Contracts\Calendar\Event;
005⫶use Ibexa\Contracts\Calendar\Event;
006⫶use Ibexa\Contracts\Calendar\EventAction\EventActionCollection;
007⫶use Ibexa\Contracts\Calendar\EventType\EventTypeInterface;
008⫶
009⫶class EventType implements EventTypeInterface
010⫶{
011⫶ private const EVENT_TYPE_IDENTIFIER = 'holiday';
012⫶
013⫶ private EventActionCollection $actions;
014⫶
015⫶ public function __construct(iterable $actions)
016⫶ {
017⫶ $this->actions = new EventActionCollection($actions);
018⫶ }
019⫶
020❇️ public function getTypeIdentifier(): string
021❇️ {
022❇️ return self::EVENT_TYPE_IDENTIFIER;
023❇️ }
024⫶
025⫶ public function getTypeLabel(): string
026⫶ {
027⫶ return 'Holidays';
028⫶ }
029⫶
030⫶ public function getEventName(Event $event): string
031⫶ {
032⫶ return $event->getId();
033⫶ }
034⫶
035⫶ public function getActions(): EventActionCollection
036⫶ {
037⫶ return $this->actions;
038⫶ }
039⫶}


code_samples/back_office/images/src/PlaceholderProvider.php

007⫶use Ibexa\Contracts\Calendar\EventType\EventTypeInterface;
008⫶
009⫶class EventType implements EventTypeInterface
010⫶{
011⫶ private const EVENT_TYPE_IDENTIFIER = 'holiday';
012⫶
013⫶ private EventActionCollection $actions;
014⫶
015⫶ public function __construct(iterable $actions)
016⫶ {
017⫶ $this->actions = new EventActionCollection($actions);
018⫶ }
019⫶
020❇️ public function getTypeIdentifier(): string
021❇️ {
022❇️ return self::EVENT_TYPE_IDENTIFIER;
023❇️ }
024⫶
025⫶ public function getTypeLabel(): string
026⫶ {
027⫶ return 'Holidays';
028⫶ }
029⫶
030⫶ public function getEventName(Event $event): string
031⫶ {
032⫶ return $event->getId();
033⫶ }
034⫶
035⫶ public function getActions(): EventActionCollection
036⫶ {
037⫶ return $this->actions;
038⫶ }
039⫶}


code_samples/back_office/images/src/PlaceholderProvider.php

docs/content_management/images/images.md@123:``` php
docs/content_management/images/images.md@124:[[= include_file('code_samples/back_office/images/src/PlaceholderProvider.php') =]]
docs/content_management/images/images.md@125:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace Ibexa\Bundle\Core\Imagine;
004⫶
005⫶use Ibexa\Core\FieldType\Image\Value as ImageValue;
006⫶
007⫶interface PlaceholderProvider
008⫶{
009⫶ /**
010⫶ * Provides a placeholder image path for a given Image FieldType value.
011⫶ *
012⫶ * @param \Ibexa\Core\FieldType\Image\Value $value
013⫶ * @param array $options
014⫶ *
015⫶ * @return string Path to placeholder
016⫶ */
017⫶ public function getPlaceholder(ImageValue $value, array $options = []): string;
018⫶}


code_samples/back_office/limitation/src/Security/Limitation/CustomLimitationType.php

docs/permissions/custom_policies.md@161:```php
docs/permissions/custom_policies.md@162:[[= include_file('code_samples/back_office/limitation/src/Security/Limitation/CustomLimitationType.php') =]]
docs/permissions/custom_policies.md@163:```

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\Security\Limitation;
006⫶
007⫶use Ibexa\Contracts\Core\Limitation\Type;
008⫶use Ibexa\Contracts\Core\Repository\Exceptions\NotImplementedException;
009⫶use Ibexa\Contracts\Core\Repository\Values\Content\Query\CriterionInterface;
010⫶use Ibexa\Contracts\Core\Repository\Values\User\Limitation;
011⫶use Ibexa\Contracts\Core\Repository\Values\User\UserReference;
012⫶use Ibexa\Contracts\Core\Repository\Values\ValueObject;
013⫶use Ibexa\Core\Base\Exceptions\InvalidArgumentException;
014⫶use Ibexa\Core\Base\Exceptions\InvalidArgumentType;
015⫶use Ibexa\Core\FieldType\ValidationError;
016⫶
017⫶class CustomLimitationType implements Type
018⫶{
019⫶ public function acceptValue(Limitation $limitationValue): void
020⫶ {
021⫶ if (!$limitationValue instanceof CustomLimitationValue) {
022⫶ throw new InvalidArgumentType(
023⫶ '$limitationValue',
024⫶ CustomLimitationValue::class,
025⫶ $limitationValue
026⫶ );
027⫶ }
028⫶ }
029⫶

code_samples/back_office/limitation/src/Security/Limitation/CustomLimitationType.php

docs/permissions/custom_policies.md@161:```php
docs/permissions/custom_policies.md@162:[[= include_file('code_samples/back_office/limitation/src/Security/Limitation/CustomLimitationType.php') =]]
docs/permissions/custom_policies.md@163:```

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\Security\Limitation;
006⫶
007⫶use Ibexa\Contracts\Core\Limitation\Type;
008⫶use Ibexa\Contracts\Core\Repository\Exceptions\NotImplementedException;
009⫶use Ibexa\Contracts\Core\Repository\Values\Content\Query\CriterionInterface;
010⫶use Ibexa\Contracts\Core\Repository\Values\User\Limitation;
011⫶use Ibexa\Contracts\Core\Repository\Values\User\UserReference;
012⫶use Ibexa\Contracts\Core\Repository\Values\ValueObject;
013⫶use Ibexa\Core\Base\Exceptions\InvalidArgumentException;
014⫶use Ibexa\Core\Base\Exceptions\InvalidArgumentType;
015⫶use Ibexa\Core\FieldType\ValidationError;
016⫶
017⫶class CustomLimitationType implements Type
018⫶{
019⫶ public function acceptValue(Limitation $limitationValue): void
020⫶ {
021⫶ if (!$limitationValue instanceof CustomLimitationValue) {
022⫶ throw new InvalidArgumentType(
023⫶ '$limitationValue',
024⫶ CustomLimitationValue::class,
025⫶ $limitationValue
026⫶ );
027⫶ }
028⫶ }
029⫶
030⫶    /** @return \Ibexa\Core\FieldType\ValidationError[] */
030⫶    /** @return \Ibexa\Contracts\Core\FieldType\ValidationError[] */
031⫶    public function validate(Limitation $limitationValue): array
032⫶ {
033⫶ $validationErrors = [];
034⫶ if (!array_key_exists('value', $limitationValue->limitationValues)) {
035⫶ $validationErrors[] = new ValidationError("limitationValues['value'] is missing.");
036⫶ } elseif (!is_bool($limitationValue->limitationValues['value'])) {
037⫶ $validationErrors[] = new ValidationError("limitationValues['value'] is not a boolean.");
038⫶ }
039⫶
040⫶ return $validationErrors;
041⫶ }
042⫶
043⫶ public function buildValue(array $limitationValues): CustomLimitationValue
044⫶ {
045⫶ $value = false;
046⫶ if (array_key_exists('value', $limitationValues)) {
047⫶ $value = $limitationValues['value'];
048⫶ } elseif (count($limitationValues)) {
049⫶ $value = (bool)$limitationValues[0];
050⫶ }
051⫶
052⫶ return new CustomLimitationValue(['limitationValues' => ['value' => $value]]);
053⫶ }
054⫶
055⫶ /**
056⫶ * @param \Ibexa\Contracts\Core\Repository\Values\ValueObject[]|null $targets
057⫶ *
058⫶ * @return bool|null
059⫶ */
031⫶    public function validate(Limitation $limitationValue): array
032⫶ {
033⫶ $validationErrors = [];
034⫶ if (!array_key_exists('value', $limitationValue->limitationValues)) {
035⫶ $validationErrors[] = new ValidationError("limitationValues['value'] is missing.");
036⫶ } elseif (!is_bool($limitationValue->limitationValues['value'])) {
037⫶ $validationErrors[] = new ValidationError("limitationValues['value'] is not a boolean.");
038⫶ }
039⫶
040⫶ return $validationErrors;
041⫶ }
042⫶
043⫶ public function buildValue(array $limitationValues): CustomLimitationValue
044⫶ {
045⫶ $value = false;
046⫶ if (array_key_exists('value', $limitationValues)) {
047⫶ $value = $limitationValues['value'];
048⫶ } elseif (count($limitationValues)) {
049⫶ $value = (bool)$limitationValues[0];
050⫶ }
051⫶
052⫶ return new CustomLimitationValue(['limitationValues' => ['value' => $value]]);
053⫶ }
054⫶
055⫶ /**
056⫶ * @param \Ibexa\Contracts\Core\Repository\Values\ValueObject[]|null $targets
057⫶ *
058⫶ * @return bool|null
059⫶ */
060⫶    public function evaluate(Limitation $value, UserReference $currentUser, ValueObject $object, array $targets = null): ?bool
060⫶    public function evaluate(Limitation $value, UserReference $currentUser, object $object, ?array $targets = null): ?bool
061⫶    {
062⫶ if (!$value instanceof CustomLimitationValue) {
063⫶ throw new InvalidArgumentException('$value', 'Must be of type: CustomLimitationValue');
064⫶ }
065⫶
066⫶ if ($value->limitationValues['value']) {
067⫶ return Type::ACCESS_GRANTED;
068⫶ }
069⫶
070⫶ // If the limitation value is not set to `true`, then $currentUser, $object and/or $targets could be challenged to determine if the access is granted or not; Here or elsewhere. When passing the baton, a limitation can return Type::ACCESS_ABSTAIN
071⫶ return Type::ACCESS_DENIED;
072⫶ }
073⫶
074⫶ public function getCriterion(Limitation $value, UserReference $currentUser): CriterionInterface
075⫶ {
076⫶ throw new NotImplementedException(__METHOD__);
077⫶ }
078⫶
079⫶ public function valueSchema(): never
080⫶ {
081⫶ throw new NotImplementedException(__METHOD__);
082⫶ }
083⫶}


code_samples/search/custom/src/Search/FieldMapper/WebinarEventTitleFulltextFieldMapper.php

docs/search/extensibility/solr_document_field_mappers.md@59:```php
docs/search/extensibility/solr_document_field_mappers.md@60:[[= include_file('code_samples/search/custom/src/Search/FieldMapper/WebinarEventTitleFulltextFieldMapper.php') =]]
docs/search/extensibility/solr_document_field_mappers.md@61:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Search\FieldMapper;
004⫶
005⫶use Ibexa\Contracts\Core\Persistence\Content;
006⫶use Ibexa\Contracts\Core\Persistence\Content\Handler as ContentHandler;
007⫶use Ibexa\Contracts\Core\Persistence\Content\Location\Handler as LocationHandler;
008⫶use Ibexa\Contracts\Core\Search;
009⫶use Ibexa\Contracts\Solr\FieldMapper\ContentFieldMapper;
010⫶
011⫶class WebinarEventTitleFulltextFieldMapper extends ContentFieldMapper
012⫶{
013⫶ protected ContentHandler $contentHandler;
014⫶
015⫶ protected LocationHandler $locationHandler;
016⫶
017⫶ public function __construct(
018⫶ ContentHandler $contentHandler,
019⫶ LocationHandler $locationHandler
020⫶ ) {
021⫶ $this->contentHandler = $contentHandler;
022⫶ $this->locationHandler = $locationHandler;
023⫶ }
024⫶
061⫶    {
062⫶ if (!$value instanceof CustomLimitationValue) {
063⫶ throw new InvalidArgumentException('$value', 'Must be of type: CustomLimitationValue');
064⫶ }
065⫶
066⫶ if ($value->limitationValues['value']) {
067⫶ return Type::ACCESS_GRANTED;
068⫶ }
069⫶
070⫶ // If the limitation value is not set to `true`, then $currentUser, $object and/or $targets could be challenged to determine if the access is granted or not; Here or elsewhere. When passing the baton, a limitation can return Type::ACCESS_ABSTAIN
071⫶ return Type::ACCESS_DENIED;
072⫶ }
073⫶
074⫶ public function getCriterion(Limitation $value, UserReference $currentUser): CriterionInterface
075⫶ {
076⫶ throw new NotImplementedException(__METHOD__);
077⫶ }
078⫶
079⫶ public function valueSchema(): never
080⫶ {
081⫶ throw new NotImplementedException(__METHOD__);
082⫶ }
083⫶}


code_samples/search/custom/src/Search/FieldMapper/WebinarEventTitleFulltextFieldMapper.php

docs/search/extensibility/solr_document_field_mappers.md@59:```php
docs/search/extensibility/solr_document_field_mappers.md@60:[[= include_file('code_samples/search/custom/src/Search/FieldMapper/WebinarEventTitleFulltextFieldMapper.php') =]]
docs/search/extensibility/solr_document_field_mappers.md@61:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Search\FieldMapper;
004⫶
005⫶use Ibexa\Contracts\Core\Persistence\Content;
006⫶use Ibexa\Contracts\Core\Persistence\Content\Handler as ContentHandler;
007⫶use Ibexa\Contracts\Core\Persistence\Content\Location\Handler as LocationHandler;
008⫶use Ibexa\Contracts\Core\Search;
009⫶use Ibexa\Contracts\Solr\FieldMapper\ContentFieldMapper;
010⫶
011⫶class WebinarEventTitleFulltextFieldMapper extends ContentFieldMapper
012⫶{
013⫶ protected ContentHandler $contentHandler;
014⫶
015⫶ protected LocationHandler $locationHandler;
016⫶
017⫶ public function __construct(
018⫶ ContentHandler $contentHandler,
019⫶ LocationHandler $locationHandler
020⫶ ) {
021⫶ $this->contentHandler = $contentHandler;
022⫶ $this->locationHandler = $locationHandler;
023⫶ }
024⫶
025⫶    public function accept(Content $content)
025⫶    public function accept(Content $content): bool
026⫶    {
027⫶ // ContentType with ID 42 is webinar event
028⫶ return $content->versionInfo->contentInfo->contentTypeId == 42;
029⫶ }
030⫶
026⫶    {
027⫶ // ContentType with ID 42 is webinar event
028⫶ return $content->versionInfo->contentInfo->contentTypeId == 42;
029⫶ }
030⫶
031⫶    public function mapFields(Content $content)
031⫶    public function mapFields(Content $content): array
032⫶    {
033⫶ $mainLocationId = $content->versionInfo->contentInfo->mainLocationId;
034⫶ $location = $this->locationHandler->load($mainLocationId);
035⫶ $parentLocation = $this->locationHandler->load($location->parentId);
036⫶ $parentContentInfo = $this->contentHandler->loadContentInfo($parentLocation->contentId);
037⫶
038⫶ return [
039⫶ new Search\Field(
040⫶ 'fulltext',
041⫶ $parentContentInfo->name,
042⫶ new Search\FieldType\FullTextField()
043⫶ ),
044⫶ ];
045⫶ }
046⫶}

032⫶    {
033⫶ $mainLocationId = $content->versionInfo->contentInfo->mainLocationId;
034⫶ $location = $this->locationHandler->load($mainLocationId);
035⫶ $parentLocation = $this->locationHandler->load($location->parentId);
036⫶ $parentContentInfo = $this->contentHandler->loadContentInfo($parentLocation->contentId);
037⫶
038⫶ return [
039⫶ new Search\Field(
040⫶ 'fulltext',
041⫶ $parentContentInfo->name,
042⫶ new Search\FieldType\FullTextField()
043⫶ ),
044⫶ ];
045⫶ }
046⫶}

Download colorized diff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant