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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

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

namespace App\Collaboration\Cart;

use Ibexa\Contracts\Cart\CartResolverInterface;
use Ibexa\Contracts\Cart\Value\CartInterface;
use Ibexa\Contracts\Collaboration\SessionServiceInterface;
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
use Ibexa\Contracts\Core\Repository\Values\User\User;
use Symfony\Component\HttpFoundation\RequestStack;

final class CartResolverDecorator implements CartResolverInterface
{
public function __construct(
private CartResolverInterface $innerCartResolver,
private SessionServiceInterface $sessionService,
private RequestStack $requestStack
) {
}

public function resolveCart(?User $user = null): CartInterface
{
if ($this->hasSharedCart()) {
return $this->getSharedCart() ?? $this->innerCartResolver->resolveCart($user);
}

return $this->innerCartResolver->resolveCart($user);
}

private function getSharedCart(): ?CartInterface
{
/** @var \App\Collaboration\Cart\CartSession $session */
try {
$session = $this->sessionService->getSessionByToken(
$this->requestStack->getSession()->get(PermissionResolverDecorator::COLLABORATION_SESSION_ID)
);

return $session->getCart();
} catch (NotFoundException|\Ibexa\ProductCatalog\Exception\UnauthorizedException $e) {
return null;
}
}

private function hasSharedCart(): bool
{
return $this->requestStack->getSession()->has(PermissionResolverDecorator::COLLABORATION_SESSION_ID);
}
}
41 changes: 41 additions & 0 deletions code_samples/collaboration/src/Collaboration/Cart/CartSession.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

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

namespace App\Collaboration\Cart;

use DateTimeInterface;
use Ibexa\Contracts\Cart\Value\CartInterface;
use Ibexa\Contracts\Collaboration\Participant\ParticipantCollectionInterface;
use Ibexa\Contracts\Collaboration\Session\AbstractSession;
use Ibexa\Contracts\Core\Repository\Values\User\User;

