Skip to content

Conversation

mnocon
Copy link
Contributor

@mnocon mnocon commented Nov 30, 2024

Target: 5.0 only, for new code only.

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.

Together with @konradoboza we've also added a few additional exceptions - like SiteAccess configuration classes etc.

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.

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

github-actions bot commented Jul 31, 2025

Preview of modified files

Preview of modified Markdown:

Copy link
Contributor

@konradoboza konradoboza left a comment

Choose a reason for hiding this comment

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

Great work! 💪

Just a few nitpicks:

@mnocon mnocon changed the title [CI] [POC] Added code samples testing with Deptrac [CI] Added code samples testing with Deptrac Oct 1, 2025
Copy link

github-actions bot commented Oct 2, 2025

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', 63, 66) =]]
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', 49, 57) =]]
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', 70, 78) =]]
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', 82, 89) =]]
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', 63, 64) =]]
docs/commerce/cart/cart_api.md@84:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 124, 125) =]]
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', 63, 64) =]]
docs/commerce/cart/cart_api.md@93:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 91, 92) =]]
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', 63, 64) =]]
docs/commerce/cart/cart_api.md@105:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 94, 95) =]]
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', 63, 64) =]]
docs/commerce/cart/cart_api.md@118:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 99, 106) =]]
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', 63, 64) =]]
docs/commerce/cart/cart_api.md@127:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 109, 112) =]]
docs/commerce/cart/cart_api.md@128:```

001⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
002⫶
003⫶ $entry = $cart->getEntries()->first();
004⫶
005⫶ $cart = $this->cartService->removeEntry($cart, $entry); // updated Cart object

docs/commerce/cart/cart_api.md@135:``` php
docs/commerce/cart/cart_api.md@136:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 12, 13) =]]
docs/commerce/cart/cart_api.md@137:// ...
docs/commerce/cart/cart_api.md@138:
docs/commerce/cart/cart_api.md@139:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 63, 64) =]]
docs/commerce/cart/cart_api.md@140:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 109, 110) =]]
docs/commerce/cart/cart_api.md@141:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 114, 122) =]]
docs/commerce/cart/cart_api.md@142:```

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@187:```php
docs/commerce/cart/cart_api.md@188:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 126, 139) =]]
docs/commerce/cart/cart_api.md@189:```

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', 31, 34) =]]
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', 36, 37) =]]
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', 38, 40) =]]
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', 24, 30) =]]
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', 46, 52) =]]
docs/users/segment_api.md@19:```

001⫶ $newSegment = $this->segmentationService->createSegment($segmentCreateStruct);
002⫶
003⫶ $segmentGroup = $this->segmentationService->loadSegmentGroupByIdentifier('custom_group');
004⫶
005⫶ $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', 54, 54) =]]
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', 58, 62) =]]
docs/users/segment_api.md@33:```

001⫶ $this->segmentationService->assignUserToSegment($user, $segment);
002⫶
003⫶ $output->writeln((
004⫶ $this->segmentationService->isUserAssignedToSegment($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', 56, 56) =]]
docs/users/segment_api.md@41:```



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', 30, 36) =]]
docs/users/segment_api.md@51:```

001⫶ $this->permissionResolver->setCurrentUserReference($user);
002⫶
003⫶ $segmentGroupCreateStruct = new SegmentGroupCreateStruct([
004⫶ 'name' => 'Custom Group',
005⫶ 'identifier' => 'custom_group',
006⫶ 'createSegments' => [],

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', 38, 44) =]]
docs/users/segment_api.md@57:```

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


