Skip to content

Commit 19aaa98

Browse files
authored
Merge pull request #119 from JerrySmidt/master
3.7.0
2 parents ebce170 + 0249e01 commit 19aaa98

44 files changed

Lines changed: 1240 additions & 379 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.gitattributes export-ignore
22
.gitignore export-ignore
3+
.github/ export-ignore

Block/System/Config/Status.php

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ public function __construct(
6969
$this->_dataHelper = $dataHelper;
7070
$this->_updateNotifier = $updateNotifier;
7171

72-
$this->_cachedData = $this->_getCachedData();
73-
74-
$this->_notifyUpdate();
75-
7672
parent::__construct($context, $data);
7773
}
7874

@@ -85,6 +81,9 @@ public function __construct(
8581
*/
8682
public function render(AbstractElement $element): string
8783
{
84+
$this->_cachedData = $this->_getCachedData();
85+
$this->_notifyUpdate();
86+
8887
/** @noinspection PhpUndefinedMethodInspection */
8988
$this->setElement($element);
9089

@@ -101,7 +100,7 @@ public function getConfig(): array
101100
return [
102101
'enabled' => $this->_storeConfigHelper->isEnabled(),
103102
'module_version' => $this->_storeConfigHelper->getModuleVersion(),
104-
'supported_countries' => $this->_storeConfigHelper->getSupportedCountries(),
103+
'supported_countries' => $this->_storeConfigHelper->getSupportedCountryNames(),
105104
'account_name' => $this->_storeConfigHelper->getValue('account_name'),
106105
'account_status' => $this->_storeConfigHelper->getValue('account_status'), // Defaults to "new", see etc/config.xml.
107106
'has_credentials' => $this->_storeConfigHelper->hasCredentials(),
@@ -138,19 +137,52 @@ public function getApiStatusDescription(): string
138137
$status = $this->_storeConfigHelper->getValue('account_status');
139138

140139
switch ($status) {
141-
case \Flekto\Postcode\Helper\ApiClientHelper::API_ACCOUNT_STATUS_NEW:
142-
return __('not connected');
143-
case \Flekto\Postcode\Helper\ApiClientHelper::API_ACCOUNT_STATUS_ACTIVE:
140+
case ApiClientHelper::API_ACCOUNT_STATUS_NEW:
141+
return __('new');
142+
case ApiClientHelper::API_ACCOUNT_STATUS_ACTIVE:
144143
return __('active');
145-
case \Flekto\Postcode\Helper\ApiClientHelper::API_ACCOUNT_STATUS_INVALID_CREDENTIALS:
144+
case ApiClientHelper::API_ACCOUNT_STATUS_INVALID_CREDENTIALS:
146145
return __('invalid key and/or secret');
147-
case \Flekto\Postcode\Helper\ApiClientHelper::API_ACCOUNT_STATUS_INACTIVE:
146+
case ApiClientHelper::API_ACCOUNT_STATUS_INACTIVE:
148147
return __('inactive');
149148
default:
150149
throw new Status\Exception(__('Invalid account status value.'));
151150
}
152151
}
153152

153+
/**
154+
* Get hint about API status.
155+
*
156+
* @return string
157+
*/
158+
public function getApiStatusHint(): string
159+
{
160+
$status = $this->_storeConfigHelper->getValue('account_status');
161+
162+
switch ($status) {
163+
case ApiClientHelper::API_ACCOUNT_STATUS_NEW:
164+
return __('Enter your Postcode.eu API key and secret to connect.');
165+
case ApiClientHelper::API_ACCOUNT_STATUS_ACTIVE:
166+
return __('The Postcode.eu API is successfully connected.');
167+
case ApiClientHelper::API_ACCOUNT_STATUS_INVALID_CREDENTIALS:
168+
return __('The API key or secret is incorrect. Please check your credentials.');
169+
case ApiClientHelper::API_ACCOUNT_STATUS_INACTIVE:
170+
return __('Your Postcode.eu subscription is inactive. Please log in to your account to resolve this.');
171+
default:
172+
throw new Status\Exception(__('Invalid account status value.'));
173+
}
174+
}
175+
176+
/**
177+
* Check if API status is active.
178+
*
179+
* @return bool
180+
*/
181+
public function isStatusActive(): bool
182+
{
183+
return $this->_storeConfigHelper->getValue('account_status') === ApiClientHelper::API_ACCOUNT_STATUS_ACTIVE;
184+
}
185+
154186
/**
155187
* Get cached data.
156188
*
@@ -180,7 +212,7 @@ private function _getCachedData(): array
180212
private function _getAccountInfo(): array
181213
{
182214
$status = $this->_storeConfigHelper->getValue('account_status');
183-
if ($status === \Flekto\Postcode\Helper\ApiClientHelper::API_ACCOUNT_STATUS_ACTIVE) {
215+
if ($status === ApiClientHelper::API_ACCOUNT_STATUS_ACTIVE) {
184216
return $this->_apiClientHelper->getAccountInfo();
185217
}
186218

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
<?php
2+
3+
namespace Flekto\Postcode\Data\Form\Element;
4+
5+
use Magento\Framework\Data\Form\Element\AbstractElement;
6+
use Magento\Framework\Data\Form\Element\CollectionFactory;
7+
use Magento\Framework\Data\Form\Element\Factory;
8+
use Magento\Framework\Escaper;
9+
use Magento\Framework\View\LayoutInterface;
10+
11+
/**
12+
* Add custom element for address autocomplete controls
13+
*/
14+
class AddressAutofill extends AbstractElement
15+
{
16+
/** @var LayoutInterface */
17+
protected $_layout;
18+
19+
/**
20+
* @param Factory $factoryElement
21+
* @param CollectionFactory $factoryCollection
22+
* @param Escaper $escaper
23+
* @param LayoutInterface $layout
24+
* @param array $data
25+
*/
26+
public function __construct(
27+
Factory $factoryElement,
28+
CollectionFactory $factoryCollection,
29+
Escaper $escaper,
30+
LayoutInterface $layout,
31+
$data = []
32+
) {
33+
parent::__construct($factoryElement, $factoryCollection, $escaper, $data);
34+
$this->setType('postcode-eu-address-autofill');
35+
$this->_layout = $layout;
36+
}
37+
38+
/**
39+
* Get element HTML
40+
*
41+
* @return string
42+
*/
43+
public function getElementHtml(): string
44+
{
45+
$block = $this->_layout->createBlock(
46+
\Magento\Backend\Block\Template::class,
47+
$this->getId(),
48+
[
49+
'data' => [
50+
'template' => 'Flekto_Postcode::form/element/address-autofill.phtml',
51+
'jsLayout' => $this->getJsLayout(),
52+
],
53+
],
54+
);
55+
56+
return $block->toHtml();
57+
}
58+
59+
/**
60+
* Get JS layout
61+
*
62+
* @return array
63+
*/
64+
public function getJsLayout(): array
65+
{
66+
return [
67+
'components' => [
68+
$this->getId() => [
69+
'component' => 'Flekto_Postcode/js/view/address/autofill',
70+
'config' => [
71+
'settings' => $this->getData('settings'),
72+
'htmlIdPrefix' => $this->getData('htmlIdPrefix'),
73+
'addressType' => $this->getData('addressType'),
74+
'countryCode' => $this->getData('countryCode'),
75+
'visible' => $this->getData('visible'),
76+
],
77+
'children' => [
78+
'address_autofill_nl' => [
79+
'component' => 'Flekto_Postcode/js/view/form/sales/order_create/address-autofill-nl',
80+
'config' => [
81+
'componentDisabled' => $this->getData('isNlComponentDisabled'),
82+
],
83+
'children' => [
84+
'postcode' => [
85+
'component' => 'Magento_Ui/js/form/element/abstract',
86+
'label' => __('Zip/Postal Code'),
87+
'config' => [
88+
'template' => 'ui/form/field',
89+
'elementTmpl' => 'Flekto_Postcode/form/element/address-autofill-field',
90+
'placeholder' => '1234 AB',
91+
'imports' => [
92+
'visible' => '${ $.parentName }:visible',
93+
],
94+
],
95+
],
96+
'house_number' => [
97+
'component' => 'Magento_Ui/js/form/element/abstract',
98+
'label' => __('House number and addition'),
99+
'additionalClasses' => [
100+
'address-autofill-nl-house-number' => true,
101+
],
102+
'config' => [
103+
'template' => 'ui/form/field',
104+
'elementTmpl' => 'Flekto_Postcode/form/element/address-autofill-field',
105+
'imports' => [
106+
'visible' => '${ $.parentName }:visible',
107+
],
108+
],
109+
],
110+
'house_number_select' => [
111+
'component' => 'Magento_Ui/js/form/element/select',
112+
'label' => __('Which house number do you mean?'),
113+
'config' => [
114+
'caption' => __('- Select house number -'),
115+
'template' => 'ui/form/field',
116+
'visible' => false,
117+
],
118+
],
119+
],
120+
],
121+
'address_autofill_intl' => [
122+
'component' => 'Flekto_Postcode/js/view/form/sales/order_create/address-autofill-intl',
123+
'label' => __('Find an address'),
124+
'placeholder' => __('City, street or postcode')
125+
],
126+
'address_autofill_error' => [
127+
'component' => 'Magento_Ui/js/form/components/html',
128+
'config' => [
129+
'visible' => false,
130+
'listens' => [
131+
'${$.parentName}:error' => 'content',
132+
'content' => 'visible',
133+
],
134+
'additionalClasses' => [
135+
'admin__field-note' => true,
136+
'address-autofill-warning' => true,
137+
],
138+
],
139+
],
140+
],
141+
],
142+
],
143+
];
144+
}
145+
}

HTTP/Client/Curl.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,9 @@
77
*/
88
class Curl extends \Magento\Framework\HTTP\Client\Curl
99
{
10+
/**
11+
* Request timeout
12+
* @var int type
13+
*/
14+
protected $_timeout = 30;
1015
}

Helper/Data.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
use Magento\Framework\Exception\LocalizedException;
1111
use Magento\Framework\Filesystem\DirectoryList;
1212
use Magento\Framework\Filesystem\DriverInterface;
13-
use Magento\Framework\HTTP\Client\Curl;
13+
use Flekto\Postcode\HTTP\Client\Curl;
14+
use Flekto\Postcode\Service\Exception\CurlException;
1415

1516
class Data extends AbstractHelper
1617
{
@@ -166,7 +167,12 @@ private function _getPackageData(): array
166167
}
167168
}
168169

169-
$this->_curl->get(self::PACKAGIST_URL);
170+
try {
171+
$this->_curl->get(self::PACKAGIST_URL);
172+
} catch (CurlException $e) {
173+
throw new LocalizedException(__('Failed to fetch package data: %1', $e->getMessage()));
174+
}
175+
170176
$status = $this->_curl->getStatus();
171177
if ($status == 200) {
172178
$response = $this->_curl->getBody();
@@ -175,7 +181,12 @@ private function _getPackageData(): array
175181
throw new LocalizedException(__('Failed to write package data to %1.', $filePath));
176182
}
177183

178-
return json_decode($response, true);
184+
$result = json_decode($response, true);
185+
if (json_last_error() !== JSON_ERROR_NONE) {
186+
throw new LocalizedException(__('Invalid JSON response from Packagist.'));
187+
}
188+
189+
return $result;
179190

180191
} elseif ($status == 304) { // Not modified, use cached file.
181192
$data = $this->_fs->fileGetContents($filePath);
@@ -184,7 +195,12 @@ private function _getPackageData(): array
184195
throw new LocalizedException(__('Failed to read package data from %1.', $filePath));
185196
}
186197

