diff --git a/Api/Data/UpdateNotificationInterface.php b/Api/Data/UpdateNotificationInterface.php new file mode 100644 index 0000000..02e1f6c --- /dev/null +++ b/Api/Data/UpdateNotificationInterface.php @@ -0,0 +1,34 @@ +_scopeConfig = $context->getScopeConfig(); $this->_storeConfigHelper = $storeConfigHelper; + $this->_apiClientHelper = $apiClientHelper; $this->_resourceConfig = $resourceConfig; + $this->_cacheTypeList = $cacheTypeList; + $this->_cacheFrontendPool = $cacheFrontendPool; + $this->_serializer = $serializer; + $this->_dataHelper = $dataHelper; + $this->_updateNotifier = $updateNotifier; + + $this->_cachedData = $this->_getCachedData(); + + $this->_notifyUpdate(); + parent::__construct($context, $data); } @@ -57,8 +99,8 @@ public function render(AbstractElement $element): string public function getConfig(): array { return [ - 'enabled' => $this->_storeConfigHelper->isSetFlag(StoreConfigHelper::PATH['enabled']), - 'module_version' => $this->_storeConfigHelper->getValue(StoreConfigHelper::PATH['module_version']), + 'enabled' => $this->_storeConfigHelper->isEnabled(), + 'module_version' => $this->_storeConfigHelper->getModuleVersion(), 'supported_countries' => $this->_storeConfigHelper->getSupportedCountries(), 'account_name' => $this->_storeConfigHelper->getValue(StoreConfigHelper::PATH['account_name']), 'account_status' => $this->_storeConfigHelper->getValue(StoreConfigHelper::PATH['account_status']), // Defaults to "new", see etc/config.xml. @@ -66,6 +108,26 @@ public function getConfig(): array ]; } + /** + * Get cached account info. + * + * @return array + */ + public function getAccountInfo(): array + { + return $this->_cachedData['accountInfo'] ?? []; + } + + /** + * Get cached module info. + * + * @return array + */ + public function getModuleInfo(): array + { + return $this->_cachedData['moduleInfo'] ?? []; + } + /** * Get short description of API status. * @@ -88,4 +150,51 @@ public function getApiStatusDescription(): string throw new Status\Exception(__('Invalid account status value.')); } } + + /** + * Get cached data. + * + * @return array + */ + private function _getCachedData(): array + { + $cache = $this->_cacheFrontendPool->get(\Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER); + $cachedData = $cache->load(self::CACHE_ID); + + if ($cachedData === false) { + $data = []; + $data['accountInfo'] = $this->_getAccountInfo(); + $data['moduleInfo'] = $this->_dataHelper->getModuleInfo(); + $cache->save($this->_serializer->serialize($data), self::CACHE_ID, [], self::CACHE_LIFETIME_SECONDS); + return $data; + } + + return $this->_serializer->unserialize($cachedData); + } + + /** + * Get Postcode.eu API account info. + * + * @return array + */ + private function _getAccountInfo(): array + { + $status = $this->_storeConfigHelper->getValue(StoreConfigHelper::PATH['account_status']); + if ($status === \Flekto\Postcode\Helper\ApiClientHelper::API_ACCOUNT_STATUS_ACTIVE) { + return $this->_apiClientHelper->getApiClient()->accountInfo(); + } + + return []; + } + + /** + * Set a notification if an update is available. + */ + private function _notifyUpdate(): void + { + $moduleInfo = $this->getModuleInfo(); + if ($moduleInfo['has_update'] ?? false) { + $this->_updateNotifier->notifyVersion($moduleInfo['latest_version']); + } + } } diff --git a/Cron/NotifyModuleUpdate.php b/Cron/NotifyModuleUpdate.php new file mode 100644 index 0000000..3f67fb8 --- /dev/null +++ b/Cron/NotifyModuleUpdate.php @@ -0,0 +1,49 @@ +_logger = $logger; + $this->_dataHelper = $dataHelper; + $this->_updateNotifier = $updateNotifier; + } + + /** + * Run cron job. + * + * @access public + * @return void + */ + public function execute(): void + { + $moduleInfo = $this->_dataHelper->getModuleInfo(); + if (($moduleInfo['has_update'] ?? false) + && $this->_updateNotifier->notifyVersion($moduleInfo['latest_version']) + ) { + $this->_logger->info(__('Added notification for Postcode.eu Address API %1 update.', $moduleInfo['latest_version'])); + } + } +} diff --git a/Cron/UpdateApiData.php b/Cron/UpdateApiData.php index 0630177..fd87282 100644 --- a/Cron/UpdateApiData.php +++ b/Cron/UpdateApiData.php @@ -15,7 +15,7 @@ class UpdateApiData protected $_storeConfigHelper; /** - * __construct function. + * Constructor * * @access public * @param LoggerInterface $logger diff --git a/Helper/ApiClientHelper.php b/Helper/ApiClientHelper.php index 0d88e22..61a9cdf 100644 --- a/Helper/ApiClientHelper.php +++ b/Helper/ApiClientHelper.php @@ -11,11 +11,11 @@ use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Locale\Resolver as LocaleResolver; use Magento\Framework\Module\ModuleListInterface; -use Magento\Framework\Stdlib\DateTime; use Magento\Framework\Webapi\Rest\Request; use Magento\Framework\Webapi\Rest\Response; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\UrlInterface; class ApiClientHelper extends AbstractHelper { @@ -30,6 +30,7 @@ class ApiClientHelper extends AbstractHelper protected $_request; protected $_response; protected $_storeManager; + protected $_urlBuilder; protected $_client; protected $_localeResolver; protected $_countryCodeMap = []; @@ -56,6 +57,7 @@ public function __construct( Request $request, Response $response, StoreManagerInterface $storeManager, + UrlInterface $urlBuilder, LocaleResolver $localeResolver, StoreConfigHelper $storeConfigHelper ) { @@ -64,6 +66,7 @@ public function __construct( $this->_request = $request; $this->_response = $response; $this->_storeManager = $storeManager; + $this->_urlBuilder = $urlBuilder; $this->_localeResolver = $localeResolver; $this->_storeConfigHelper = $storeConfigHelper; parent::__construct($context); @@ -96,7 +99,7 @@ public function getJsinit(): array 'enabled_countries' => $this->_storeConfigHelper->getEnabledCountries(), 'nl_input_behavior' => $this->_storeConfigHelper->getValue(StoreConfigHelper::PATH['nl_input_behavior']) ?? \Flekto\Postcode\Model\Config\Source\NlInputBehavior::ZIP_HOUSE, 'show_hide_address_fields' => $this->_storeConfigHelper->getValue(StoreConfigHelper::PATH['show_hide_address_fields']) ?? \Flekto\Postcode\Model\Config\Source\ShowHideAddressFields::SHOW, - 'base_url' => $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB), + 'base_url' => $this->getCurrentStoreBaseUrl(), 'debug' => $this->isDebugging(), 'fixedCountry' => $this->_getFixedCountry(), 'change_fields_position' => $this->_storeConfigHelper->isSetFlag(StoreConfigHelper::PATH['change_fields_position']), @@ -119,8 +122,7 @@ public function getAddressAutocomplete(string $context, string $term): array $context = strtolower($this->getCountryIso3Code($context) ?? $context); } - // API requires format 'nl-NL' - $locale = str_replace('_', '-', $this->_localeResolver->getLocale()); + $language = explode('_', $this->_localeResolver->getLocale())[0]; try { @@ -131,7 +133,7 @@ public function getAddressAutocomplete(string $context, string $term): array $sessionStr = $this->_generateSessionString(); } - $response = $client->internationalAutocomplete($context, $term, $sessionStr, $locale); + $response = $client->internationalAutocomplete($context, $term, $sessionStr, $language); return $this->_prepareResponse($response, $client); @@ -177,6 +179,7 @@ public function getAddressDetails(string $context): array public function getNlAddress(string $zipCode, string $houseNumber): array { $address = null; + $matches = []; preg_match('/^(\d{1,5})(\D.*)?$/i', $houseNumber, $matches); $houseNumber = isset($matches[1]) ? (int)$matches[1] : null; @@ -250,6 +253,7 @@ private function _generateSessionString(): string */ private function _handleClientException(\Exception $exception): array { + $response = []; $response['error'] = true; // only in this case we actually pass error @@ -294,8 +298,7 @@ private function _prepareResponse(array $apiResult, PostcodeApiClient $client): preg_match("#max-age=(.*?)$#sim", $clientResponseHeaders['cache-control'][0], $secondsToLive); if (!empty($secondsToLive) && isset($secondsToLive[1])) { $secondsToLive = $secondsToLive[1]; - $dateTime = new DateTime(); - $this->_response->setHeader('expires', $dateTime->gmDate('D, d M Y H:i:s T', $dateTime->strToTime('+ '.$secondsToLive.' seconds')), true); + $this->_response->setHeader('expires', gmdate('D, d M Y H:i:s T', strtotime('+ '.$secondsToLive.' seconds')), true); } } @@ -355,6 +358,12 @@ public function isDebugging(): bool return $this->_storeConfigHelper->isSetFlag(StoreConfigHelper::PATH['api_debug'], ScopeInterface::SCOPE_STORE) && $this->_developerHelper->isDevAllowed(); } + public function getCurrentStoreBaseUrl(): string + { + $currentStore = $this->_storeManager->getStore(); + return $this->_urlBuilder->getBaseUrl(['_store' => $currentStore->getCode()]); + } + /** * Get API key. * @@ -460,7 +469,7 @@ private function _getDebugInfo(): array // Magento version $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); - $productMetadata = $objectManager->get(Magento\Framework\App\ProductMetadataInterface::class); + $productMetadata = $objectManager->get(ProductMetadataInterface::class); $version = $productMetadata->getVersion(); $debug['magentoVersion'] = 'Magento/' . $version; diff --git a/Helper/Data.php b/Helper/Data.php index 933c56a..abcd63f 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -7,27 +7,58 @@ use Flekto\Postcode\Model\Config\Source\ShowHideAddressFields; use Magento\Framework\App\Helper\AbstractHelper; use Magento\Framework\App\Helper\Context; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Filesystem\DirectoryList; +use Magento\Framework\Filesystem\DriverInterface; +use Magento\Framework\HTTP\Client\Curl; class Data extends AbstractHelper { + public const MODULE_RELEASE_URL = 'https://github.com/postcode-nl/PostcodeNl_Api_Magento2/releases/latest'; + public const PACKAGIST_URL = 'https://repo.packagist.org/p2/postcode-nl/api-magento2-module.json'; + /** * @var StoreConfigHelper */ private $_storeConfigHelper; + /** + * @var DirectoryList + */ + private $_dir; + + /** + * @var DriverInterface + */ + private $_fs; + + /** + * @var Curl + */ + private $_curl; + /** * Constructor * * @access public * @param Context $context * @param StoreConfigHelper $storeConfigHelper + * @param DirectoryList $dir + * @param DriverInterface $filesystem + * @param Curl $curl * @return void */ public function __construct( Context $context, - StoreConfigHelper $storeConfigHelper + StoreConfigHelper $storeConfigHelper, + DirectoryList $dir, + DriverInterface $filesystem, + Curl $curl, ) { $this->_storeConfigHelper = $storeConfigHelper; + $this->_dir = $dir; + $this->_fs = $filesystem; + $this->_curl = $curl; parent::__construct($context); } @@ -37,7 +68,7 @@ public function __construct( * @access public * @return bool */ - public function isFormattedOutputDisabled() + public function isFormattedOutputDisabled(): bool { return $this->isDisabled() @@ -50,7 +81,7 @@ public function isFormattedOutputDisabled() * @access public * @return bool */ - public function isNlComponentDisabled() + public function isNlComponentDisabled(): bool { return $this->isDisabled() @@ -64,7 +95,7 @@ public function isNlComponentDisabled() * @access public * @return bool */ - public function isDisabled() + public function isDisabled(): bool { return false === $this->_storeConfigHelper->isSetFlag(StoreConfigHelper::PATH['enabled']) @@ -77,11 +108,94 @@ public function isDisabled() * @access public * @return bool */ - public function isAutofillBypassDisabled() + public function isAutofillBypassDisabled(): bool { return $this->isDisabled() || ShowHideAddressFields::SHOW == $this->_storeConfigHelper->getValue(StoreConfigHelper::PATH['show_hide_address_fields']) || $this->_storeConfigHelper->isSetFlag(StoreConfigHelper::PATH['allow_autofill_bypass']) === false; } + + /** + * Get module info. + * + * @return array + */ + public function getModuleInfo(): array + { + $version = $this->_storeConfigHelper->getModuleVersion(); + + try { + $data = $this->_getPackageData(); + $latest_version = $data['packages']['postcode-nl/api-magento2-module'][0]['version']; + } catch (LocalizedException $e) { + $this->_logger->error(__('Failed to get package data: "%1".', $e->getMessage())); + $latest_version = $version; + } + + return [ + 'version' => $version, + 'latest_version' => $latest_version, + 'has_update' => version_compare($latest_version, $version, '>'), + 'release_url' => $this->getModuleReleaseUrl(), + ]; + } + + /** + * Request module info from Packagist. + * + * Will only download from Packagist if their file is newer. + * + * @throws LocalizedException + * @return array - Decoded JSON data. + */ + private function _getPackageData(): array + { + $path = $this->_dir->getPath('var') . '/Flekto_Postcode'; + if (!$this->_fs->isDirectory($path)) { + $this->_fs->createDirectory($path, 0755); + } + + $filePath = $path . '/package-data.json'; + if ($this->_fs->isExists($filePath)) { + $lastModified = $this->_fs->stat($filePath)['mtime']; + + if ($lastModified !== false) { + $this->_curl->setHeaders(['If-Modified-Since' => gmdate('D, d M Y H:i:s T', $lastModified)]); + } + } + + $this->_curl->get(self::PACKAGIST_URL); + $status = $this->_curl->getStatus(); + if ($status == 200) { + $response = $this->_curl->getBody(); + + if ($this->_fs->filePutContents($filePath, $response) === false) { + throw new LocalizedException(__('Failed to write package data to %1.', $filePath)); + } + + return json_decode($response, true); + + } elseif ($status == 304) { // Not modified, use cached file. + $data = $this->_fs->fileGetContents($filePath); + + if ($data === false) { + throw new LocalizedException(__('Failed to read package data from %1.', $filePath)); + } + + return json_decode($data, true); + } + + throw new LocalizedException(__('Unexpected status code %1 while fetching package data.', $status)); + } + + /** + * Get URL to the latest version of the module. + * + * @return string + */ + public function getModuleReleaseUrl(): string + { + return self::MODULE_RELEASE_URL; + } } diff --git a/Helper/StoreConfigHelper.php b/Helper/StoreConfigHelper.php index 8c92fd2..93e65e0 100644 --- a/Helper/StoreConfigHelper.php +++ b/Helper/StoreConfigHelper.php @@ -105,4 +105,15 @@ public function hasCredentials(): bool return isset($key, $secret); } + + /** + * Get current module version. + * + * @access public + * @return string + */ + public function getModuleVersion(): string + { + return $this->getValue(static::PATH['module_version']); + } } diff --git a/Model/ResourceModel/UpdateNotification.php b/Model/ResourceModel/UpdateNotification.php new file mode 100644 index 0000000..542e35c --- /dev/null +++ b/Model/ResourceModel/UpdateNotification.php @@ -0,0 +1,16 @@ +_init(self::MAIN_TABLE, self::ID_FIELD); + } +} diff --git a/Model/ResourceModel/UpdateNotification/Collection.php b/Model/ResourceModel/UpdateNotification/Collection.php new file mode 100644 index 0000000..39a136a --- /dev/null +++ b/Model/ResourceModel/UpdateNotification/Collection.php @@ -0,0 +1,18 @@ +_init( + UpdateNotification::class, + UpdateNotificationResourceModel::class + ); + } +} diff --git a/Model/System/Message/LicenceCheck.php b/Model/System/Message/LicenceCheck.php index f8de416..a39801d 100644 --- a/Model/System/Message/LicenceCheck.php +++ b/Model/System/Message/LicenceCheck.php @@ -38,9 +38,9 @@ public function __construct(StoreConfigHelper $storeConfigHelper, UrlInterface $ * Retrieve unique message identity. * * @access public - * @return void + * @return string */ - public function getIdentity() + public function getIdentity(): string { return self::MESSAGE_IDENTITY; } @@ -51,7 +51,7 @@ public function getIdentity() * @access public * @return bool */ - public function isDisplayed() + public function isDisplayed(): bool { return $this->_storeConfigHelper->getValue(StoreConfigHelper::PATH['account_status']) != \Flekto\Postcode\Helper\ApiClientHelper::API_ACCOUNT_STATUS_ACTIVE; } @@ -60,9 +60,9 @@ public function isDisplayed() * Retrieve message text. * * @access public - * @return void + * @return string */ - public function getText() + public function getText(): string { $msg = __('Your Postcode.eu API licence is invalid.'); $msg .= ' ' . __('Check your API credentials.') . ''; @@ -74,9 +74,9 @@ public function getText() * Retrieve message severity. * * @access public - * @return void + * @return int */ - public function getSeverity() + public function getSeverity(): int { return self::SEVERITY_MAJOR; } diff --git a/Model/UpdateNotification.php b/Model/UpdateNotification.php new file mode 100644 index 0000000..b2d8ce4 --- /dev/null +++ b/Model/UpdateNotification.php @@ -0,0 +1,34 @@ +_init(ResourceModel\UpdateNotification::class); + } + + public function getVersion(): string + { + return $this->getData(self::VERSION); + } + + public function setVersion(string $version): UpdateNotification + { + return $this->setData(self::VERSION, $version); + } + + public function getNotified(): bool + { + return $this->getData(self::NOTIFIED); + } + + public function setNotified(bool $notified): UpdateNotification + { + return $this->setData(self::NOTIFIED, $notified); + } +} diff --git a/Model/UpdateNotification/UpdateNotifier.php b/Model/UpdateNotification/UpdateNotifier.php new file mode 100644 index 0000000..ac95c33 --- /dev/null +++ b/Model/UpdateNotification/UpdateNotifier.php @@ -0,0 +1,52 @@ +_notifier = $notifier; + $this->_updateNotification = $updateNotification; + } + + /** + * Notifies about a new version. + * + * @param string $version + * @return bool - True if notified about a new version, false otherwise. + */ + public function notifyVersion(string $version): bool + { + if ($this->_updateNotification->isVersionNotified($version)) { + return false; + } + + $this->_notifier->addNotice( + __('Postcode.eu Address API update available'), + __('Stay ahead with our latest update. + Get the newest features and improvements for our Postcode.eu address validation module.'), + \Flekto\Postcode\Helper\Data::MODULE_RELEASE_URL + ); + $this->_updateNotification->setVersionNotified($version); + return $this->_updateNotification->isVersionNotified($version); + } +} diff --git a/Model/UpdateNotificationRepository.php b/Model/UpdateNotificationRepository.php new file mode 100644 index 0000000..e7b5174 --- /dev/null +++ b/Model/UpdateNotificationRepository.php @@ -0,0 +1,71 @@ +_resource = $resource; + $this->_notificationFactory = $notificationFactory; + } + + public function getByVersion(string $version): UpdateNotificationInterface + { + $notification = $this->_notificationFactory->create(); + $this->_resource->load($notification, $version, 'version'); + + if (!$notification->getId()) { + throw new NoSuchEntityException(__('Version "%1" not found', $version)); + } + + return $notification; + } + + public function save(UpdateNotificationInterface $notification): UpdateNotificationInterface + { + try { + $this->_resource->save($notification); + } catch (\Exception $e) { + throw new CouldNotSaveException(__($e->getMessage())); + } + + return $notification; + } + + public function setVersionNotified(string $version): void + { + try { + $notification = $this->getByVersion($version); + } catch (NoSuchEntityException $e) { + $notification = $this->_notificationFactory->create(); + } + + $notification->setVersion($version); + $notification->setNotified(true); + $this->_resource->save($notification); + } + + public function isVersionNotified(string $version): bool + { + try { + $notification = $this->getByVersion($version); + return $notification->getNotified(); + } catch (NoSuchEntityException $e) { + return false; + } + } +} diff --git a/Observer/System/Config.php b/Observer/System/Config.php index 57e5e5d..8bfb0b7 100644 --- a/Observer/System/Config.php +++ b/Observer/System/Config.php @@ -5,6 +5,7 @@ use Flekto\Postcode\Helper\ApiClientHelper; use Flekto\Postcode\Helper\StoreConfigHelper; use Magento\Framework\App\Cache\TypeListInterface; +use Magento\Framework\App\Cache\Frontend\Pool as CacheFrontendPool; use Magento\Framework\App\Config\Storage\WriterInterface; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; @@ -17,6 +18,7 @@ class Config implements ObserverInterface protected $_logger; protected $_apiClientHelper; protected $_cacheTypeList; + protected $_cacheFrontendPool; protected $_storeConfigHelper; protected $_request; @@ -27,14 +29,17 @@ class Config implements ObserverInterface * @param WriterInterface $configWriter * @param LoggerInterface $logger * @param TypeListInterface $cacheTypeList + * @param CacheFrontendPool $cacheFrontendPool * @param ApiClientHelper $apiClientHelper * @param StoreConfigHelper $storeConfigHelper + * @param RequestInterface $request * @return void */ public function __construct( WriterInterface $configWriter, LoggerInterface $logger, TypeListInterface $cacheTypeList, + CacheFrontendPool $cacheFrontendPool, ApiClientHelper $apiClientHelper, StoreConfigHelper $storeConfigHelper, RequestInterface $request @@ -42,6 +47,7 @@ public function __construct( $this->_configWriter = $configWriter; $this->_logger = $logger; $this->_cacheTypeList = $cacheTypeList; + $this->_cacheFrontendPool = $cacheFrontendPool; $this->_apiClientHelper = $apiClientHelper; $this->_storeConfigHelper = $storeConfigHelper; $this->_request = $request; @@ -51,7 +57,7 @@ public function __construct( * @param Observer $observer * @return void */ - public function execute(Observer $observer) + public function execute(Observer $observer): void { if (empty($this->_request->getParam('refresh_api_data'))) { @@ -65,7 +71,7 @@ public function execute(Observer $observer) $this->_configWriter->delete(StoreConfigHelper::PATH['account_name']); $this->_configWriter->delete(StoreConfigHelper::PATH['account_status']); - $this->_cleanConfigCache(); + $this->_purgeCachedData(); return; } @@ -113,15 +119,28 @@ public function execute(Observer $observer) } } - $this->_cleanConfigCache(); // Clean cache to update status block. + $this->_purgeCachedData(); // Clean cache to update status block. } /** * Clean config cache. + * * @return void */ - protected function _cleanConfigCache() + protected function _cleanConfigCache(): void { $this->_cacheTypeList->cleanType(\Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER); } + + /** + * Purge cached data. + * + * @return void + */ + private function _purgeCachedData(): void + { + $this->_cleanConfigCache(); + $cache = $this->_cacheFrontendPool->get(\Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER); + $cache->remove(\Flekto\Postcode\Block\System\Config\Status::CACHE_ID); + } } diff --git a/Service/PostcodeApiClient.php b/Service/PostcodeApiClient.php index 9319d06..ec627d7 100644 --- a/Service/PostcodeApiClient.php +++ b/Service/PostcodeApiClient.php @@ -67,7 +67,7 @@ public function __construct(string $key, string $secret) /** * @see https://api.postcode.nl/documentation/international/v1/Autocomplete/autocomplete */ - public function internationalAutocomplete(string $context, string $term, ?string $session = null, $language = ''): array + public function internationalAutocomplete(string $context, string $term, ?string $session = null, string $language = ''): array { return $this->_performApiCall('international/v1/autocomplete/' . rawurlencode($context) . '/' . rawurlencode($term) . '/' . rawurlencode($language), $session ?? $this->_generateSessionString()); } diff --git a/Setup/Patch/Data/UpdateApiStatusConfig.php b/Setup/Patch/Data/UpdateApiStatusConfig.php index dc8e434..ac8dfce 100644 --- a/Setup/Patch/Data/UpdateApiStatusConfig.php +++ b/Setup/Patch/Data/UpdateApiStatusConfig.php @@ -43,7 +43,7 @@ public function __construct( * * @return string[] */ - public function getAliases() + public function getAliases(): array { return []; } @@ -53,7 +53,7 @@ public function getAliases() * * @return string[] */ - public static function getDependencies() + public static function getDependencies(): array { return []; } @@ -61,9 +61,9 @@ public static function getDependencies() /** * Apply patch. * - * @return $this + * @return void */ - public function apply() + public function apply(): void { $this->_resourceConfig->getConnection()->startSetup(); $connection = $this->_resourceConfig->getConnection(); diff --git a/composer.json b/composer.json index ef7471b..6e04003 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "postcode-nl/api-magento2-module", - "version": "3.1.10", + "version": "3.1.11", "description": "Postcode.eu International Address API module for Magento 2. Adds autocompletion for addresses in multiple countries using official postal data.", "require": { "php": "^7.4 || ^8.0 || ^8.1 || ^8.2", diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml index a077331..ce566c1 100644 --- a/etc/adminhtml/di.xml +++ b/etc/adminhtml/di.xml @@ -1,5 +1,4 @@ - @@ -8,4 +7,4 @@ - \ No newline at end of file + diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index d46b817..ccca903 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -40,7 +40,7 @@ - Allows users to skip the autocomplete field and manually enter an address. Enabling this option may lead to invalid addresses. + Allows users to skip the autocomplete field and manually enter an address. Enabling this option may lead to invalid addresses. Applicable to free address input only. Magento\Config\Model\Config\Source\Yesno format|disable|hide diff --git a/etc/config.xml b/etc/config.xml index 467dc38..8bafb93 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -3,7 +3,7 @@ - 3.1.10 + 3.1.11 new diff --git a/etc/crontab.xml b/etc/crontab.xml index a948717..9144a4a 100644 --- a/etc/crontab.xml +++ b/etc/crontab.xml @@ -4,5 +4,8 @@ 3 3 * * * + + 3 3 * * * + diff --git a/etc/db_schema.xml b/etc/db_schema.xml new file mode 100644 index 0000000..2be74f0 --- /dev/null +++ b/etc/db_schema.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + +
+
diff --git a/etc/di.xml b/etc/di.xml index 6f78329..63e31b7 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -1,6 +1,9 @@ + + + diff --git a/etc/module.xml b/etc/module.xml index 26ad5ed..87d584a 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,6 +1,6 @@ - + diff --git a/view/adminhtml/templates/system/config/status.phtml b/view/adminhtml/templates/system/config/status.phtml index 7f70599..6a6da43 100644 --- a/view/adminhtml/templates/system/config/status.phtml +++ b/view/adminhtml/templates/system/config/status.phtml @@ -1,6 +1,8 @@ getConfig(); +$accountInfo = $block->getAccountInfo(); +$moduleInfo = $block->getModuleInfo(); ?>
@@ -9,10 +11,25 @@ $config = $block->getConfig();
-

Module version escapeHtml($config['module_version']) ?>

+

+ Module version escapeHtml($moduleInfo['version']) ?> + + + ↻ + escapeHtml(__('update available')) ?> + + + +

- +
@@ -24,12 +41,35 @@ $config = $block->getConfig();

API connection

- +
Account name
-
escapeHtml($config['account_name']) ?>
+
escapeHtml($accountInfo['name']) ?>
Subscription status
-
+
+ + + + + + euro + +

Supported countries

diff --git a/view/adminhtml/web/css/postcode-eu.css b/view/adminhtml/web/css/postcode-eu.css index a8fce67..4487fab 100644 --- a/view/adminhtml/web/css/postcode-eu.css +++ b/view/adminhtml/web/css/postcode-eu.css @@ -107,3 +107,20 @@ .badge-account-status-inactive { background-color: #666; } + +.account-usage-meter { + width: 100px; + margin: 0 5px 0 10px; +} + +.update-available-message { + display: inline-block; + padding: 1px 10px 2px 7px; + border-radius: 20px; + background-color: #00759a; + color: white; +} + +.update-available-message a { + color: inherit; +} diff --git a/view/frontend/web/js/form/components/address-autofill-nl.js b/view/frontend/web/js/form/components/address-autofill-nl.js index 55bea25..84f1881 100644 --- a/view/frontend/web/js/form/components/address-autofill-nl.js +++ b/view/frontend/web/js/form/components/address-autofill-nl.js @@ -118,6 +118,7 @@ define([ this.resetHouseNumberSelect(); this.resetInputAddress(); this.loading(true); + this.childHouseNumber().error(false); const url = `${this.settings.base_url}postcode-eu/V1/nl/address/${postcode}/${houseNumber}`; diff --git a/view/frontend/web/js/ko/bindings/init-intl-autocomplete.js b/view/frontend/web/js/ko/bindings/init-intl-autocomplete.js index 46eff34..317db79 100644 --- a/view/frontend/web/js/ko/bindings/init-intl-autocomplete.js +++ b/view/frontend/web/js/ko/bindings/init-intl-autocomplete.js @@ -2,7 +2,8 @@ define([ 'ko', 'Magento_Ui/js/lib/knockout/template/renderer', 'Flekto_Postcode/js/lib/postcode-eu-autocomplete-address', -], function (ko, renderer, AutocompleteAddress) { + 'mage/translate', +], function (ko, renderer, AutocompleteAddress, $t) { 'use strict'; ko.bindingHandlers.initIntlAutocomplete = { diff --git a/view/frontend/web/js/view/customer/address/autofill.js b/view/frontend/web/js/view/customer/address/autofill.js index 5a0decb..e0f29d4 100644 --- a/view/frontend/web/js/view/customer/address/autofill.js +++ b/view/frontend/web/js/view/customer/address/autofill.js @@ -2,6 +2,7 @@ define([ 'uiCollection', 'uiRegistry', 'jquery', + 'jquery/validate', ], function (Collection, Registry, $) { 'use strict';