Skip to content

Commit b6002ac

Browse files
adriendupuisjulitafalconduszaciastektkmnocon
authored
IBX-11083: Extending collaboration described in Developer Documentation (4.6) (#3094)
* IBX-11083: Extending collaboration described in Developer Documentation (#3055) * Downgrade to Commerce 4.6.28 / PHP 7.4 --------- Co-authored-by: julitafalcondusza <julitafalcondusza@users.noreply.github.com> Co-authored-by: Tomasz Kryszan <tomasz.kryszan@ibexa.co> Co-authored-by: adriendupuis <adriendupuis@users.noreply.github.com> Co-authored-by: Marek Nocoń <mnocon@users.noreply.github.com>
1 parent 6fdb999 commit b6002ac

35 files changed

+1245
-4
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# This file is the entry point to configure your own services.
2+
# Files in the packages/ subdirectory configure your dependencies.
3+
4+
# Put parameters here that don't need to change on each machine where the app is deployed
5+
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
6+
parameters:
7+
8+
services:
9+
# default configuration for services in *this* file
10+
_defaults:
11+
autowire: true # Automatically injects dependencies in your services.
12+
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
13+
14+
# makes classes in src/ available to be used as services
15+
# this creates a service per class whose id is the fully-qualified class name
16+
App\:
17+
resource: '../src/'
18+
exclude:
19+
- '../src/DependencyInjection/'
20+
- '../src/Entity/'
21+
- '../src/Kernel.php'
22+
23+
# add more service definitions when explicit configuration is needed
24+
# please note that last definitions always *replace* previous ones
25+
26+
App\Collaboration\Cart\Persistence\Gateway\DatabaseGateway:
27+
arguments:
28+
$connection: '@ibexa.persistence.connection'
29+
tags:
30+
- name: 'ibexa.collaboration.persistence.session.gateway'
31+
discriminator: !php/const App\Collaboration\Cart\Persistence\Gateway\DatabaseGateway::DISCRIMINATOR
32+
33+
App\Collaboration\Cart\Persistence\Mapper:
34+
tags:
35+
- name: 'ibexa.collaboration.persistence.session.mapper'
36+
discriminator: !php/const App\Collaboration\Cart\Persistence\Gateway\DatabaseGateway::DISCRIMINATOR
37+
38+
App\Collaboration\Cart\Mapper\CartSessionDomainMapper:
39+
tags:
40+
- name: 'ibexa.collaboration.service.session.domain.mapper'
41+
type: App\Collaboration\Cart\Persistence\Values\CartSession
42+
43+
App\Collaboration\Cart\Mapper\CartSessionPersistenceMapper:
44+
tags:
45+
- name: 'ibexa.collaboration.service.session.persistence.mapper'
46+
type: !php/const App\Collaboration\Cart\CartSessionType::IDENTIFIER
47+
48+
App\Collaboration\Cart\PermissionResolverDecorator:
49+
decorates: Ibexa\Contracts\ProductCatalog\PermissionResolverInterface
50+
51+
App\Collaboration\Cart\CartResolverDecorator:
52+
decorates: Ibexa\Contracts\Cart\CartResolverInterface
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CREATE TABLE ibexa_collaboration_cart (
2+
id INT NOT NULL PRIMARY KEY,
3+
cart_identifier VARCHAR(255) NOT NULL,
4+
CONSTRAINT ibexa_collaboration_cart_ibexa_collaboration_id_fk
5+
FOREIGN KEY (id) REFERENCES ibexa_collaboration (id)
6+
ON DELETE CASCADE
7+
) COLLATE = utf8mb4_general_ci;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CREATE TABLE ibexa_collaboration_cart (
2+
id INTEGER NOT NULL PRIMARY KEY,
3+
cart_identifier VARCHAR(255) NOT NULL,
4+
CONSTRAINT ibexa_collaboration_cart_ibexa_collaboration_id_fk
5+
FOREIGN KEY (id) REFERENCES ibexa_collaboration (id)
6+
ON DELETE CASCADE
7+
);
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\Collaboration\Cart;
4+
5+
use Ibexa\Contracts\Cart\CartResolverInterface;
6+
use Ibexa\Contracts\Cart\Value\CartInterface;
7+
use Ibexa\Contracts\Collaboration\SessionServiceInterface;
8+
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
9+
use Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException;
10+
use Ibexa\Contracts\Core\Repository\Values\User\User;
11+
use Symfony\Component\HttpFoundation\RequestStack;
12+
13+
final class CartResolverDecorator implements CartResolverInterface
14+
{
15+
private CartResolverInterface $innerCartResolver;
16+
17+
private SessionServiceInterface $sessionService;
18+
19+
private RequestStack $requestStack;
20+
21+
public function __construct(
22+
CartResolverInterface $innerCartResolver,
23+
SessionServiceInterface $sessionService,
24+
RequestStack $requestStack
25+
) {
26+
$this->innerCartResolver = $innerCartResolver;
27+
$this->sessionService = $sessionService;
28+
$this->requestStack = $requestStack;
29+
}
30+
31+
public function resolveCart(?User $user = null): CartInterface
32+
{
33+
if ($this->hasSharedCart()) {
34+
return $this->getSharedCart() ?? $this->innerCartResolver->resolveCart($user);
35+
}
36+
37+
return $this->innerCartResolver->resolveCart($user);
38+
}
39+
40+
private function getSharedCart(): ?CartInterface
41+
{
42+
try {
43+
$session = $this->sessionService->getSessionByToken(
44+
$this->requestStack->getSession()->get(PermissionResolverDecorator::COLLABORATION_SESSION_ID)
45+
);
46+
47+
if (!$session instanceof CartSession) {
48+
return null;
49+
}
50+
51+
return $session->getCart();
52+
} catch (NotFoundException|UnauthorizedException $exception) {
53+
return null;
54+
}
55+
}
56+
57+
private function hasSharedCart(): bool
58+
{
59+
return $this->requestStack->getSession()->has(PermissionResolverDecorator::COLLABORATION_SESSION_ID);
60+
}
61+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\Collaboration\Cart;
4+
5+
use DateTimeInterface;
6+
use Ibexa\Contracts\Cart\Value\CartInterface;
7+
use Ibexa\Contracts\Collaboration\Participant\ParticipantCollectionInterface;
8+
use Ibexa\Contracts\Collaboration\Session\AbstractSession;
9+
use Ibexa\Contracts\Core\Repository\Values\User\User;
10+
11+
final class CartSession extends AbstractSession
12+
{
13+
private CartInterface $cart;
14+
15+
public function __construct(
16+
int $id,
17+
CartInterface $cart,
18+
string $token,
19+
User $owner,
20+
ParticipantCollectionInterface $participants,
21+
bool $isActive,
22+
bool $hasPublicLink,
23+
DateTimeInterface $createdAt,
24+
DateTimeInterface $updatedAt
25+
) {
26+
$this->cart = $cart;
27+
parent::__construct($id, $token, $owner, $participants, $isActive, $hasPublicLink, $createdAt, $updatedAt);
28+
}
29+
30+
public function getCart(): CartInterface
31+
{
32+
return $this->cart;
33+
}
34+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\Collaboration\Cart;
4+
5+
use Ibexa\Contracts\Cart\Value\CartInterface;
6+
use Ibexa\Contracts\Collaboration\Session\AbstractSessionCreateStruct;
7+
8+
final class CartSessionCreateStruct extends AbstractSessionCreateStruct
9+
{
10+
private CartInterface $cart;
11+
12+
public function __construct(CartInterface $cart)
13+
{
14+
$this->cart = $cart;
15+
parent::__construct();
16+
}
17+
18+
public function getCart(): CartInterface
19+
{
20+
return $this->cart;
21+
}
22+
23+
public function setCart(CartInterface $cart): void
24+
{
25+
$this->cart = $cart;
26+
}
27+
28+
public function getType(): string
29+
{
30+
return CartSessionType::IDENTIFIER;
31+
}
32+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\Collaboration\Cart;
4+
5+
use Ibexa\Contracts\Collaboration\Session\SessionScopeInterface;
6+
7+
final class CartSessionType implements SessionScopeInterface
8+
{
9+
public const SCOPE_VIEW = 'view';
10+
public const SCOPE_EDIT = 'edit';
11+
12+
public const IDENTIFIER = 'cart';
13+
14+
private function __construct()
15+
{
16+
// This class is not intended to be instantiated
17+
}
18+
19+
public function getDefaultScope(): string
20+
{
21+
return self::SCOPE_VIEW;
22+
}
23+
24+
public function isValidScope(string $scope): bool
25+
{
26+
return in_array($scope, $this->getScopes(), true);
27+
}
28+
29+
public function getScopes(): array
30+
{
31+
return [
32+
self::SCOPE_VIEW,
33+
self::SCOPE_EDIT,
34+
];
35+
}
36+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\Collaboration\Cart;
4+
5+
use Ibexa\Contracts\Collaboration\Session\AbstractSessionUpdateStruct;
6+
7+
final class CartSessionUpdateStruct extends AbstractSessionUpdateStruct
8+
{
9+
public function getType(): string
10+
{
11+
return CartSessionType::IDENTIFIER;
12+
}
13+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\Collaboration\Cart\Mapper;
4+
5+
use Ibexa\Contracts\Cart\CartServiceInterface;
6+
use Ibexa\Contracts\Cart\Value\CartInterface;
7+
use Ibexa\Contracts\Core\Repository\Repository;
8+
use Ibexa\Core\Repository\ProxyFactory\ProxyGeneratorInterface;
9+
use ProxyManager\Proxy\LazyLoadingInterface;
10+
11+
final class CartProxyMapper implements CartProxyMapperInterface
12+
{
13+
private Repository $repository;
14+
15+
private CartServiceInterface $cartService;
16+
17+
private ProxyGeneratorInterface $proxyGenerator;
18+
19+
public function __construct(
20+
Repository $repository,
21+
CartServiceInterface $cartService,
22+
ProxyGeneratorInterface $proxyGenerator
23+
) {
24+
$this->repository = $repository;
25+
$this->cartService = $cartService;
26+
$this->proxyGenerator = $proxyGenerator;
27+
}
28+
29+
public function createCartProxy(string $identifier): CartInterface
30+
{
31+
$initializer = function (
32+
&$wrappedObject,
33+
LazyLoadingInterface $proxy,
34+
$method,
35+
array $parameters,
36+
&$initializer
37+
) use ($identifier): bool {
38+
$initializer = null;
39+
$wrappedObject = $this->repository->sudo(fn (): CartInterface => $this->cartService->getCart($identifier));
40+
41+
return true;
42+
};
43+
44+
return $this->proxyGenerator->createProxy(CartInterface::class, $initializer);
45+
}
46+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\Collaboration\Cart\Mapper;
4+
5+
use Ibexa\Contracts\Cart\Value\CartInterface;
6+
7+
interface CartProxyMapperInterface
8+
{
9+
public function createCartProxy(string $identifier): CartInterface;
10+
}

0 commit comments

Comments
 (0)