final class CartSession extends AbstractSession
{
private CartInterface $cart;

public function __construct(
int $id,
CartInterface $cart,
string $token,
User $owner,
ParticipantCollectionInterface $participants,
bool $isActive,
bool $hasPublicLink,
DateTimeInterface $createdAt,
DateTimeInterface $updatedAt
) {
parent::__construct($id, $token, $owner, $participants, $isActive, $hasPublicLink, $createdAt, $updatedAt);

$this->cart = $cart;
}

public function getCart(): CartInterface
{
return $this->cart;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

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

namespace App\Collaboration\Cart;

use Ibexa\Contracts\Cart\Value\CartInterface;
use Ibexa\Contracts\Collaboration\Session\AbstractSessionCreateStruct;

final class CartSessionCreateStruct extends AbstractSessionCreateStruct
{
private CartInterface $cart;

public function __construct(CartInterface $cart)
{
parent::__construct();

$this->cart = $cart;
}

public function getCart(): CartInterface
{
return $this->cart;
}

public function setCart(CartInterface $cart): void
{
$this->cart = $cart;
}

public function getType(): string
{
return CartSessionType::IDENTIFIER;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

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

namespace App\Collaboration\Cart;

use Ibexa\Contracts\Collaboration\Session\SessionScopeInterface;

final class CartSessionType implements SessionScopeInterface
{
public const SCOPE_VIEW = 'view';
public const SCOPE_EDIT = 'edit';

public const IDENTIFIER = 'cart';

private function __construct()
{
// This class is not intended to be instantiated
}

public function getDefaultScope(): string
{
return self::SCOPE_VIEW;
}

public function isValidScope(string $scope): bool
{
return in_array($scope, $this->getScopes(), true);
}

public function getScopes(): array
{
return [
self::SCOPE_VIEW,
self::SCOPE_EDIT,
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

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

namespace App\Collaboration\Cart;

use Ibexa\Contracts\Collaboration\Session\AbstractSessionUpdateStruct;

final class CartSessionUpdateStruct extends AbstractSessionUpdateStruct
{
public function getType(): string
{
return CartSessionType::IDENTIFIER;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

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

namespace App\Collaboration\Cart\Mapper;

use Ibexa\Contracts\Cart\CartServiceInterface;
use Ibexa\Contracts\Cart\Value\CartInterface;
use Ibexa\Contracts\Core\Repository\Repository;
use Ibexa\Core\Repository\ProxyFactory\ProxyGeneratorInterface;
use ProxyManager\Proxy\LazyLoadingInterface;

final class CartProxyMapper implements CartProxyMapperInterface
{
public function __construct(
private Repository $repository,
private CartServiceInterface $cartService,
private ProxyGeneratorInterface $proxyGenerator
) {
}

public function createCartProxy(string $identifier): CartInterface
{
$initializer = function (
&$wrappedObject,
LazyLoadingInterface $proxy,
$method,
array $parameters,
&$initializer
) use ($identifier): bool {
$initializer = null;
$wrappedObject = $this->repository->sudo(fn () => $this->cartService->getCart($identifier));

return true;
};

return $this->proxyGenerator->createProxy(CartInterface::class, $initializer);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

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

namespace App\Collaboration\Cart\Mapper;

use Ibexa\Contracts\Cart\Value\CartInterface;

interface CartProxyMapperInterface
{
public function createCartProxy(string $identifier): CartInterface;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

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

namespace App\Collaboration\Cart\Mapper;

use App\Collaboration\Cart\CartSession;
use Ibexa\Collaboration\Mapper\Domain\ParticipantCollectionDomainMapperInterface;
use Ibexa\Collaboration\Mapper\Domain\SessionDomainMapperInterface;
use Ibexa\Collaboration\Mapper\Domain\UserProxyDomainMapperInterface;
use Ibexa\Collaboration\Persistence\Values\AbstractSession as SessionData;
use Ibexa\Contracts\Collaboration\Session\SessionInterface;

/**
* @template-implements \Ibexa\Collaboration\Mapper\Domain\SessionDomainMapperInterface<
* \App\Collaboration\Cart\Persistence\Values\CartSession
* >
*/
final class CartSessionDomainMapper implements SessionDomainMapperInterface
{
public function __construct(
private CartProxyMapperInterface $cartProxyMapper,
private UserProxyDomainMapperInterface $userDomainMapper,
private ParticipantCollectionDomainMapperInterface $participantCollectionDomainMapper
) {
}

/**
* @param \App\Collaboration\Cart\Persistence\Values\CartSession $data
*/
public function fromPersistence(SessionData $data): SessionInterface
{
return new CartSession(
$data->getId(),
$this->cartProxyMapper->createCartProxy($data->getCartIdentifier()),
$data->getToken(),
$this->userDomainMapper->createUserProxy($data->getOwnerId()),
$this->participantCollectionDomainMapper->createParticipantCollectionProxy($data->getId()),
$data->isActive(),
$data->hasPublicLink(),
$data->getCreatedAt(),
$data->getUpdatedAt(),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

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

namespace App\Collaboration\Cart\Mapper;

use App\Collaboration\Cart\Persistence\Values\CartSessionCreateStruct;
use App\Collaboration\Cart\Persistence\Values\CartSessionUpdateStruct;
use Ibexa\Collaboration\Mapper\Persistence\SessionPersistenceMapperInterface;
use Ibexa\Collaboration\Persistence\Values\AbstractSessionCreateStruct as PersistenceSessionCreateStruct;
use Ibexa\Collaboration\Persistence\Values\AbstractSessionUpdateStruct as PersistenceSessionUpdateStruct;
use Ibexa\Contracts\Collaboration\Session\AbstractSessionCreateStruct as SessionCreateStruct;
use Ibexa\Contracts\Collaboration\Session\AbstractSessionUpdateStruct as SessionUpdateStruct;
use Ibexa\Contracts\Collaboration\Session\SessionInterface;

final class CartSessionPersistenceMapper implements SessionPersistenceMapperInterface
{
/**
* @param \App\Collaboration\Cart\CartSessionCreateStruct $createStruct
*/
public function toPersistenceCreateStruct(
SessionCreateStruct $createStruct
): PersistenceSessionCreateStruct {
return new CartSessionCreateStruct(
$createStruct->getToken(),
$createStruct->getCart()->getIdentifier(),
$createStruct->getOwner()->getUserId(),
$createStruct->isActive(),
$createStruct->hasPublicLink(),
new \DateTimeImmutable(),
new \DateTimeImmutable()
);
}

public function toPersistenceUpdateStruct(
SessionInterface $session,
SessionUpdateStruct $updateStruct
): PersistenceSessionUpdateStruct {
return new CartSessionUpdateStruct(
$session->getId(),
$updateStruct->getToken(),
($updateStruct->getOwner() ?? $session->getOwner())->getUserId()
);
}
}
Loading
Loading