187-
return json_decode($data, true);
198+
$result = json_decode($data, true);
199+
if (json_last_error() !== JSON_ERROR_NONE) {
200+
throw new LocalizedException(__('Invalid cached JSON data.'));
201+
}
202+
203+
return $result;
188204
}
189205

190206
throw new LocalizedException(__('Unexpected status code %1 while fetching package data.', $status));

Helper/StoreConfigHelper.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
use Magento\Store\Model\StoreManagerInterface;
99
use Magento\Developer\Helper\Data as DeveloperHelperData;
1010
use Magento\Framework\Encryption\EncryptorInterface;
11+
use Magento\Directory\Model\ResourceModel\Country\CollectionFactory as CountryCollectionFactory;
12+
use Magento\Framework\Locale\ResolverInterface;
1113
use Flekto\Postcode\Model\Config\Source\NlInputBehavior;
1214
use Flekto\Postcode\Model\Config\Source\ShowHideAddressFields;
1315

@@ -16,6 +18,8 @@ class StoreConfigHelper extends AbstractHelper
1618
protected $_storeManager;
1719
protected $_developerHelper;
1820
protected $_encryptor;
21+
protected $_countryCollectionFactory;
22+
protected $_localeResolver;
1923

2024
public const PATH = [
2125
// Status
@@ -38,23 +42,30 @@ class StoreConfigHelper extends AbstractHelper
3842
'disabled_countries' => 'postcodenl_api/advanced_config/disabled_countries',
3943
'allow_pobox_shipping' => 'postcodenl_api/advanced_config/allow_pobox_shipping',
4044
'split_street_values' => 'postcodenl_api/advanced_config/split_street_values',
45+
'admin_address_autocomplete_behavior' => 'postcodenl_api/advanced_config/admin_address_autocomplete_behavior',
4146
];
4247