code_samples/back_office/images/src/PlaceholderProvider.php


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', 63, 66) =]]
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', 49, 57) =]]
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', 70, 78) =]]
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', 82, 89) =]]
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', 63, 64) =]]
docs/commerce/cart/cart_api.md@84:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 124, 125) =]]
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', 63, 64) =]]
docs/commerce/cart/cart_api.md@93:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 91, 92) =]]
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', 63, 64) =]]
docs/commerce/cart/cart_api.md@105:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 94, 95) =]]
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', 63, 64) =]]
docs/commerce/cart/cart_api.md@118:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 99, 106) =]]
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', 63, 64) =]]
docs/commerce/cart/cart_api.md@127:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 109, 112) =]]
docs/commerce/cart/cart_api.md@128:```

001⫶ $cart = $this->cartService->getCart('1844450e-61da-4814-8d82-9301a3df0054');
002⫶
003⫶ $entry = $cart->getEntries()->first();
004⫶
005⫶ $cart = $this->cartService->removeEntry($cart, $entry); // updated Cart object

docs/commerce/cart/cart_api.md@135:``` php
docs/commerce/cart/cart_api.md@136:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 12, 13) =]]
docs/commerce/cart/cart_api.md@137:// ...
docs/commerce/cart/cart_api.md@138:
docs/commerce/cart/cart_api.md@139:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 63, 64) =]]
docs/commerce/cart/cart_api.md@140:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 109, 110) =]]
docs/commerce/cart/cart_api.md@141:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 114, 122) =]]
docs/commerce/cart/cart_api.md@142:```

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@187:```php
docs/commerce/cart/cart_api.md@188:[[= include_file('code_samples/api/commerce/src/Command/CartCommand.php', 126, 139) =]]
docs/commerce/cart/cart_api.md@189:```

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', 31, 34) =]]
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', 36, 37) =]]
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', 38, 40) =]]
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', 24, 30) =]]
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', 46, 52) =]]
docs/users/segment_api.md@19:```

