Skip to content

Commit

Permalink
Merge pull request #6022 from magento-obsessive-owls/PWA-805-group
Browse files Browse the repository at this point in the history
[Owls] PWA-805: Expose localization system / store config from GraphQL
  • Loading branch information
davemacaulay authored Aug 18, 2020
2 parents 4930963 + 2d34a2f commit bdde24b
Show file tree
Hide file tree
Showing 16 changed files with 673 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ public function getStoreByWebsiteId($websiteId)
*
* @param int $websiteId
* @param bool $available
* @param int|null $storeGroupId
* @return array
*/
public function getWebsiteStores(int $websiteId, bool $available = false): array
public function getWebsiteStores(int $websiteId, bool $available = false, int $storeGroupId = null): array
{
$connection = $this->resource->getConnection();
$storeTable = $this->resource->getTableName('store');
Expand All @@ -60,6 +61,13 @@ public function getWebsiteStores(int $websiteId, bool $available = false): array
$websiteId
);

if ($storeGroupId) {
$storeSelect = $storeSelect->where(
'group_id = ?',
$storeGroupId
);
}

if ($available) {
$storeSelect = $storeSelect->where(
'is_active = 1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ public function resolve(
array $value = null,
array $args = null
) {
$storeGroupId = !empty($args['useCurrentGroup']) ?
(int)$context->getExtensionAttributes()->getStore()->getStoreGroupId() :
null;
return $this->storeConfigDataProvider->getAvailableStoreConfig(
(int)$context->getExtensionAttributes()->getStore()->getWebsiteId()
(int)$context->getExtensionAttributes()->getStore()->getWebsiteId(),
$storeGroupId
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ public function getStoreConfigData(StoreInterface $store): array
* Get available website stores
*
* @param int $websiteId
* @param int|null $storeGroupId
* @return array
*/
public function getAvailableStoreConfig(int $websiteId): array
public function getAvailableStoreConfig(int $websiteId, int $storeGroupId = null): array
{
$websiteStores = $this->storeWebsiteRelation->getWebsiteStores($websiteId, true);
$websiteStores = $this->storeWebsiteRelation->getWebsiteStores($websiteId, true, $storeGroupId);
$storeCodes = array_column($websiteStores, 'code');

$storeConfigs = $this->storeConfigManager->getStoreConfigs($storeCodes);
Expand Down
83 changes: 83 additions & 0 deletions app/code/Magento/StoreGraphQl/Plugin/LocalizeEmail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\StoreGraphQl\Plugin;

use Magento\Framework\App\AreaInterface;
use Magento\Framework\App\AreaList;
use Magento\Framework\App\State;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Store\Model\App\Emulation;
use Magento\Store\Model\StoreManagerInterface;

/**
* Emulate the correct store when GraphQL is sending an email
*/
class LocalizeEmail
{
/**
* @var StoreManagerInterface
*/
private $storeManager;

/**
* @var Emulation
*/
private $emulation;

/**
* @var AreaList
*/
private $areaList;

/**
* @var State
*/
private $appState;

/**
* @param StoreManagerInterface $storeManager
* @param Emulation $emulation
* @param AreaList $areaList
* @param State $appState
*/
public function __construct(
StoreManagerInterface $storeManager,
Emulation $emulation,
AreaList $areaList,
State $appState
) {
$this->storeManager = $storeManager;
$this->emulation = $emulation;
$this->areaList = $areaList;
$this->appState = $appState;
}

/**
* Emulate the correct store during email preparation
*
* @param TransportBuilder $subject
* @param \Closure $proceed
* @return mixed
* @throws NoSuchEntityException|LocalizedException
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function aroundGetTransport(TransportBuilder $subject, \Closure $proceed)
{
// Load translations for the app
$area = $this->areaList->getArea($this->appState->getAreaCode());
$area->load(AreaInterface::PART_TRANSLATE);

$currentStore = $this->storeManager->getStore();
$this->emulation->startEnvironmentEmulation($currentStore->getId());
$output = $proceed();
$this->emulation->stopEnvironmentEmulation();

return $output;
}
}
10 changes: 10 additions & 0 deletions app/code/Magento/StoreGraphQl/etc/graphql/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,14 @@
</argument>
</arguments>
</type>
<type name="Magento\StoreGraphQl\Model\Resolver\Store\StoreConfigDataProvider">
<arguments>
<argument name="extendedConfigData" xsi:type="array">
<item name="use_store_in_url" xsi:type="string">web/url/use_store</item>
</argument>
</arguments>
</type>
<type name="Magento\Framework\Mail\Template\TransportBuilder">
<plugin name="graphQlEmulateEmail" type="Magento\StoreGraphQl\Plugin\LocalizeEmail" />
</type>
</config>
5 changes: 4 additions & 1 deletion app/code/Magento/StoreGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
# See COPYING.txt for license details.
type Query {
storeConfig : StoreConfig @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\StoreConfigResolver") @doc(description: "The store config query") @cache(cacheable: false)
availableStores: [StoreConfig] @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\AvailableStoresResolver") @doc(description: "Get a list of available store views and their config information.")
availableStores(
useCurrentGroup: Boolean @doc(description: "Filter store views by current store group")
): [StoreConfig] @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\AvailableStoresResolver") @doc(description: "Get a list of available store views and their config information.")
}

type Website @doc(description: "Website is deprecated because it is should not be used on storefront. The type contains information about a website") {
Expand Down Expand Up @@ -32,4 +34,5 @@ type StoreConfig @doc(description: "The type contains information about a store
secure_base_static_url : String @doc(description: "Secure base static URL for the store")
secure_base_media_url : String @doc(description: "Secure base media URL for the store")
store_name : String @doc(description: "Name of the store")
use_store_in_url: Boolean @doc(description: "The configuration determines if the store code should be used in the URL")
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public function testDefaultWebsiteAvailableStoreConfigs(): void
secure_base_static_url,
secure_base_media_url,
store_name
use_store_in_url
}
}
QUERY;
Expand Down Expand Up @@ -126,6 +127,7 @@ public function testNonDefaultWebsiteAvailableStoreConfigs(): void
secure_base_static_url,
secure_base_media_url,
store_name
use_store_in_url
}
}
QUERY;
Expand Down Expand Up @@ -167,5 +169,99 @@ private function validateStoreConfig(StoreConfigInterface $storeConfig, array $r
$this->assertEquals($storeConfig->getSecureBaseStaticUrl(), $responseConfig['secure_base_static_url']);
$this->assertEquals($storeConfig->getSecureBaseMediaUrl(), $responseConfig['secure_base_media_url']);
$this->assertEquals($store->getName(), $responseConfig['store_name']);
$this->assertEquals($store->isUseStoreInUrl(), $responseConfig['use_store_in_url']);
}

/**
* @magentoApiDataFixture Magento/Store/_files/second_website_with_four_stores_divided_in_groups.php
* @magentoConfigFixture web/url/use_store 1
*/
public function testAllStoreConfigsWithCodeInUrlEnabled(): void
{
$storeConfigs = $this->storeConfigManager->getStoreConfigs(
[
'fixture_second_store',
'fixture_third_store',
'fixture_fourth_store',
'fixture_fifth_store'
]
);

$query
= <<<QUERY
{
availableStores(useCurrentGroup:false) {
id,
code,
website_id,
locale,
base_currency_code,
default_display_currency_code,
timezone,
weight_unit,
base_url,
base_link_url,
base_static_url,
base_media_url,
secure_base_url,
secure_base_link_url,
secure_base_static_url,
secure_base_media_url,
store_name
use_store_in_url
}
}
QUERY;
$headerMap = ['Store' => 'fixture_fifth_store'];
$response = $this->graphQlQuery($query, [], '', $headerMap);

$this->assertArrayHasKey('availableStores', $response);
$this->assertCount(4, $response['availableStores']);
foreach ($response['availableStores'] as $key => $responseConfig) {
$this->validateStoreConfig($storeConfigs[$key], $responseConfig);
$this->assertEquals(true, $responseConfig['use_store_in_url']);
}
}

/**
* @magentoApiDataFixture Magento/Store/_files/second_website_with_four_stores_divided_in_groups.php
*/
public function testCurrentGroupStoreConfigs(): void
{
$storeConfigs = $this->storeConfigManager->getStoreConfigs(['fixture_fourth_store', 'fixture_fifth_store']);

$query
= <<<QUERY
{
availableStores(useCurrentGroup:true) {
id,
code,
website_id,
locale,
base_currency_code,
default_display_currency_code,
timezone,
weight_unit,
base_url,
base_link_url,
base_static_url,
base_media_url,
secure_base_url,
secure_base_link_url,
secure_base_static_url,
secure_base_media_url,
store_name
use_store_in_url
}
}
QUERY;
$headerMap = ['Store' => 'fixture_fifth_store'];
$response = $this->graphQlQuery($query, [], '', $headerMap);

$this->assertArrayHasKey('availableStores', $response);
$this->assertCount(2, $response['availableStores']);
foreach ($response['availableStores'] as $key => $responseConfig) {
$this->validateStoreConfig($storeConfigs[$key], $responseConfig);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ protected function _assignConfigData(TestCase $test)
self::ANNOTATION
);
foreach ($testAnnotations as $configPathAndValue) {
if (preg_match('/^.+?(?=_store\s)/', $configPathAndValue, $matches)) {
if (preg_match('/^[^\/]+?(?=_store\s)/', $configPathAndValue, $matches)) {
$this->setStoreConfigValue($matches ?? [], $configPathAndValue);
} elseif (preg_match('/^.+?(?=_website\s)/', $configPathAndValue, $matches)) {
} elseif (preg_match('/^[^\/]+?(?=_website\s)/', $configPathAndValue, $matches)) {
$this->setWebsiteConfigValue($matches ?? [], $configPathAndValue);
} else {
$this->setGlobalConfigValue($configPathAndValue);
Expand Down
Loading

0 comments on commit bdde24b

Please sign in to comment.