Skip to content

IBX-11083: Extending collaboration described in Developer Documentation#3055

Draft
julitafalcondusza wants to merge 3 commits into5.0from
IBX-11083
Draft

IBX-11083: Extending collaboration described in Developer Documentation#3055
julitafalcondusza wants to merge 3 commits into5.0from
IBX-11083

Conversation

@julitafalcondusza
Copy link
Contributor

Question Answer
JIRA Ticket (https://ibexa.atlassian.net/browse/IBX-11083)
Versions 4.6+

Extending collaboration described in Developer Documentation

Checklist

  • Text renders correctly
  • Text has been checked with vale
  • Description metadata is up to date
  • Redirects cover removed/moved pages
  • Code samples are working
  • PHP code samples have been fixed with PHP CS fixer
  • Added link to this PR in relevant JIRA ticket or code PR

@github-actions
Copy link

Preview of modified files

Preview of modified Markdown:

@github-actions
Copy link

code_samples/ change report

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

code_samples/collaboration/src/Collaboration/Cart/CartResolverDecorator.php


code_samples/collaboration/src/Collaboration/Cart/CartResolverDecorator.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@163:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@164:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/CartResolverDecorator.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@165:```

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\Collaboration\Cart;
010⫶
011⫶use Ibexa\Contracts\Cart\CartResolverInterface;
012⫶use Ibexa\Contracts\Cart\Value\CartInterface;
013⫶use Ibexa\Contracts\Collaboration\SessionServiceInterface;
014⫶use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
015⫶use Ibexa\Contracts\Core\Repository\Values\User\User;
016⫶use Symfony\Component\HttpFoundation\RequestStack;
017⫶
018⫶final class CartResolverDecorator implements CartResolverInterface
019⫶{
020⫶ public function __construct(
021⫶ private CartResolverInterface $innerCartResolver,
022⫶ private SessionServiceInterface $sessionService,
023⫶ private RequestStack $requestStack
024⫶ ) {
025⫶ }
026⫶
027⫶ public function resolveCart(?User $user = null): CartInterface
028⫶ {
029⫶ if ($this->hasSharedCart()) {
030⫶ return $this->getSharedCart() ?? $this->innerCartResolver->resolveCart($user);
031⫶ }
032⫶
033⫶ return $this->innerCartResolver->resolveCart($user);
034⫶ }
035⫶
036⫶ private function getSharedCart(): ?CartInterface
037⫶ {
038⫶ /** @var \App\Collaboration\Cart\CartSession $session */
039⫶ try {
040⫶ $session = $this->sessionService->getSessionByToken(
041⫶ $this->requestStack->getSession()->get(PermissionResolverDecorator::COLLABORATION_SESSION_ID)
042⫶ );
043⫶
044⫶ return $session->getCart();
045⫶ } catch (NotFoundException|\Ibexa\ProductCatalog\Exception\UnauthorizedException $e) {
046⫶ return null;
047⫶ }
048⫶ }
049⫶
050⫶ private function hasSharedCart(): bool
051⫶ {
052⫶ return $this->requestStack->getSession()->has(PermissionResolverDecorator::COLLABORATION_SESSION_ID);
053⫶ }
054⫶}


code_samples/collaboration/src/Collaboration/Cart/CartSession.php


code_samples/collaboration/src/Collaboration/Cart/CartSession.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@95:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@96:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/CartSession.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@97:```

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\Collaboration\Cart;
010⫶
011⫶use DateTimeInterface;
012⫶use Ibexa\Contracts\Cart\Value\CartInterface;
013⫶use Ibexa\Contracts\Collaboration\Participant\ParticipantCollectionInterface;
014⫶use Ibexa\Contracts\Collaboration\Session\AbstractSession;
015⫶use Ibexa\Contracts\Core\Repository\Values\User\User;
016⫶
017⫶final class CartSession extends AbstractSession
018⫶{
019⫶ private CartInterface $cart;
020⫶
021⫶ public function __construct(
022⫶ int $id,
023⫶ CartInterface $cart,
024⫶ string $token,
025⫶ User $owner,
026⫶ ParticipantCollectionInterface $participants,
027⫶ bool $isActive,
028⫶ bool $hasPublicLink,
029⫶ DateTimeInterface $createdAt,
030⫶ DateTimeInterface $updatedAt
031⫶ ) {
032⫶ parent::__construct($id, $token, $owner, $participants, $isActive, $hasPublicLink, $createdAt, $updatedAt);
033⫶
034⫶ $this->cart = $cart;
035⫶ }
036⫶
037⫶ public function getCart(): CartInterface
038⫶ {
039⫶ return $this->cart;
040⫶ }
041⫶}

docs/content_management/collaborative_editing/extend_collaborative_editing.md@132:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@133:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/CartSession.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@134:```

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\Collaboration\Cart;
010⫶
011⫶use DateTimeInterface;
012⫶use Ibexa\Contracts\Cart\Value\CartInterface;
013⫶use Ibexa\Contracts\Collaboration\Participant\ParticipantCollectionInterface;
014⫶use Ibexa\Contracts\Collaboration\Session\AbstractSession;
015⫶use Ibexa\Contracts\Core\Repository\Values\User\User;
016⫶
017⫶final class CartSession extends AbstractSession
018⫶{
019⫶ private CartInterface $cart;
020⫶
021⫶ public function __construct(
022⫶ int $id,
023⫶ CartInterface $cart,
024⫶ string $token,
025⫶ User $owner,
026⫶ ParticipantCollectionInterface $participants,
027⫶ bool $isActive,
028⫶ bool $hasPublicLink,
029⫶ DateTimeInterface $createdAt,
030⫶ DateTimeInterface $updatedAt
031⫶ ) {
032⫶ parent::__construct($id, $token, $owner, $participants, $isActive, $hasPublicLink, $createdAt, $updatedAt);
033⫶
034⫶ $this->cart = $cart;
035⫶ }
036⫶
037⫶ public function getCart(): CartInterface
038⫶ {
039⫶ return $this->cart;
040⫶ }
041⫶}


code_samples/collaboration/src/Collaboration/Cart/CartSessionCreateStruct.php


code_samples/collaboration/src/Collaboration/Cart/CartSessionCreateStruct.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@101:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@102:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/CartSessionCreateStruct.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@103:```

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\Collaboration\Cart;
010⫶
011⫶use Ibexa\Contracts\Cart\Value\CartInterface;
012⫶use Ibexa\Contracts\Collaboration\Session\AbstractSessionCreateStruct;
013⫶
014⫶final class CartSessionCreateStruct extends AbstractSessionCreateStruct
015⫶{
016⫶ private CartInterface $cart;
017⫶
018⫶ public function __construct(CartInterface $cart)
019⫶ {
020⫶ parent::__construct();
021⫶
022⫶ $this->cart = $cart;
023⫶ }
024⫶
025⫶ public function getCart(): CartInterface
026⫶ {
027⫶ return $this->cart;
028⫶ }
029⫶
030⫶ public function setCart(CartInterface $cart): void
031⫶ {
032⫶ $this->cart = $cart;
033⫶ }
034⫶
035⫶ public function getType(): string
036⫶ {
037⫶ return CartSessionType::IDENTIFIER;
038⫶ }
039⫶}

docs/content_management/collaborative_editing/extend_collaborative_editing.md@120:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@121:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/CartSessionCreateStruct.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@122:```

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\Collaboration\Cart;
010⫶
011⫶use Ibexa\Contracts\Cart\Value\CartInterface;
012⫶use Ibexa\Contracts\Collaboration\Session\AbstractSessionCreateStruct;
013⫶
014⫶final class CartSessionCreateStruct extends AbstractSessionCreateStruct
015⫶{
016⫶ private CartInterface $cart;
017⫶
018⫶ public function __construct(CartInterface $cart)
019⫶ {
020⫶ parent::__construct();
021⫶
022⫶ $this->cart = $cart;
023⫶ }
024⫶
025⫶ public function getCart(): CartInterface
026⫶ {
027⫶ return $this->cart;
028⫶ }
029⫶
030⫶ public function setCart(CartInterface $cart): void
031⫶ {
032⫶ $this->cart = $cart;
033⫶ }
034⫶
035⫶ public function getType(): string
036⫶ {
037⫶ return CartSessionType::IDENTIFIER;
038⫶ }
039⫶}


code_samples/collaboration/src/Collaboration/Cart/CartSessionType.php


code_samples/collaboration/src/Collaboration/Cart/CartSessionType.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@138:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@139:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/CartSessionType.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@140:```

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\Collaboration\Cart;
010⫶
011⫶use Ibexa\Contracts\Collaboration\Session\SessionScopeInterface;
012⫶
013⫶final class CartSessionType implements SessionScopeInterface
014⫶{
015⫶ public const SCOPE_VIEW = 'view';
016⫶ public const SCOPE_EDIT = 'edit';
017⫶
018⫶ public const IDENTIFIER = 'cart';
019⫶
020⫶ private function __construct()
021⫶ {
022⫶ // This class is not intended to be instantiated
023⫶ }
024⫶
025⫶ public function getDefaultScope(): string
026⫶ {
027⫶ return self::SCOPE_VIEW;
028⫶ }
029⫶
030⫶ public function isValidScope(string $scope): bool
031⫶ {
032⫶ return in_array($scope, $this->getScopes(), true);
033⫶ }
034⫶
035⫶ public function getScopes(): array
036⫶ {
037⫶ return [
038⫶ self::SCOPE_VIEW,
039⫶ self::SCOPE_EDIT,
040⫶ ];
041⫶ }
042⫶}


code_samples/collaboration/src/Collaboration/Cart/CartSessionUpdateStruct.php


code_samples/collaboration/src/Collaboration/Cart/CartSessionUpdateStruct.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@107:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@108:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/CartSessionUpdateStruct.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@109:```

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\Collaboration\Cart;
010⫶
011⫶use Ibexa\Contracts\Collaboration\Session\AbstractSessionUpdateStruct;
012⫶
013⫶final class CartSessionUpdateStruct extends AbstractSessionUpdateStruct
014⫶{
015⫶ public function getType(): string
016⫶ {
017⫶ return CartSessionType::IDENTIFIER;
018⫶ }
019⫶}

docs/content_management/collaborative_editing/extend_collaborative_editing.md@126:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@127:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/CartSessionUpdateStruct.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@128:```

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\Collaboration\Cart;
010⫶
011⫶use Ibexa\Contracts\Collaboration\Session\AbstractSessionUpdateStruct;
012⫶
013⫶final class CartSessionUpdateStruct extends AbstractSessionUpdateStruct
014⫶{
015⫶ public function getType(): string
016⫶ {
017⫶ return CartSessionType::IDENTIFIER;
018⫶ }
019⫶}


code_samples/collaboration/src/Collaboration/Cart/Mapper/CartProxyMapper.php


code_samples/collaboration/src/Collaboration/Cart/Mapper/CartProxyMapper.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@175:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@176:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/Mapper/CartProxyMapper.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@177:```

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\Collaboration\Cart\Mapper;
010⫶
011⫶use Ibexa\Contracts\Cart\CartServiceInterface;
012⫶use Ibexa\Contracts\Cart\Value\CartInterface;
013⫶use Ibexa\Contracts\Core\Repository\Repository;
014⫶use Ibexa\Core\Repository\ProxyFactory\ProxyGeneratorInterface;
015⫶use ProxyManager\Proxy\LazyLoadingInterface;
016⫶
017⫶final class CartProxyMapper implements CartProxyMapperInterface
018⫶{
019⫶ public function __construct(
020⫶ private Repository $repository,
021⫶ private CartServiceInterface $cartService,
022⫶ private ProxyGeneratorInterface $proxyGenerator
023⫶ ) {
024⫶ }
025⫶
026⫶ public function createCartProxy(string $identifier): CartInterface
027⫶ {
028⫶ $initializer = function (
029⫶ &$wrappedObject,
030⫶ LazyLoadingInterface $proxy,
031⫶ $method,
032⫶ array $parameters,
033⫶ &$initializer
034⫶ ) use ($identifier): bool {
035⫶ $initializer = null;
036⫶ $wrappedObject = $this->repository->sudo(fn () => $this->cartService->getCart($identifier));
037⫶
038⫶ return true;
039⫶ };
040⫶
041⫶ return $this->proxyGenerator->createProxy(CartInterface::class, $initializer);
042⫶ }
043⫶}


code_samples/collaboration/src/Collaboration/Cart/Mapper/CartProxyMapperInterface.php


code_samples/collaboration/src/Collaboration/Cart/Mapper/CartProxyMapperInterface.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@181:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@182:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/Mapper/CartProxyMapperInterface.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@183:```

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\Collaboration\Cart\Mapper;
010⫶
011⫶use Ibexa\Contracts\Cart\Value\CartInterface;
012⫶
013⫶interface CartProxyMapperInterface
014⫶{
015⫶ public function createCartProxy(string $identifier): CartInterface;
016⫶}


code_samples/collaboration/src/Collaboration/Cart/Mapper/CartSessionDomainMapper.php


code_samples/collaboration/src/Collaboration/Cart/Mapper/CartSessionDomainMapper.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@187:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@188:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/Mapper/CartSessionDomainMapper.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@189:```

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\Collaboration\Cart\Mapper;
010⫶
011⫶use App\Collaboration\Cart\CartSession;
012⫶use Ibexa\Collaboration\Mapper\Domain\ParticipantCollectionDomainMapperInterface;
013⫶use Ibexa\Collaboration\Mapper\Domain\SessionDomainMapperInterface;
014⫶use Ibexa\Collaboration\Mapper\Domain\UserProxyDomainMapperInterface;
015⫶use Ibexa\Collaboration\Persistence\Values\AbstractSession as SessionData;
016⫶use Ibexa\Contracts\Collaboration\Session\SessionInterface;
017⫶
018⫶/**
019⫶ * @template-implements \Ibexa\Collaboration\Mapper\Domain\SessionDomainMapperInterface<
020⫶ * \App\Collaboration\Cart\Persistence\Values\CartSession
021⫶ * >
022⫶ */
023⫶final class CartSessionDomainMapper implements SessionDomainMapperInterface
024⫶{
025⫶ public function __construct(
026⫶ private CartProxyMapperInterface $cartProxyMapper,
027⫶ private UserProxyDomainMapperInterface $userDomainMapper,
028⫶ private ParticipantCollectionDomainMapperInterface $participantCollectionDomainMapper
029⫶ ) {
030⫶ }
031⫶
032⫶ /**
033⫶ * @param \App\Collaboration\Cart\Persistence\Values\CartSession $data
034⫶ */
035⫶ public function fromPersistence(SessionData $data): SessionInterface
036⫶ {
037⫶ return new CartSession(
038⫶ $data->getId(),
039⫶ $this->cartProxyMapper->createCartProxy($data->getCartIdentifier()),
040⫶ $data->getToken(),
041⫶ $this->userDomainMapper->createUserProxy($data->getOwnerId()),
042⫶ $this->participantCollectionDomainMapper->createParticipantCollectionProxy($data->getId()),
043⫶ $data->isActive(),
044⫶ $data->hasPublicLink(),
045⫶ $data->getCreatedAt(),
046⫶ $data->getUpdatedAt(),
047⫶ );
048⫶ }
049⫶}


code_samples/collaboration/src/Collaboration/Cart/Mapper/CartSessionPersistenceMapper.php


code_samples/collaboration/src/Collaboration/Cart/Mapper/CartSessionPersistenceMapper.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@193:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@194:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/Mapper/CartSessionPersistenceMapper.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@195:```

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\Collaboration\Cart\Mapper;
010⫶
011⫶use App\Collaboration\Cart\Persistence\Values\CartSessionCreateStruct;
012⫶use App\Collaboration\Cart\Persistence\Values\CartSessionUpdateStruct;
013⫶use Ibexa\Collaboration\Mapper\Persistence\SessionPersistenceMapperInterface;
014⫶use Ibexa\Collaboration\Persistence\Values\AbstractSessionCreateStruct as PersistenceSessionCreateStruct;
015⫶use Ibexa\Collaboration\Persistence\Values\AbstractSessionUpdateStruct as PersistenceSessionUpdateStruct;
016⫶use Ibexa\Contracts\Collaboration\Session\AbstractSessionCreateStruct as SessionCreateStruct;
017⫶use Ibexa\Contracts\Collaboration\Session\AbstractSessionUpdateStruct as SessionUpdateStruct;
018⫶use Ibexa\Contracts\Collaboration\Session\SessionInterface;
019⫶
020⫶final class CartSessionPersistenceMapper implements SessionPersistenceMapperInterface
021⫶{
022⫶ /**
023⫶ * @param \App\Collaboration\Cart\CartSessionCreateStruct $createStruct
024⫶ */
025⫶ public function toPersistenceCreateStruct(
026⫶ SessionCreateStruct $createStruct
027⫶ ): PersistenceSessionCreateStruct {
028⫶ return new CartSessionCreateStruct(
029⫶ $createStruct->getToken(),
030⫶ $createStruct->getCart()->getIdentifier(),
031⫶ $createStruct->getOwner()->getUserId(),
032⫶ $createStruct->isActive(),
033⫶ $createStruct->hasPublicLink(),
034⫶ new \DateTimeImmutable(),
035⫶ new \DateTimeImmutable()
036⫶ );
037⫶ }
038⫶
039⫶ public function toPersistenceUpdateStruct(
040⫶ SessionInterface $session,
041⫶ SessionUpdateStruct $updateStruct
042⫶ ): PersistenceSessionUpdateStruct {
043⫶ return new CartSessionUpdateStruct(
044⫶ $session->getId(),
045⫶ $updateStruct->getToken(),
046⫶ ($updateStruct->getOwner() ?? $session->getOwner())->getUserId()
047⫶ );
048⫶ }
049⫶}


code_samples/collaboration/src/Collaboration/Cart/PermissionResolverDecorator.php


code_samples/collaboration/src/Collaboration/Cart/PermissionResolverDecorator.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@157:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@158:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/PermissionResolverDecorator.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@159:```

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\Collaboration\Cart;
010⫶
011⫶use Ibexa\Contracts\Cart\Permission\Policy\Cart\Edit as CartEdit;
012⫶use Ibexa\Contracts\Cart\Permission\Policy\Cart\View as CartView;
013⫶use Ibexa\Contracts\Cart\Value\CartInterface;
014⫶use Ibexa\Contracts\Collaboration\SessionServiceInterface;
015⫶use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
016⫶use Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException;
017⫶use Ibexa\Contracts\ProductCatalog\Permission\Policy\PolicyInterface;
018⫶use Ibexa\Contracts\ProductCatalog\PermissionResolverInterface;
019⫶use Symfony\Component\HttpFoundation\RequestStack;
020⫶
021⫶final class PermissionResolverDecorator implements PermissionResolverInterface
022⫶{
023⫶ public const COLLABORATION_SESSION_ID = 'collaboration_session';
024⫶
025⫶ private bool $nested = false;
026⫶
027⫶ public function __construct(
028⫶ private PermissionResolverInterface $innerPermissionResolver,
029⫶ private SessionServiceInterface $sessionService,
030⫶ private RequestStack $requestStack,
031⫶ ) {
032⫶ }
033⫶
034⫶ public function canUser(PolicyInterface $policy): bool
035⫶ {
036⫶ if ($this->nested === false && $this->isCartPolicy($policy) && $this->isSharedCart($policy->getObject())) {
037⫶ return true;
038⫶ }
039⫶
040⫶ return $this->innerPermissionResolver->canUser($policy);
041⫶ }
042⫶
043⫶ public function assertPolicy(PolicyInterface $policy): void
044⫶ {
045⫶ if ($this->nested === false && $this->isCartPolicy($policy) && $this->isSharedCart($policy->getObject())) {
046⫶ return;
047⫶ }
048⫶
049⫶ $this->innerPermissionResolver->assertPolicy($policy);
050⫶ }
051⫶
052⫶ private function isCartPolicy(PolicyInterface $policy): bool
053⫶ {
054⫶ return $policy instanceof CartView || $policy instanceof CartEdit;
055⫶ }
056⫶
057⫶ private function isSharedCart(?CartInterface $cart): bool
058⫶ {
059⫶ if ($cart === null) {
060⫶ return false;
061⫶ }
062⫶
063⫶ try {
064⫶ $this->nested = true;
065⫶
066⫶ /** @var \App\Collaboration\Cart\CartSession $session */
067⫶ $session = $this->getCurrentCartCollaborationSession();
068⫶ if ($session !== null) {
069⫶ try {
070⫶ return $cart->getId() === $session->getCart()->getId();
071⫶ } catch (NotFoundException $e) {
072⫶ }
073⫶ }
074⫶ } finally {
075⫶ $this->nested = false;
076⫶ }
077⫶
078⫶ return false;
079⫶ }
080⫶
081⫶ private function getCurrentCartCollaborationSession(): ?CartSession
082⫶ {
083⫶ $token = $this->requestStack->getSession()->get(self::COLLABORATION_SESSION_ID);
084⫶ if ($token === null) {
085⫶ return null;
086⫶ }
087⫶
088⫶ try {
089⫶ $session = $this->sessionService->getSessionByToken($token);
090⫶ if ($session instanceof CartSession) {
091⫶ return $session;
092⫶ }
093⫶ } catch (NotFoundException|UnauthorizedException) {
094⫶ }
095⫶
096⫶ return null;
097⫶ }
098⫶}


code_samples/collaboration/src/Collaboration/Cart/Persistence/Gateway/DatabaseGateway.php


code_samples/collaboration/src/Collaboration/Cart/Persistence/Gateway/DatabaseGateway.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@76:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@77:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/Persistence/Gateway/DatabaseGateway.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@78:```

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\Collaboration\Cart\Persistence\Gateway;
010⫶
011⫶use App\Collaboration\Cart\Persistence\Values\CartSessionCreateStruct as CreateStruct;
012⫶use App\Collaboration\Cart\Persistence\Values\CartSessionUpdateStruct as UpdateStruct;
013⫶use Doctrine\DBAL\Types\Types;
014⫶use Ibexa\Collaboration\Persistence\Session\Inner\GatewayInterface;
015⫶use Ibexa\Collaboration\Persistence\Values\AbstractSessionCreateStruct;
016⫶use Ibexa\Collaboration\Persistence\Values\AbstractSessionUpdateStruct;
017⫶use Ibexa\Contracts\CorePersistence\Gateway\AbstractDoctrineDatabase;
018⫶use Ibexa\Contracts\CorePersistence\Gateway\DoctrineSchemaMetadata;
019⫶use Ibexa\Contracts\CorePersistence\Gateway\DoctrineSchemaMetadataInterface;
020⫶
021⫶/**
022⫶ * @phpstan-type TRow array{
023⫶ * id: int,
024⫶ * cart_identifier: string
025⫶ * }
026⫶ *
027⫶ * @template-extends \Ibexa\Contracts\CorePersistence\Gateway\AbstractDoctrineDatabase<TRow>
028⫶ *
029⫶ * @template-implements \Ibexa\Collaboration\Persistence\Session\Inner\GatewayInterface<TRow, CreateStruct, UpdateStruct>
030⫶ */
031⫶final class DatabaseGateway extends AbstractDoctrineDatabase implements GatewayInterface
032⫶{
033⫶ public const DISCRIMINATOR = 'cart';
034⫶
035⫶ protected function buildMetadata(): DoctrineSchemaMetadataInterface
036⫶ {
037⫶ return new DoctrineSchemaMetadata(
038⫶ $this->connection,
039⫶ null,
040⫶ $this->getTableName(),
041⫶ [
042⫶ DatabaseSchema::COLUMN_ID => Types::INTEGER,
043⫶ DatabaseSchema::COLUMN_CART_IDENTIFIER => Types::STRING,
044⫶ ],
045⫶ [DatabaseSchema::COLUMN_ID]
046⫶ );
047⫶ }
048⫶
049⫶ protected function getTableName(): string
050⫶ {
051⫶ return DatabaseSchema::TABLE_NAME;
052⫶ }
053⫶
054⫶ public function getDiscriminator(): string
055⫶ {
056⫶ return self::DISCRIMINATOR;
057⫶ }
058⫶
059⫶ /**
060⫶ * @param \App\Collaboration\Cart\Persistence\Values\CartSessionCreateStruct $createStruct
061⫶ */
062⫶ public function create(int $sessionId, AbstractSessionCreateStruct $createStruct): void
063⫶ {
064⫶ $this->doInsert([
065⫶ DatabaseSchema::COLUMN_ID => $sessionId,
066⫶ DatabaseSchema::COLUMN_CART_IDENTIFIER => $createStruct->getCartIdentifier(),
067⫶ ]);
068⫶ }
069⫶
070⫶ /**
071⫶ * @param \Ibexa\Collaboration\Persistence\Values\AbstractSessionUpdateStruct $updateStruct
072⫶ */
073⫶ public function update(AbstractSessionUpdateStruct $updateStruct): void
074⫶ {
075⫶ // There is nothing to update
076⫶ }
077⫶}


code_samples/collaboration/src/Collaboration/Cart/Persistence/Gateway/DatabaseSchema.php


code_samples/collaboration/src/Collaboration/Cart/Persistence/Gateway/DatabaseSchema.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@82:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@83:[[= include_file('code_samples/collaboration/src/Collaboration/Cart/Persistence/Gateway/DatabaseSchema.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@84:```

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\Collaboration\Cart\Persistence\Gateway;
010⫶
011⫶final class DatabaseSchema
012⫶{
013⫶ public const TABLE_NAME = 'ibexa_collaboration_cart';
014⫶
015⫶ public const COLUMN_ID = 'id';
016⫶ public const COLUMN_CART_IDENTIFIER = 'cart_identifier';
017⫶
018⫶ private function __construct()
019⫶ {
020⫶ // This class is not intended to be instantiated
021⫶ }
022⫶}


code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSession.php


code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionCreateStruct.php


code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionUpdateStruct.php


code_samples/collaboration/src/Controller/ShareCartCreateController.php


code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSession.php


code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionCreateStruct.php


code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionUpdateStruct.php


code_samples/collaboration/src/Controller/ShareCartCreateController.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@216:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@217:[[= include_file('code_samples/collaboration/src/Controller/ShareCartCreateController.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@218:```

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\Controller;
010⫶
011⫶use App\Collaboration\Cart\CartSessionCreateStruct;
012⫶use App\Collaboration\Cart\CartSessionType;
013⫶use App\Form\Type\ShareCartType;
014⫶use Ibexa\Contracts\Cart\CartResolverInterface;
015⫶use Ibexa\Contracts\Collaboration\Participant\ExternalParticipantCreateStruct;
016⫶use Ibexa\Contracts\Collaboration\SessionServiceInterface;
017⫶use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
018⫶use Symfony\Component\HttpFoundation\Request;
019⫶use Symfony\Component\HttpFoundation\Response;
020⫶use Symfony\Component\HttpKernel\Attribute\AsController;
021⫶use Symfony\Component\Routing\Annotation\Route;
022⫶
023⫶#[AsController]
024⫶#[Route('/shared-cart/create', name: 'app.shared_cart.create')]
025⫶final class ShareCartCreateController extends AbstractController
026⫶{
027⫶ public function __construct(
028⫶ private SessionServiceInterface $sessionService,
029⫶ private CartResolverInterface $cartResolver
030⫶ ) {
031⫶ }
032⫶
033⫶ public function __invoke(Request $request): Response
034⫶ {
035⫶ $form = $this->createForm(
036⫶ ShareCartType::class,
037⫶ null,
038⫶ [
039⫶ 'method' => 'POST',
040⫶ ]
041⫶ );
042⫶
043⫶ $form->handleRequest($request);
044⫶ if ($form->isSubmitted() && $form->isValid()) {
045⫶ /** @var \App\Form\Data\ShareCartData $data */
046⫶ $data = $form->getData();
047⫶
048⫶ // Handle the form submission
049⫶ $cart = $this->cartResolver->resolveCart();
050⫶
051⫶ $session = $this->sessionService->createSession(
052⫶ new CartSessionCreateStruct($cart)
053⫶ );
054⫶
055⫶ $this->sessionService->addParticipant(
056⫶ $session,
057⫶ new ExternalParticipantCreateStruct(
058⫶ $data->getEmail(),
059⫶ CartSessionType::SCOPE_EDIT
060⫶ )
061⫶ );
062⫶
063⫶ return $this->render(
064⫶ '@ibexadesign/cart/share_result.html.twig',
065⫶ [
066⫶ 'session' => $session,
067⫶ ]
068⫶ );
069⫶ }
070⫶
071⫶ return $this->render(
072⫶ '@ibexadesign/cart/share.html.twig',
073⫶ [
074⫶ 'form' => $form->createView(),
075⫶ ]
076⫶ );
077⫶ }
078⫶}


code_samples/collaboration/src/Controller/ShareCartJoinController.php


code_samples/collaboration/src/Controller/ShareCartJoinController.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@228:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@229:[[= include_file('code_samples/collaboration/src/Controller/ShareCartJoinController.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@230:```

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\Controller;
010⫶
011⫶use App\Collaboration\Cart\CartSession;
012⫶use Ibexa\Contracts\Collaboration\SessionServiceInterface;
013⫶use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
014⫶use Symfony\Component\HttpFoundation\RedirectResponse;
015⫶use Symfony\Component\HttpFoundation\Request;
016⫶use Symfony\Component\HttpKernel\Attribute\AsController;
017⫶use Symfony\Component\Routing\Annotation\Route;
018⫶
019⫶#[AsController]
020⫶#[Route('/shared-cart/join/{token}', name: 'app.shared_cart.join')]
021⫶final class ShareCartJoinController extends AbstractController
022⫶{
023⫶ public const CURRENT_COLLABORATION_SESSION = 'collaboration_session';
024⫶
025⫶ public function __construct(
026⫶ private SessionServiceInterface $sessionService,
027⫶ ) {
028⫶ }
029⫶
030⫶ public function __invoke(Request $request, string $token): RedirectResponse
031⫶ {
032⫶ $session = $this->sessionService->getSessionByToken($token);
033⫶ if ($session instanceof CartSession) {
034⫶ $request->getSession()->set(self::CURRENT_COLLABORATION_SESSION, $session->getToken());
035⫶
036⫶ return $this->redirectToRoute('ibexa.cart.view', [
037⫶ 'identifier' => $session->getCart()->getIdentifier(),
038⫶ ]);
039⫶ }
040⫶
041⫶ throw $this->createAccessDeniedException();
042⫶ }
043⫶}


code_samples/collaboration/src/Form/Data/ShareCartData.php


code_samples/collaboration/src/Form/Data/ShareCartData.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@251:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@252:[[= include_file('code_samples/collaboration/src/Form/Data/ShareCartData.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@253:```

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\Form\Data;
010⫶
011⫶final class ShareCartData
012⫶{
013⫶ public function __construct(
014⫶ private ?string $email = null
015⫶ ) {
016⫶ }
017⫶
018⫶ public function getEmail(): ?string
019⫶ {
020⫶ return $this->email;
021⫶ }
022⫶
023⫶ public function setEmail(?string $email): void
024⫶ {
025⫶ $this->email = $email;
026⫶ }
027⫶}


code_samples/collaboration/src/Form/Type/ShareCartType.php


code_samples/collaboration/src/Form/Type/ShareCartType.php

docs/content_management/collaborative_editing/extend_collaborative_editing.md@245:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@246:[[= include_file('code_samples/collaboration/src/Form/Type/ShareCartType.php') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@247:```

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\Form\Type;
010⫶
011⫶use App\Form\Data\ShareCartData;
012⫶use Symfony\Component\Form\AbstractType;
013⫶use Symfony\Component\Form\Extension\Core\Type\EmailType;
014⫶use Symfony\Component\Form\FormBuilderInterface;
015⫶use Symfony\Component\OptionsResolver\OptionsResolver;
016⫶
017⫶final class ShareCartType extends AbstractType
018⫶{
019⫶ public function buildForm(FormBuilderInterface $builder, array $options): void
020⫶ {
021⫶ $builder->add('email', EmailType::class, [
022⫶ 'label' => 'E-mail',
023⫶ ]);
024⫶ }
025⫶
026⫶ public function configureOptions(OptionsResolver $resolver): void
027⫶ {
028⫶ $resolver->setDefaults([
029⫶ 'data_class' => ShareCartData::class,
030⫶ ]);
031⫶ }
032⫶}


code_samples/collaboration/templates/themes/standard/cart/share.html.twig


code_samples/collaboration/templates/themes/standard/cart/share.html.twig

docs/content_management/collaborative_editing/extend_collaborative_editing.md@262:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@263:[[= include_file('code_samples/collaboration/templates/themes/standard/cart/share.html.twig') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@264:```

001⫶{% extends '@ibexadesign/storefront/layout.html.twig' %}
002⫶
003⫶{% block content %}
004⫶ {{ form_start(form) }}
005⫶ {{ form_widget(form) }}
006⫶ <button class="ibexa-store-btn ibexa-store-btn--primary" type="submit">Share</button>
007⫶ {{ form_end(form) }}
008⫶{% endblock %}


code_samples/collaboration/templates/themes/standard/cart/share_result.html.twig


code_samples/collaboration/templates/themes/standard/cart/share_result.html.twig

docs/content_management/collaborative_editing/extend_collaborative_editing.md@268:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@269:[[= include_file('code_samples/collaboration/templates/themes/standard/cart/share_result.html.twig') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@270:```

001⫶{% extends '@ibexadesign/storefront/layout.html.twig' %}
002⫶
003⫶{% block content %}
004⫶ <p class="ibexa-store-notice-card ibexa-store-notice-card--success">
005⫶ Cart has been shared successfully! Link to session:  
006⫶ <a href="{{ path('app.shared_cart.join', { token: session.getToken() }) }}">
007⫶ {{ url('app.shared_cart.join', { token: session.getToken() }) }}
008⫶ </a>
009⫶ </p>
010⫶{% endblock %}


code_samples/collaboration/templates/themes/standard/cart/view.html.twig


code_samples/collaboration/templates/themes/standard/cart/view.html.twig

docs/content_management/collaborative_editing/extend_collaborative_editing.md@274:``` php
docs/content_management/collaborative_editing/extend_collaborative_editing.md@275:[[= include_file('code_samples/collaboration/templates/themes/standard/cart/view.html.twig') =]]
docs/content_management/collaborative_editing/extend_collaborative_editing.md@276:```

001⫶{% extends '@ibexadesign/storefront/layout.html.twig' %}
002⫶
003⫶{% trans_default_domain 'ibexa_storefront' %}
004⫶
005⫶{% macro render_notice_messages(messages) %}
006⫶ {% for message in messages -%}
007⫶ {{ message }}{{ not loop.last ? '<br/>' }}
008⫶ {%- endfor %}
009⫶{% endmacro %}
010⫶
011⫶{% block content %}
012⫶ <div style="text-align: right">
013⫶ <a href="{{ path('app.shared_cart.create') }}" class="ibexa-store-btn ibexa-store-btn--secondary">Share cart</a>
014⫶ </div>
015⫶
016⫶ {% set quick_order_errors = app.flashes('quick_order_errors') %}
017⫶ {% set quick_order_successes = app.flashes('quick_order_successes') %}
018⫶ {% set cart_products_with_errors_codes = app.flashes('cart_products_with_errors_codes') %}
019⫶
020⫶ {% set reorder_errors = app.flashes('reorder_errors') %}
021⫶ {% set reorder_errors_products_codes = app.flashes('reorder_errors_products_codes') %}
022⫶
023⫶ {% set products_to_highlight_codes = cart_products_with_errors_codes|merge(reorder_errors_products_codes) %}
024⫶
025⫶ {% if quick_order_errors|length %}
026⫶ {% include '@ibexadesign/storefront/component/notice_card/notice_card.html.twig' with {
027⫶ type: 'warning',
028⫶ content: _self.render_notice_messages(quick_order_errors),
029⫶ } %}
030⫶ {% endif %}
031⫶
032⫶ {% if quick_order_successes|length %}
033⫶ {% include '@ibexadesign/storefront/component/notice_card/notice_card.html.twig' with {
034⫶ type: 'success',
035⫶ content: _self.render_notice_messages(quick_order_successes),
036⫶ } %}
037⫶ {% endif %}
038⫶
039⫶ {% if reorder_errors|length %}
040⫶ {% include '@ibexadesign/storefront/component/notice_card/notice_card.html.twig' with {
041⫶ type: 'warning',
042⫶ content: _self.render_notice_messages(reorder_errors),
043⫶ } %}
044⫶ {% endif %}
045⫶
046⫶ {% include '@ibexadesign/cart/component/maincart/maincart.html.twig' with {
047⫶ products_to_highlight_codes,
048⫶ checkout_identifier: app.request.get('checkout_identifier'),
049⫶ checkout_step: app.request.get('checkout_step'),
050⫶ } %}
051⫶{% endblock %}
052⫶
053⫶{% block javascripts %}
054⫶ {{ parent() }}
055⫶
056⫶ {{ encore_entry_script_tags('ibexa-storefront-notice-card-js', null, 'storefront') }}
057⫶{% endblock %}

Download colorized diff

@sonarqubecloud
Copy link

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant