Skip to content

Commit

Permalink
Merge pull request #8806 from magento-lynx/gl-graphql-api-enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
svera authored Mar 15, 2024
2 parents a225939 + 86e4968 commit 3e685e0
Show file tree
Hide file tree
Showing 29 changed files with 923 additions and 18 deletions.
81 changes: 81 additions & 0 deletions app/code/Magento/CustomerGraphQl/Model/Resolver/ConfirmEmail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php
/**
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained from
* Adobe.
*/
declare(strict_types=1);

namespace Magento\CustomerGraphQl\Model\Resolver;

use Magento\Customer\Api\AccountManagementInterface;
use Magento\CustomerGraphQl\Model\Customer\ExtractCustomerData;
use Magento\Framework\Exception\State\InputMismatchException;
use Magento\Framework\Exception\State\InvalidTransitionException;
use Magento\Framework\Exception\StateException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\Validator\EmailAddress as EmailValidator;

/**
* Customer email confirmation, used for GraphQL request processing
*/
class ConfirmEmail implements ResolverInterface
{
/**
* @param AccountManagementInterface $accountManagement
* @param EmailValidator $emailValidator
* @param ExtractCustomerData $extractCustomerData
*/
public function __construct(
private readonly AccountManagementInterface $accountManagement,
private readonly EmailValidator $emailValidator,
private readonly ExtractCustomerData $extractCustomerData
) {
}

/**
* Confirm customer email mutation
*
* @param \Magento\Framework\GraphQl\Config\Element\Field $field
* @param \Magento\Framework\GraphQl\Query\Resolver\ContextInterface $context
* @param ResolveInfo $info
* @param array|null $value
* @param array|null $args
* @return array|Value
* @throws \Exception
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
if (!$this->emailValidator->isValid($args['input']['email'])) {
throw new GraphQlInputException(__('Email is invalid'));
}
try {
$customer = $this->accountManagement->activate($args['input']['email'], $args['input']['confirmation_key']);
} catch (InvalidTransitionException | InputMismatchException $e) {
throw new GraphQlInputException(__($e->getRawMessage()));
} catch (StateException) {
throw new GraphQlInputException(__('This confirmation key is invalid or has expired.'));
} catch (\Exception) {
throw new GraphQlInputException(__('There was an error confirming the account'));
}
return ['customer' => $this->extractCustomerData->execute($customer)];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/************************************************************************
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
* ************************************************************************
*/
declare(strict_types=1);

namespace Magento\CustomerGraphQl\Model\Resolver;

use Magento\Customer\Api\AccountManagementInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
* Confirmation status resolver
*/
class ConfirmationStatus implements ResolverInterface
{
/**
* @param AccountManagementInterface $accountManagement
*/
public function __construct(
private readonly AccountManagementInterface $accountManagement
) {
}

/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
try {
$confirmationStatus = $this->accountManagement->getConfirmationStatus($context->getUserId());
} catch (LocalizedException $e) {
throw new GraphQlInputException(__($e->getMessage()), $e);
}
return strtoupper($confirmationStatus);
}
}
1 change: 1 addition & 0 deletions app/code/Magento/CustomerGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<item name="required_character_classes_number" xsi:type="string">customer/password/required_character_classes_number</item>
<item name="minimum_password_length" xsi:type="string">customer/password/minimum_password_length</item>
<item name="autocomplete_on_storefront" xsi:type="string">customer/password/autocomplete_on_storefront</item>
<item name="create_account_confirmation" xsi:type="string">customer/create_account/confirm</item>
</argument>
</arguments>
</type>
Expand Down
13 changes: 13 additions & 0 deletions app/code/Magento/CustomerGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type StoreConfig {
required_character_classes_number : String @doc(description: "The number of different character classes (lowercase, uppercase, digits, special characters) required in a password.")
minimum_password_length : String @doc(description: "The minimum number of characters required for a valid password.")
autocomplete_on_storefront : Boolean @doc(description: "Indicates whether to enable autocomplete on login and forgot password forms.")
create_account_confirmation: Boolean @doc(description: "Indicates if the new accounts need confirmation.")
}

type Query {
Expand All @@ -29,6 +30,12 @@ type Mutation {
requestPasswordResetEmail(email: String! @doc(description: "The customer's email address.")): Boolean @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\RequestPasswordResetEmail") @doc(description: "Request an email with a reset password token for the registered customer identified by the specified email.")
resetPassword(email: String! @doc(description: "The customer's email address."), resetPasswordToken: String! @doc(description: "A runtime token generated by the `requestPasswordResetEmail` mutation."), newPassword: String! @doc(description: "The customer's new password.")): Boolean @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ResetPassword") @doc(description: "Reset a customer's password using the reset password token that the customer received in an email after requesting it using `requestPasswordResetEmail`.")
updateCustomerEmail(email: String! @doc(description: "The customer's email address."), password: String! @doc(description: "The customer's password.")): CustomerOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\UpdateCustomerEmail") @doc(description: "Change the email address for the logged-in customer.")
confirmEmail(input: ConfirmEmailInput! @doc(description: "An input object to identify the customer to confirm the email.")): CustomerOutput @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\ConfirmEmail") @doc(description: "Confirms the email address for a customer.")
}

input ConfirmEmailInput @doc(description: "Contains details about a customer email address to confirm.") {
email: String! @doc(description: "The email address to be confirmed.")
confirmation_key: String! @doc(description: "The key to confirm the email address.")
}

input CustomerAddressInput @doc(description: "Contains details about a billing or shipping address."){
Expand Down Expand Up @@ -140,6 +147,7 @@ type Customer @doc(description: "Defines the customer name, addresses, and other
addresses: [CustomerAddress] @doc(description: "An array containing the customer's shipping and billing addresses.") @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\CustomerAddresses")
gender: Int @doc(description: "The customer's gender (Male - 1, Female - 2).")
custom_attributes(attributeCodes: [ID!]): [AttributeValueInterface] @doc(description: "Customer's custom attributes.") @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\CustomAttributeFilter")
confirmation_status: ConfirmationStatusEnum! @doc(description: "The customer's confirmation status.") @resolver(class: "Magento\\CustomerGraphQl\\Model\\Resolver\\ConfirmationStatus")
}

type CustomerAddress @doc(description: "Contains detailed information about a customer's billing or shipping address."){
Expand Down Expand Up @@ -467,3 +475,8 @@ enum ValidationRuleEnum @doc(description: "List of validation rule names applied
MAX_IMAGE_HEIGHT
MAX_IMAGE_WIDTH
}

enum ConfirmationStatusEnum @doc(description: "List of account confirmation statuses.") {
ACCOUNT_CONFIRMED @doc(description: "Account confirmed")
ACCOUNT_CONFIRMATION_NOT_REQUIRED @doc(description: "Account confirmation not required")
}
22 changes: 22 additions & 0 deletions app/code/Magento/IntegrationGraphQl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Magento_IntegrationGraphQl module

This module provides GraphQl resolvers for Integartion module.

## Installation

Before installing this module, note that the Magento_IntegrationGraphQl is dependent on the following modules:

- `Magento_GraphQl`
- `Magento_Integration`

For information about a module installation in Magento 2, see [Enable or disable modules](https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/tutorials/manage-modules.html).

## Extensibility

Extension developers can interact with the Magento_IntegrationGraphQl module. For more information about the Magento extension mechanism, see [Magento plugins](https://developer.adobe.com/commerce/php/development/components/plugins/).

[The Magento dependency injection mechanism](https://developer.adobe.com/commerce/php/development/components/dependency-injection/) enables you to override the functionality of the Magento_IntegrationGraphQl module.

## Additional information

You can get more information about [GraphQl In Magento 2](https://developer.adobe.com/commerce/webapi/graphql/).
21 changes: 21 additions & 0 deletions app/code/Magento/IntegrationGraphQl/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "magento/module-integration-graph-ql",
"description": "N/A",
"type": "magento2-module",
"require": {
"php": "~8.1.0||~8.2.0||~8.3.0",
"magento/framework": "*"
},
"license": [
"OSL-3.0",
"AFL-3.0"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Magento\\IntegrationGraphQl\\": ""
}
}
}
27 changes: 27 additions & 0 deletions app/code/Magento/IntegrationGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0"?>
<!--
/************************************************************************
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
* ************************************************************************
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\StoreGraphQl\Model\Resolver\Store\StoreConfigDataProvider">
<arguments>
<argument name="extendedConfigData" xsi:type="array">
<item name="customer_access_token_lifetime" xsi:type="string">oauth/access_token_lifetime/customer</item>
</argument>
</arguments>
</type>
</config>
22 changes: 22 additions & 0 deletions app/code/Magento/IntegrationGraphQl/etc/module.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0"?>
<!--
/************************************************************************
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
* ************************************************************************
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Magento_IntegrationGraphQl" >
</module>
</config>
18 changes: 18 additions & 0 deletions app/code/Magento/IntegrationGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ADOBE CONFIDENTIAL
# ___________________
#
# Copyright 2024 Adobe
# All Rights Reserved.
#
# NOTICE: All information contained herein is, and remains
# the property of Adobe and its suppliers, if any. The intellectual
# and technical concepts contained herein are proprietary to Adobe
# and its suppliers and are protected by all applicable intellectual
# property laws, including trade secret and copyright laws.
# Dissemination of this information or reproduction of this material
# is strictly forbidden unless prior written permission is obtained
# from Adobe.

type StoreConfig {
customer_access_token_lifetime: Float @doc(description: "Customer access token lifetime.")
}
19 changes: 19 additions & 0 deletions app/code/Magento/IntegrationGraphQl/registration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
/**
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained from
* Adobe.
*/
declare(strict_types=1);

use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_IntegrationGraphQl', __DIR__);
4 changes: 4 additions & 0 deletions app/code/Magento/QuoteGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
<item name="is_guest_checkout_enabled" xsi:type="string">checkout/options/guest_checkout</item>
<item name="is_one_page_checkout_enabled" xsi:type="string">checkout/options/onepage_checkout_enabled</item>
<item name="max_items_in_order_summary" xsi:type="string">checkout/options/max_items_display_count</item>
<item name="cart_summary_display_quantity" xsi:type="string">checkout/cart_link/use_qty</item>
<item name="minicart_display" xsi:type="string">checkout/sidebar/display</item>
<item name="minicart_max_items" xsi:type="string">checkout/sidebar/max_items_display_count</item>
<item name="cart_expires_in_days" xsi:type="string">checkout/cart/delete_quote_after</item>
</argument>
</arguments>
</type>
Expand Down
6 changes: 5 additions & 1 deletion app/code/Magento/QuoteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ type ApplyCouponToCartOutput @doc(description: "Contains details about the cart

type PlaceOrderOutput @doc(description: "Contains the results of the request to place an order.") {
order: Order @deprecated(reason: "Use `orderV2` instead.") @doc(description: "The ID of the order.")
orderV2: CustomerOrder! @doc(description: "Full order information.")
orderV2: CustomerOrder @doc(description: "Full order information.")
errors: [PlaceOrderError!]! @doc(description:"An array of place order errors.")
}

Expand Down Expand Up @@ -511,6 +511,10 @@ type StoreConfig {
is_guest_checkout_enabled: Boolean @doc(description: "Extended Config Data - checkout/options/guest_checkout")
is_one_page_checkout_enabled: Boolean @doc(description: "Extended Config Data - checkout/options/onepage_checkout_enabled")
max_items_in_order_summary: Int @doc(description: "Extended Config Data - checkout/options/max_items_display_count")
cart_summary_display_quantity: Int @doc(description: "Extended Config Data - checkout/cart_link/use_qty")
minicart_display: Boolean @doc(description: "Extended Config Data - checkout/sidebar/display")
minicart_max_items: Int @doc(description: "Extended Config Data - checkout/sidebar/count")
cart_expires_in_days: Int @doc(description: "Extended Config Data - checkout/cart/delete_quote_after")
}

input EstimateTotalsInput {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
<element name="couponCode" type="input" selector="#order-coupons input" timeout="30"/>
<element name="applyCoupon" type="button" selector="#order-coupons button"/>
<element name="removeCoupon" type="button" selector=".added-coupon-code .action-remove"/>
<element name="removeSpecificCoupon" type="button" selector=".added-coupon-code.coupon-code-{{couponCode}} .action-remove" parameterized="true"/>
<element name="couponCodeApplied" type="text" selector=".added-coupon-code.coupon-code-{{couponCode}} span" parameterized="true"/>
<element name="totalRecords" type="text" selector="#sales_order_create_search_grid-total-count"/>
<element name="numberOfPages" type="text" selector="div.admin__data-grid-pager-wrap div.admin__data-grid-pager > label"/>
<element name="productName" type="button" selector="(.//*[@class='col-product'])[2]/span"/>
Expand Down
17 changes: 3 additions & 14 deletions app/code/Magento/SalesGraphQl/Model/Formatter/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,14 @@
*/
class Order
{
/**
* @var OrderAddress
*/
private $orderAddress;

/**
* @var OrderPayments
*/
private $orderPayments;

/**
* @param OrderAddress $orderAddress
* @param OrderPayments $orderPayments
*/
public function __construct(
OrderAddress $orderAddress,
OrderPayments $orderPayments
private readonly OrderAddress $orderAddress,
private readonly OrderPayments $orderPayments
) {
$this->orderAddress = $orderAddress;
$this->orderPayments = $orderPayments;
}

/**
Expand All @@ -57,6 +45,7 @@ public function format(OrderInterface $orderModel): array
'order_date' => $orderModel->getCreatedAt(),
'order_number' => $orderModel->getIncrementId(),
'status' => $orderModel->getStatusLabel(),
'email' => $orderModel->getCustomerEmail(),
'shipping_method' => $orderModel->getShippingDescription(),
'shipping_address' => $this->orderAddress->getOrderShippingAddress($orderModel),
'billing_address' => $this->orderAddress->getOrderBillingAddress($orderModel),
Expand Down
Loading

0 comments on commit 3e685e0

Please sign in to comment.