001⫶ $newSegment = $this->segmentationService->createSegment($segmentCreateStruct);
002⫶
003⫶ $segmentGroup = $this->segmentationService->loadSegmentGroupByIdentifier('custom_group');
004⫶
005⫶ $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', 54, 54) =]]
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', 58, 62) =]]
docs/users/segment_api.md@33:```

001⫶ $this->segmentationService->assignUserToSegment($user, $segment);
002⫶
003⫶ $output->writeln((
004⫶ $this->segmentationService->isUserAssignedToSegment($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', 56, 56) =]]
docs/users/segment_api.md@41:```



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', 30, 36) =]]
docs/users/segment_api.md@51:```

001⫶ $this->permissionResolver->setCurrentUserReference($user);
002⫶
003⫶ $segmentGroupCreateStruct = new SegmentGroupCreateStruct([
004⫶ 'name' => 'Custom Group',
005⫶ 'identifier' => 'custom_group',
006⫶ 'createSegments' => [],

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', 38, 44) =]]
docs/users/segment_api.md@57:```

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


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\Core\Base\Exceptions\InvalidArgumentException;
013⫶use Ibexa\Core\Base\Exceptions\InvalidArgumentType;
014⫶use Ibexa\Core\FieldType\ValidationError;
015⫶
016⫶class CustomLimitationType implements Type
017⫶{
018⫶ public function acceptValue(Limitation $limitationValue): void
019⫶ {
020⫶ if (!$limitationValue instanceof CustomLimitationValue) {
021⫶ throw new InvalidArgumentType(
022⫶ '$limitationValue',
023⫶ CustomLimitationValue::class,
024⫶ $limitationValue
025⫶ );
026⫶ }
027⫶ }
028⫶

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\Core\Base\Exceptions\InvalidArgumentException;
013⫶use Ibexa\Core\Base\Exceptions\InvalidArgumentType;
014⫶use Ibexa\Core\FieldType\ValidationError;
015⫶
016⫶class CustomLimitationType implements Type
017⫶{
018⫶ public function acceptValue(Limitation $limitationValue): void
019⫶ {
020⫶ if (!$limitationValue instanceof CustomLimitationValue) {
021⫶ throw new InvalidArgumentType(
022⫶ '$limitationValue',
023⫶ CustomLimitationValue::class,
024⫶ $limitationValue
025⫶ );
026⫶ }
027⫶ }
028⫶
029⫶    /** @return \Ibexa\Core\FieldType\ValidationError[] */
029⫶    /** @return \Ibexa\Contracts\Core\FieldType\ValidationError[] */
030⫶    public function validate(Limitation $limitationValue): array
031⫶ {
032⫶ $validationErrors = [];
033⫶ if (!array_key_exists('value', $limitationValue->limitationValues)) {
034⫶ $validationErrors[] = new ValidationError("limitationValues['value'] is missing.");
035⫶ } elseif (!is_bool($limitationValue->limitationValues['value'])) {
036⫶ $validationErrors[] = new ValidationError("limitationValues['value'] is not a boolean.");
037⫶ }
038⫶
039⫶ return $validationErrors;
040⫶ }
041⫶
042⫶ public function buildValue(array $limitationValues): CustomLimitationValue
043⫶ {
044⫶ $value = false;
045⫶ if (array_key_exists('value', $limitationValues)) {
046⫶ $value = $limitationValues['value'];
047⫶ } elseif (count($limitationValues)) {
048⫶ $value = (bool)$limitationValues[0];
049⫶ }
050⫶
051⫶ return new CustomLimitationValue(['limitationValues' => ['value' => $value]]);
052⫶ }
053⫶
054⫶ /**
055⫶ * @param \Ibexa\Contracts\Core\Repository\Values\ValueObject[]|null $targets
056⫶ *
057⫶ * @return bool|null
058⫶ */
030⫶    public function validate(Limitation $limitationValue): array
031⫶ {
032⫶ $validationErrors = [];
033⫶ if (!array_key_exists('value', $limitationValue->limitationValues)) {
034⫶ $validationErrors[] = new ValidationError("limitationValues['value'] is missing.");
035⫶ } elseif (!is_bool($limitationValue->limitationValues['value'])) {
036⫶ $validationErrors[] = new ValidationError("limitationValues['value'] is not a boolean.");
037⫶ }
038⫶
039⫶ return $validationErrors;
040⫶ }
041⫶
042⫶ public function buildValue(array $limitationValues): CustomLimitationValue
043⫶ {
044⫶ $value = false;
045⫶ if (array_key_exists('value', $limitationValues)) {
046⫶ $value = $limitationValues['value'];
047⫶ } elseif (count($limitationValues)) {
048⫶ $value = (bool)$limitationValues[0];
049⫶ }
050⫶
051⫶ return new CustomLimitationValue(['limitationValues' => ['value' => $value]]);
052⫶ }
053⫶
054⫶ /**
055⫶ * @param \Ibexa\Contracts\Core\Repository\Values\ValueObject[]|null $targets
056⫶ *
057⫶ * @return bool|null
058⫶ */
059⫶    public function evaluate(Limitation $value, UserReference $currentUser, object $object, array $targets = null): ?bool
059⫶    public function evaluate(Limitation $value, UserReference $currentUser, object $object, ?array $targets = null): ?bool
060⫶    {
061⫶ if (!$value instanceof CustomLimitationValue) {
062⫶ throw new InvalidArgumentException('$value', 'Must be of type: CustomLimitationValue');
063⫶ }
064⫶
065⫶ if ($value->limitationValues['value']) {
066⫶ return Type::ACCESS_GRANTED;
067⫶ }
068⫶
069⫶ // 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
070⫶ return Type::ACCESS_DENIED;
071⫶ }
072⫶
073⫶ public function getCriterion(Limitation $value, UserReference $currentUser): CriterionInterface
074⫶ {
075⫶ throw new NotImplementedException(__METHOD__);
076⫶ }
077⫶
078⫶ public function valueSchema(): never
079⫶ {
080⫶ throw new NotImplementedException(__METHOD__);
081⫶ }
082⫶}


code_samples/catalog/custom_attribute_type/src/Attribute/Percent/Storage/PercentStorageConverter.php

060⫶    {
061⫶ if (!$value instanceof CustomLimitationValue) {
062⫶ throw new InvalidArgumentException('$value', 'Must be of type: CustomLimitationValue');
063⫶ }
064⫶
065⫶ if ($value->limitationValues['value']) {
066⫶ return Type::ACCESS_GRANTED;
067⫶ }
068⫶
069⫶ // 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
070⫶ return Type::ACCESS_DENIED;
071⫶ }
072⫶
073⫶ public function getCriterion(Limitation $value, UserReference $currentUser): CriterionInterface
074⫶ {
075⫶ throw new NotImplementedException(__METHOD__);
076⫶ }
077⫶
078⫶ public function valueSchema(): never
079⫶ {
080⫶ throw new NotImplementedException(__METHOD__);
081⫶ }
082⫶}


code_samples/catalog/custom_attribute_type/src/Attribute/Percent/Storage/PercentStorageConverter.php