4348
/**
4449
* @param Context $context
4550
* @param StoreManagerInterface $storeManager
46-
* @param Data $developerHelper
51+
* @param DeveloperHelperData $developerHelper
4752
* @param EncryptorInterface $encryptor
53+
* @param CountryCollectionFactory $countryCollectionFactory
54+
* @param ResolverInterface $localeResolver
4855
*/
4956
public function __construct(
5057
Context $context,
5158
StoreManagerInterface $storeManager,
5259
DeveloperHelperData $developerHelper,
53-
EncryptorInterface $encryptor
60+
EncryptorInterface $encryptor,
61+
CountryCollectionFactory $countryCollectionFactory,
62+
ResolverInterface $localeResolver
5463
) {
5564
$this->_storeManager = $storeManager;
5665
$this->_developerHelper = $developerHelper;
5766
$this->_encryptor = $encryptor;
67+
$this->_countryCollectionFactory = $countryCollectionFactory;
68+
$this->_localeResolver = $localeResolver;
5869
parent::__construct($context);
5970
}
6071

@@ -122,6 +133,22 @@ public function getEnabledCountries(): array
122133
return array_values(array_diff($supported, explode(',', $disabled)));
123134
}
124135

136+
/**
137+
* Get supported country names.
138+
*
139+
* @return array
140+
*/
141+
public function getSupportedCountryNames(): array
142+
{
143+
$isoCodes = array_map(fn($country) => $country->iso2, $this->getSupportedCountries());
144+
$collection = $this->_countryCollectionFactory->create()->addFieldToFilter('country_id', ['in' => $isoCodes]);
145+
$locale = $this->_localeResolver->getLocale();
146+
$names = array_map(fn($country) => $country->getName(), $collection->getItems());
147+
\Collator::create($locale)->asort($names);
148+
149+
return $names;
150+
}
151+
125152
/**
126153
* Check if API credentials are set.
127154
*

0 commit comments

Comments
 (0)