diff --git a/code_samples/collaboration/config/services.yaml b/code_samples/collaboration/config/services.yaml new file mode 100644 index 0000000000..c6d81568ae --- /dev/null +++ b/code_samples/collaboration/config/services.yaml @@ -0,0 +1,48 @@ +# This file is the entry point to configure your own services. +# Files in the packages/ subdirectory configure your dependencies. + +# Put parameters here that don't need to change on each machine where the app is deployed +# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration +parameters: + +services: + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + + # makes classes in src/ available to be used as services + # this creates a service per class whose id is the fully-qualified class name + App\: + resource: '../src/' + + # add more service definitions when explicit configuration is needed + # please note that last definitions always *replace* previous ones + + App\Collaboration\Cart\Persistence\Gateway\DatabaseGateway: + arguments: + $connection: '@ibexa.persistence.connection' + tags: + - name: 'ibexa.collaboration.persistence.session.gateway' + discriminator: !php/const App\Collaboration\Cart\Persistence\Gateway\DatabaseGateway::DISCRIMINATOR + + App\Collaboration\Cart\Persistence\Mapper: + tags: + - name: 'ibexa.collaboration.persistence.session.mapper' + discriminator: !php/const App\Collaboration\Cart\Persistence\Gateway\DatabaseGateway::DISCRIMINATOR + + App\Collaboration\Cart\Mapper\CartSessionDomainMapper: + tags: + - name: 'ibexa.collaboration.service.session.domain.mapper' + type: App\Collaboration\Cart\Persistence\Values\CartSession + + App\Collaboration\Cart\Mapper\CartSessionPersistenceMapper: + tags: + - name: 'ibexa.collaboration.service.session.persistence.mapper' + type: !php/const App\Collaboration\Cart\CartSessionType::IDENTIFIER + + App\Collaboration\Cart\PermissionResolverDecorator: + decorates: Ibexa\Contracts\ProductCatalog\PermissionResolverInterface + + App\Collaboration\Cart\CartResolverDecorator: + decorates: Ibexa\Contracts\Cart\CartResolverInterface diff --git a/code_samples/collaboration/ibexa_collaboration_cart.mysql.sql b/code_samples/collaboration/ibexa_collaboration_cart.mysql.sql new file mode 100644 index 0000000000..74b94b6a62 --- /dev/null +++ b/code_samples/collaboration/ibexa_collaboration_cart.mysql.sql @@ -0,0 +1,7 @@ +CREATE TABLE ibexa_collaboration_cart ( + id INT NOT NULL PRIMARY KEY, + cart_identifier VARCHAR(255) NOT NULL, + CONSTRAINT ibexa_collaboration_cart_ibexa_collaboration_id_fk + FOREIGN KEY (id) REFERENCES ibexa_collaboration (id) + ON DELETE CASCADE +) COLLATE = utf8mb4_general_ci; diff --git a/code_samples/collaboration/ibexa_collaboration_cart.postgresql.sql b/code_samples/collaboration/ibexa_collaboration_cart.postgresql.sql new file mode 100644 index 0000000000..a073132fca --- /dev/null +++ b/code_samples/collaboration/ibexa_collaboration_cart.postgresql.sql @@ -0,0 +1,7 @@ +CREATE TABLE ibexa_collaboration_cart ( + id INTEGER NOT NULL PRIMARY KEY, + cart_identifier VARCHAR(255) NOT NULL, + CONSTRAINT ibexa_collaboration_cart_ibexa_collaboration_id_fk + FOREIGN KEY (id) REFERENCES ibexa_collaboration (id) + ON DELETE CASCADE +); diff --git a/code_samples/collaboration/src/Collaboration/Cart/CartResolverDecorator.php b/code_samples/collaboration/src/Collaboration/Cart/CartResolverDecorator.php index 4d879c5dfc..9bf359e4a9 100644 --- a/code_samples/collaboration/src/Collaboration/Cart/CartResolverDecorator.php +++ b/code_samples/collaboration/src/Collaboration/Cart/CartResolverDecorator.php @@ -1,10 +1,4 @@ -getCart(); - } catch (NotFoundException|\Ibexa\ProductCatalog\Exception\UnauthorizedException $e) { + } catch (NotFoundException|\Ibexa\ProductCatalog\Exception\UnauthorizedException) { return null; } } diff --git a/code_samples/collaboration/src/Collaboration/Cart/CartSession.php b/code_samples/collaboration/src/Collaboration/Cart/CartSession.php index eb3cb41aaf..dcacef4130 100644 --- a/code_samples/collaboration/src/Collaboration/Cart/CartSession.php +++ b/code_samples/collaboration/src/Collaboration/Cart/CartSession.php @@ -1,10 +1,4 @@ -cart = $cart; } public function getCart(): CartInterface diff --git a/code_samples/collaboration/src/Collaboration/Cart/CartSessionCreateStruct.php b/code_samples/collaboration/src/Collaboration/Cart/CartSessionCreateStruct.php index 4a51d8ca85..9594b61cd7 100644 --- a/code_samples/collaboration/src/Collaboration/Cart/CartSessionCreateStruct.php +++ b/code_samples/collaboration/src/Collaboration/Cart/CartSessionCreateStruct.php @@ -1,10 +1,4 @@ -cart = $cart; } public function getCart(): CartInterface diff --git a/code_samples/collaboration/src/Collaboration/Cart/CartSessionType.php b/code_samples/collaboration/src/Collaboration/Cart/CartSessionType.php index e19c86207e..93c9ab3023 100644 --- a/code_samples/collaboration/src/Collaboration/Cart/CartSessionType.php +++ b/code_samples/collaboration/src/Collaboration/Cart/CartSessionType.php @@ -1,10 +1,4 @@ - */ -final class CartSessionDomainMapper implements SessionDomainMapperInterface +final readonly class CartSessionDomainMapper implements SessionDomainMapperInterface { public function __construct( private CartProxyMapperInterface $cartProxyMapper, diff --git a/code_samples/collaboration/src/Collaboration/Cart/Mapper/CartSessionPersistenceMapper.php b/code_samples/collaboration/src/Collaboration/Cart/Mapper/CartSessionPersistenceMapper.php index ed29967aab..380ecf6b06 100644 --- a/code_samples/collaboration/src/Collaboration/Cart/Mapper/CartSessionPersistenceMapper.php +++ b/code_samples/collaboration/src/Collaboration/Cart/Mapper/CartSessionPersistenceMapper.php @@ -1,10 +1,4 @@ -getId() === $session->getCart()->getId(); - } catch (NotFoundException $e) { + } catch (NotFoundException) { } } } finally { diff --git a/code_samples/collaboration/src/Collaboration/Cart/Persistence/Gateway/DatabaseGateway.php b/code_samples/collaboration/src/Collaboration/Cart/Persistence/Gateway/DatabaseGateway.php index 7bbfc271d5..8ecca9a74b 100644 --- a/code_samples/collaboration/src/Collaboration/Cart/Persistence/Gateway/DatabaseGateway.php +++ b/code_samples/collaboration/src/Collaboration/Cart/Persistence/Gateway/DatabaseGateway.php @@ -1,10 +1,4 @@ - + */ +final class Mapper implements MapperInterface +{ + public function extractFromRow(array $row): AbstractSession + { + return new CartSession( + $row['id'], + $row['cart_cart_identifier'], + $row['token'], + $row['owner_id'], + $row['is_active'], + $row['has_public_link'], + $row['created_at'], + $row['updated_at'] + ); + } +} diff --git a/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSession.php b/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSession.php index a2c81c3121..dd58482adf 100644 --- a/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSession.php +++ b/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSession.php @@ -1,10 +1,4 @@ -cartIdentifier = $cartIdentifier; } public function getCartIdentifier(): string diff --git a/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionCreateStruct.php b/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionCreateStruct.php index 23f4c4c6f7..875dc6a87a 100644 --- a/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionCreateStruct.php +++ b/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionCreateStruct.php @@ -1,10 +1,4 @@ -cartIdentifier = $cartIdentifier; } public function getCartIdentifier(): string diff --git a/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionUpdateStruct.php b/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionUpdateStruct.php index 88474c4a8c..471a5f7fbd 100644 --- a/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionUpdateStruct.php +++ b/code_samples/collaboration/src/Collaboration/Cart/Persistence/Values/CartSessionUpdateStruct.php @@ -1,10 +1,4 @@ -add('email', EmailType::class, [ 'label' => 'E-mail', + ])->add('submit', SubmitType::class, [ + 'label' => 'Share', ]); } diff --git a/code_samples/collaboration/src/Query/Search.php b/code_samples/collaboration/src/Query/Search.php index 71cea24df5..b4f7dfbabc 100644 --- a/code_samples/collaboration/src/Query/Search.php +++ b/code_samples/collaboration/src/Query/Search.php @@ -1,5 +1,4 @@ -Share - {{ form_end(form) }} -{% endblock %} diff --git a/code_samples/collaboration/templates/themes/standard/cart/view.html.twig b/code_samples/collaboration/templates/themes/standard/cart/view.html.twig deleted file mode 100644 index e7900e130e..0000000000 --- a/code_samples/collaboration/templates/themes/standard/cart/view.html.twig +++ /dev/null @@ -1,57 +0,0 @@ -{% extends '@ibexadesign/storefront/layout.html.twig' %} - -{% trans_default_domain 'ibexa_storefront' %} - -{% macro render_notice_messages(messages) %} - {% for message in messages -%} - {{ message }}{{ not loop.last ? '
' }} - {%- endfor %} -{% endmacro %} - -{% block content %} -
- Share cart -
- - {% set quick_order_errors = app.flashes('quick_order_errors') %} - {% set quick_order_successes = app.flashes('quick_order_successes') %} - {% set cart_products_with_errors_codes = app.flashes('cart_products_with_errors_codes') %} - - {% set reorder_errors = app.flashes('reorder_errors') %} - {% set reorder_errors_products_codes = app.flashes('reorder_errors_products_codes') %} - - {% set products_to_highlight_codes = cart_products_with_errors_codes|merge(reorder_errors_products_codes) %} - - {% if quick_order_errors|length %} - {% include '@ibexadesign/storefront/component/notice_card/notice_card.html.twig' with { - type: 'warning', - content: _self.render_notice_messages(quick_order_errors), - } %} - {% endif %} - - {% if quick_order_successes|length %} - {% include '@ibexadesign/storefront/component/notice_card/notice_card.html.twig' with { - type: 'success', - content: _self.render_notice_messages(quick_order_successes), - } %} - {% endif %} - - {% if reorder_errors|length %} - {% include '@ibexadesign/storefront/component/notice_card/notice_card.html.twig' with { - type: 'warning', - content: _self.render_notice_messages(reorder_errors), - } %} - {% endif %} - - {% include '@ibexadesign/cart/component/maincart/maincart.html.twig' with { - products_to_highlight_codes, - checkout_identifier: app.request.get('checkout_identifier'), - checkout_step: app.request.get('checkout_step'), - } %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {{ encore_entry_script_tags('ibexa-storefront-notice-card-js', null, 'storefront') }} -{% endblock %} diff --git a/code_samples/collaboration/templates/themes/storefront/cart/share.html.twig b/code_samples/collaboration/templates/themes/storefront/cart/share.html.twig new file mode 100644 index 0000000000..f4ba2e2913 --- /dev/null +++ b/code_samples/collaboration/templates/themes/storefront/cart/share.html.twig @@ -0,0 +1,9 @@ +{% extends '@ibexadesign/storefront/layout.html.twig' %} + +{% block content %} + {{ form_start(form) }} + {{ form_label(form.email, null, { 'label_attr': { 'class': 'ibexa-store-label' }}) }} + {{ form_widget(form.email, { 'attr': { 'class': 'ibexa-store-input' } }) }} + {{ form_widget(form.submit, { 'attr': { 'class': 'ibexa-store-btn ibexa-store-btn--primary' } }) }} + {{ form_end(form) }} +{% endblock %} diff --git a/code_samples/collaboration/templates/themes/standard/cart/share_result.html.twig b/code_samples/collaboration/templates/themes/storefront/cart/share_result.html.twig similarity index 83% rename from code_samples/collaboration/templates/themes/standard/cart/share_result.html.twig rename to code_samples/collaboration/templates/themes/storefront/cart/share_result.html.twig index b9b24bda31..a830a4d768 100644 --- a/code_samples/collaboration/templates/themes/standard/cart/share_result.html.twig +++ b/code_samples/collaboration/templates/themes/storefront/cart/share_result.html.twig @@ -2,7 +2,7 @@ {% block content %}

- Cart has been shared successfully! Link to session:   + Cart has been shared successfully! Link to session:  {{ url('app.shared_cart.join', { token: session.getToken() }) }} diff --git a/code_samples/collaboration/templates/themes/storefront/cart/view.html.twig b/code_samples/collaboration/templates/themes/storefront/cart/view.html.twig new file mode 100644 index 0000000000..922e21be24 --- /dev/null +++ b/code_samples/collaboration/templates/themes/storefront/cart/view.html.twig @@ -0,0 +1,8 @@ +{% extends '@IbexaStorefront/themes/storefront/cart/view.html.twig' %} + +{% block content %} +

+ Share cart +
+ {{ parent() }} +{% endblock %} diff --git a/docs/content_management/collaborative_editing/extend_collaborative_editing.md b/docs/content_management/collaborative_editing/extend_collaborative_editing.md index 4aea75b0e5..4abb2fbbf2 100644 --- a/docs/content_management/collaborative_editing/extend_collaborative_editing.md +++ b/docs/content_management/collaborative_editing/extend_collaborative_editing.md @@ -25,26 +25,13 @@ In this example, it represents the shopping Cart (identified by the Cart identif === "MySQL" ``` sql - CREATE TABLE ibexa_collaboration_cart - ( - id INT NOT NULL PRIMARY KEY, - cart_identifier VARCHAR(255) NOT NULL, - CONSTRAINT ibexa_collaboration_cart_ibexa_collaboration_id_fk - FOREIGN KEY (id) REFERENCES ibexa_collaboration (id) - ON DELETE CASCADE - ) COLLATE = utf8mb4_general_ci; + [[= include_file('code_samples/collaboration/ibexa_collaboration_cart.mysql.sql', 0, None, ' ') =]] ``` === "PostgreSQL" ``` sql - CREATE TABLE ibexa_collaboration_cart ( - id INTEGER NOT NULL PRIMARY KEY, - cart_identifier VARCHAR(255) NOT NULL, - CONSTRAINT ibexa_collaboration_cart_ibexa_collaboration_id_fk - FOREIGN KEY (id) REFERENCES ibexa_collaboration (id) - ON DELETE CASCADE - ); + [[= include_file('code_samples/collaboration/ibexa_collaboration_cart.postgresql.sql', 0, None, ' ') =]] ``` ## Set up the persistence layer @@ -255,22 +242,22 @@ The form collects the email address of the user that you want to invite, and the The last step is to integrate the new session type into your application by adding templates. In this step, the view is rendered. -You need to add following templates in the `templates/themes/standard/cart` folder: +You need to add following templates in the `templates/themes/storefront/cart` folder: - `share` - this Twig template defines the view for the Cart sharing form. It renders the form where a user can enter an email address to invite someone to collaborate on the Cart. ``` php -[[= include_file('code_samples/collaboration/templates/themes/standard/cart/share.html.twig') =]] +[[= include_file('code_samples/collaboration/templates/themes/storefront/cart/share.html.twig') =]] ``` - `share_result` - this Twig template renders the result page after a Cart has been shared. If the shared Cart exists in the system, the created session object is passed to the view and displayed. A message like "Cart has been shared…" is displayed, along with a link to access the session. ``` php -[[= include_file('code_samples/collaboration/templates/themes/standard/cart/share_result.html.twig') =]] +[[= include_file('code_samples/collaboration/templates/themes/storefront/cart/share_result.html.twig') =]] ``` - `view` - is the template that shows the Cart page. It displays the Cart content and includes the “Share Cart” button and other elements for Cart collaboration. ``` php -[[= include_file('code_samples/collaboration/templates/themes/standard/cart/view.html.twig') =]] +[[= include_file('code_samples/collaboration/templates/themes/storefront/cart/view.html.twig') =]] ``` diff --git a/docs/search/collaboration_search_reference/collaboration_criteria.md b/docs/search/collaboration_search_reference/collaboration_criteria.md index b5b909674a..8ef1bed45a 100644 --- a/docs/search/collaboration_search_reference/collaboration_criteria.md +++ b/docs/search/collaboration_search_reference/collaboration_criteria.md @@ -50,7 +50,7 @@ Session Search Criteria are implementing the [CriterionInterface](/api/php_api/p The following example shows how you can use the criteria to find all the currently active sessions: -```php hl_lines="12-16" +```php hl_lines="11-15" [[= include_file('code_samples/collaboration/src/Query/Search.php') =]] ``` diff --git a/docs/search/collaboration_search_reference/collaboration_sort_clauses.md b/docs/search/collaboration_search_reference/collaboration_sort_clauses.md index be985fb453..33b943f937 100644 --- a/docs/search/collaboration_search_reference/collaboration_sort_clauses.md +++ b/docs/search/collaboration_search_reference/collaboration_sort_clauses.md @@ -33,7 +33,7 @@ Session Search Sort Clauses are implementing the [SortClauseInterface](/api/php_ The following example shows how to use them to sort the searched sessions: -```php hl_lines="18" +```php hl_lines="17" [[= include_file('code_samples/collaboration/src/Query/Search.php') =]] ```