docs/pim/create_custom_attribute_type.md@128:``` php
docs/pim/create_custom_attribute_type.md@129:[[= include_file('code_samples/catalog/custom_attribute_type/src/Attribute/Percent/Storage/PercentStorageConverter.php') =]]
docs/pim/create_custom_attribute_type.md@130:```
docs/pim/create_custom_attribute_type.md@151:``` php
docs/pim/create_custom_attribute_type.md@152:[[= include_file('code_samples/catalog/custom_attribute_type/src/Attribute/Percent/Storage/PercentStorageConverter.php') =]]
docs/pim/create_custom_attribute_type.md@153:```

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\Attribute\Percent\Storage;
006⫶
007⫶use Ibexa\Contracts\ProductCatalog\Local\Attribute\StorageConverterInterface;

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\Attribute\Percent\Storage;
006⫶
007⫶use Ibexa\Contracts\ProductCatalog\Local\Attribute\StorageConverterInterface;
008⫶use Ibexa\ProductCatalog\Local\Persistence\Legacy\Attribute\Float\StorageSchema;
009⫶use Webmozart\Assert\Assert;
010⫶
011⫶final class PercentStorageConverter implements StorageConverterInterface
012⫶{
013⫶ public function fromPersistence(array $data)
014⫶ {
015⫶ $value = $data[StorageSchema::COLUMN_VALUE];
016⫶ Assert::nullOrNumeric($value);
017⫶
018⫶ return $value;
019⫶ }
020⫶
021⫶ public function toPersistence($value): array
022⫶ {
023⫶ Assert::nullOrNumeric($value);
024⫶
025⫶ return [
026⫶ StorageSchema::COLUMN_VALUE => $value,
027⫶ ];
028⫶ }
029⫶}
008⫶use Webmozart\Assert\Assert;
009⫶
010⫶final class PercentStorageConverter implements StorageConverterInterface
011⫶{
012⫶ public function fromPersistence(array $data)
013⫶ {
014⫶ $value = $data['value'];
015⫶ Assert::nullOrNumeric($value);
016⫶
017⫶ return $value;
018⫶ }
019⫶
020⫶ public function toPersistence($value): array
021⫶ {
022⫶ Assert::nullOrNumeric($value);
023⫶
024⫶ return [
025⫶ 'value' => $value,
026⫶ ];
027⫶ }
028⫶}


code_samples/catalog/custom_attribute_type/src/Attribute/Percent/Storage/PercentStorageDefinition.php



code_samples/catalog/custom_attribute_type/src/Attribute/Percent/Storage/PercentStorageDefinition.php

docs/pim/create_custom_attribute_type.md@142:``` php
docs/pim/create_custom_attribute_type.md@143:[[= include_file('code_samples/catalog/custom_attribute_type/src/Attribute/Percent/Storage/PercentStorageDefinition.php') =]]
docs/pim/create_custom_attribute_type.md@144:```
docs/pim/create_custom_attribute_type.md@165:``` php
docs/pim/create_custom_attribute_type.md@166:[[= include_file('code_samples/catalog/custom_attribute_type/src/Attribute/Percent/Storage/PercentStorageDefinition.php') =]]
docs/pim/create_custom_attribute_type.md@167:```

001⫶<?php
002⫶
003⫶/**
004⫶ * @copyright Copyright (C) Ibexa AS. All rights reserved.
005⫶ * @license For full copyright and license information view LICENSE file distributed with this source code.
006⫶ */
007⫶declare(strict_types=1);
008⫶
009⫶namespace App\Attribute\Percent\Storage;
010⫶
011⫶use Doctrine\DBAL\Types\Types;
012⫶use Ibexa\Contracts\ProductCatalog\Local\Attribute\StorageDefinitionInterface;

001⫶<?php
002⫶
003⫶/**
004⫶ * @copyright Copyright (C) Ibexa AS. All rights reserved.
005⫶ * @license For full copyright and license information view LICENSE file distributed with this source code.
006⫶ */
007⫶declare(strict_types=1);
008⫶
009⫶namespace App\Attribute\Percent\Storage;
010⫶
011⫶use Doctrine\DBAL\Types\Types;
012⫶use Ibexa\Contracts\ProductCatalog\Local\Attribute\StorageDefinitionInterface;
013⫶use Ibexa\ProductCatalog\Local\Persistence\Legacy\Attribute\Float\StorageSchema;
014⫶
015⫶final class PercentStorageDefinition implements StorageDefinitionInterface
016⫶{
017⫶ public function getColumns(): array
018⫶ {
019⫶ return [
020⫶ StorageSchema::COLUMN_VALUE => Types::FLOAT,
021⫶ ];
022⫶ }
023⫶
024⫶ public function getTableName(): string
025⫶ {
026⫶ return StorageSchema::TABLE_NAME;
027⫶ }
028⫶}
013⫶
014⫶final class PercentStorageDefinition implements StorageDefinitionInterface
015⫶{
016⫶ public function getColumns(): array
017⫶ {
018⫶ return [
019⫶ 'value' => Types::FLOAT,
020⫶ ];
021⫶ }
022⫶
023⫶ public function getTableName(): string
024⫶ {
025⫶ return 'app_product_specification_attribute_percent';
026⫶ }
027⫶}


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.

2 participants