diff --git a/Controller/Api/Meteo.php b/Controller/Api/Meteo.php index c1ff448..066ac0d 100644 --- a/Controller/Api/Meteo.php +++ b/Controller/Api/Meteo.php @@ -7,35 +7,37 @@ namespace Opengento\Snowflake\Controller\Api; -use Magento\Framework\App\Action\Action; -use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Controller\Result\Json; use Magento\Framework\Controller\Result\JsonFactory; use Opengento\Snowflake\Service\OpenWeatherMapApi; -class Meteo extends Action +class Meteo implements HttpGetActionInterface { - protected OpenWeatherMapApi $api; - protected JsonFactory $resultJsonFactory; + private RequestInterface $request; + + private OpenWeatherMapApi $api; + + private JsonFactory $resultJsonFactory; public function __construct( - Context $context, + RequestInterface $request, OpenWeatherMapApi $api, JsonFactory $resultJsonFactory ) { - parent::__construct($context); - $this->resultJsonFactory = $resultJsonFactory; + $this->request = $request; $this->api = $api; + $this->resultJsonFactory = $resultJsonFactory; } - /** - * @throws \Cmfcmf\OpenWeatherMap\Exception - */ - public function execute() + // ToDo: Add exception handling + CSRF + public function execute(): Json { $isSnowing = ['is_snowing' => '0']; - $lat = $this->getRequest()->getParam('lat') ?? ''; - $lon = $this->getRequest()->getParam('lon') ?? ''; + $lat = $this->request->getParam('lat') ?? ''; + $lon = $this->request->getParam('lon') ?? ''; if ($lat && $lon) { $isSnowing = ['is_snowing' => $this->api->isSnowing($lat, $lon)]; diff --git a/Model/Config/Backend/EmojiConverter.php b/Model/Config/Backend/EmojiConverter.php index 889e411..4e036bc 100644 --- a/Model/Config/Backend/EmojiConverter.php +++ b/Model/Config/Backend/EmojiConverter.php @@ -12,19 +12,15 @@ class EmojiConverter extends Value implements ProcessorInterface { - /** - * Unset array element with '__empty' key - * - * @return $this - */ - public function beforeSave() + public function beforeSave(): self { $this->setValue(json_encode($this->getValue())); + return parent::beforeSave(); } - public function processValue($value) + public function processValue($value): string { - return json_decode($value); + return (string)json_decode($value); } } diff --git a/Model/Config/OpenWeather.php b/Model/Config/OpenWeather.php new file mode 100644 index 0000000..f4477d8 --- /dev/null +++ b/Model/Config/OpenWeather.php @@ -0,0 +1,55 @@ +scopeConfig = $scopeConfig; + } + + public function isEnabled(?int $scopeId = null): bool + { + return $this->scopeConfig->isSetFlag( + self::CONFIG_PATH_SNOWFLAKE_OPENWEATHERMAP_ENABLED, + ScopeInterface::SCOPE_STORE, + $scopeId + ); + } + + public function getApiKey(?int $scopeId = null): string + { + return (string)$this->scopeConfig->getValue( + self::CONFIG_PATH_SNOWFLAKE_OPENWEATHERMAP_API_KEY, + ScopeInterface::SCOPE_STORE, + $scopeId + ); + } + + public function getIpLocatorApiUrl(?int $scopeId = null): string + { + return (string)$this->scopeConfig->getValue( + self::CONFIG_PATH_SNOWFLAKE_IP_LOCATOR_API_URL, + ScopeInterface::SCOPE_STORE, + $scopeId + ); + } +} diff --git a/Model/Config/Snowflake.php b/Model/Config/Snowflake.php index 6f0e466..7d7f53d 100644 --- a/Model/Config/Snowflake.php +++ b/Model/Config/Snowflake.php @@ -10,17 +10,16 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Store\Model\ScopeInterface; -class Snowflake +/** + * @api + */ +final class Snowflake { - public const AJAX_URL = 'opengento_snowflake/api/meteo'; - private const CONFIG_PATH_SNOWFLAKE_ENABLE = 'snowflake/general/enable'; private const CONFIG_PATH_SNOWFLAKE_CHAR = 'snowflake/general/icon'; private const CONFIG_PATH_SNOWFLAKE_V_SPEED = 'snowflake/general/vspeed'; private const CONFIG_PATH_SNOWFLAKE_H_SPEED = 'snowflake/general/hspeed'; private const CONFIG_PATH_SNOWFLAKE_ROT_SPEED = 'snowflake/general/rotspeed'; - private const CONFIG_PATH_SNOWFLAKE_OPENWEATHERMAP_ENABLE = 'snowflake/general/enable_api'; - private const CONFIG_PATH_SNOWFLAKE_OPENWEATHERMAP_API_KEY = 'snowflake/general/api_key'; private const CONFIG_PATH_SNOWFLAKE_MIN_SIZE = 'snowflake/general/max_size'; private const CONFIG_PATH_SNOWFLAKE_MAX_SIZE = 'snowflake/general/min_size'; private const CONFIG_PATH_SNOWFLAKE_QTY = 'snowflake/general/qty'; @@ -40,64 +39,69 @@ public function isEnabled(?int $scopeId = null): bool public function getSnowflakeChar(?int $scopeId = null): string { - return $this->scopeConfig->getValue(self::CONFIG_PATH_SNOWFLAKE_CHAR, ScopeInterface::SCOPE_STORE, $scopeId) ?? ''; - } - - public function getSnowflakeVSpeed(?int $scopeId = null): string - { - return $this->scopeConfig->getValue(self::CONFIG_PATH_SNOWFLAKE_V_SPEED, ScopeInterface::SCOPE_STORE, $scopeId) ?? ''; - } - - public function getSnowflakeHSpeed(?int $scopeId = null): string - { - return $this->scopeConfig->getValue(self::CONFIG_PATH_SNOWFLAKE_H_SPEED, ScopeInterface::SCOPE_STORE, $scopeId) ?? ''; - } - - public function getSnowflakeRotSpeed(?int $scopeId = null): string - { - return $this->scopeConfig->getValue(self::CONFIG_PATH_SNOWFLAKE_ROT_SPEED, ScopeInterface::SCOPE_STORE, $scopeId) ?? ''; + return (string)$this->scopeConfig->getValue( + self::CONFIG_PATH_SNOWFLAKE_CHAR, + ScopeInterface::SCOPE_STORE, + $scopeId + ); } - public function getSnowflakeQty(?int $scopeId = null): string + public function getSnowflakeVSpeed(?int $scopeId = null): float { - return $this->scopeConfig->getValue(self::CONFIG_PATH_SNOWFLAKE_QTY, ScopeInterface::SCOPE_STORE, $scopeId) ?? ''; + return (float)$this->scopeConfig->getValue( + self::CONFIG_PATH_SNOWFLAKE_V_SPEED, + ScopeInterface::SCOPE_STORE, + $scopeId + ); } - public function getSnowflakeMinSize(?int $scopeId = null): string + public function getSnowflakeHSpeed(?int $scopeId = null): float { - return $this->scopeConfig->getValue(self::CONFIG_PATH_SNOWFLAKE_MIN_SIZE, ScopeInterface::SCOPE_STORE, $scopeId) ?? ''; + return (float)$this->scopeConfig->getValue( + self::CONFIG_PATH_SNOWFLAKE_H_SPEED, + ScopeInterface::SCOPE_STORE, + $scopeId + ); } - public function getSnowflakeMaxSize(?int $scopeId = null): string + public function getSnowflakeRotSpeed(?int $scopeId = null): int { - return $this->scopeConfig->getValue(self::CONFIG_PATH_SNOWFLAKE_MAX_SIZE, ScopeInterface::SCOPE_STORE, $scopeId) ?? ''; + return (int)$this->scopeConfig->getValue( + self::CONFIG_PATH_SNOWFLAKE_ROT_SPEED, + ScopeInterface::SCOPE_STORE, + $scopeId + ); } - public function isForceSnow(?int $scopeId = null): bool + public function getSnowflakeQty(?int $scopeId = null): int { - return $this->scopeConfig->isSetFlag(self::CONFIG_PATH_SNOWFLAKE_FORCE, ScopeInterface::SCOPE_STORE, $scopeId); + return (int)$this->scopeConfig->getValue( + self::CONFIG_PATH_SNOWFLAKE_QTY, + ScopeInterface::SCOPE_STORE, + $scopeId + ); } - public function isApiEnable(?int $scopeId = null): bool + public function getSnowflakeMinSize(?int $scopeId = null): int { - return $this->scopeConfig->isSetFlag( - self::CONFIG_PATH_SNOWFLAKE_OPENWEATHERMAP_ENABLE, + return (int)$this->scopeConfig->getValue( + self::CONFIG_PATH_SNOWFLAKE_MIN_SIZE, ScopeInterface::SCOPE_STORE, $scopeId ); } - public function getApiKey(?int $scopeId = null): string + public function getSnowflakeMaxSize(?int $scopeId = null): int { - return $this->scopeConfig->getValue( - self::CONFIG_PATH_SNOWFLAKE_OPENWEATHERMAP_API_KEY, + return (int)$this->scopeConfig->getValue( + self::CONFIG_PATH_SNOWFLAKE_MAX_SIZE, ScopeInterface::SCOPE_STORE, $scopeId ); } - public function getAjaxUrl(): string + public function isForceSnow(?int $scopeId = null): bool { - return static::AJAX_URL; + return $this->scopeConfig->isSetFlag(self::CONFIG_PATH_SNOWFLAKE_FORCE, ScopeInterface::SCOPE_STORE, $scopeId); } } diff --git a/README.md b/README.md index 18e2eeb..9f99380 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ bin/magento setup:upgrade ## Features +![Let it snow!](doc/snowflake.png) + ### Snowflake base on local meteo Do you like the snow? Do you like to feel the same weather on your favorite website? Try this plugin and get the snow along your local meteo! @@ -59,6 +61,10 @@ You don't like snow, no problem, Snowflake can make it rain [cookies](https://tw The configuration for this module is available in `Stores > Configuration > General > ❄️ Snowflake`. +![General Config](doc/config1.png) + +![Openweather Config](doc/config2.png) + ## Support Raise a new [request](https://github.com/opengento/magento2-snowflake/issues) to the issue tracker. diff --git a/Service/OpenWeatherMapApi.php b/Service/OpenWeatherMapApi.php index a5ee8b4..770b0e0 100644 --- a/Service/OpenWeatherMapApi.php +++ b/Service/OpenWeatherMapApi.php @@ -10,26 +10,28 @@ use Cmfcmf\OpenWeatherMap; use Http\Adapter\Guzzle6\Client as GuzzleAdapter; use Http\Factory\Guzzle\RequestFactory; -use Opengento\Snowflake\Model\Config\Snowflake; +use Opengento\Snowflake\Model\Config\OpenWeather as OpenWeatherConfig; +/** + * @api + */ class OpenWeatherMapApi { - // Manage all Group 6xx: Snow - // https://openweathermap.org/weather-conditions + /** Manage all Group 6xx: Snow: https://openweathermap.org/weather-conditions */ public const WEATHER_CONDITION = 'snow'; - // Language of data (try your own language here!): - protected string $lang = 'en'; + /** Language of data (try your own language here!):*/ + private string $lang = 'en'; - // Units (can be 'metric' or 'imperial' [default]): - protected string $units = 'metric'; + /** Units (can be 'metric' or 'imperial' [default]):*/ + private string $units = 'metric'; - protected Snowflake $config; + private OpenWeatherConfig $openWeatherConfig; public function __construct( - Snowflake $config + OpenWeatherConfig $openWeatherConfig ) { - $this->config = $config; + $this->openWeatherConfig = $openWeatherConfig; } /** @@ -37,15 +39,13 @@ public function __construct( */ public function isSnowing(string $lat, string $lon): bool { - $apiKey = $this->config->getApiKey(); - $httpRequestFactory = new RequestFactory(); $httpClient = GuzzleAdapter::createWithConfig([]); - $owm = new OpenWeatherMap($apiKey, $httpClient, $httpRequestFactory); + $owm = new OpenWeatherMap($this->openWeatherConfig->getApiKey(), $httpClient, $httpRequestFactory); $weather = $owm->getWeather(['lat' => $lat, 'lon' => $lon], $this->lang, $this->units); - return static::WEATHER_CONDITION === $weather->weather->description; + return self::WEATHER_CONDITION === $weather->weather->description; } } diff --git a/Block/Snowflake.php b/ViewModel/Snowflake.php similarity index 51% rename from Block/Snowflake.php rename to ViewModel/Snowflake.php index c8c8198..b643a21 100644 --- a/Block/Snowflake.php +++ b/ViewModel/Snowflake.php @@ -5,24 +5,24 @@ */ declare(strict_types=1); -namespace Opengento\Snowflake\Block; +namespace Opengento\Snowflake\ViewModel; -use Magento\Framework\View\Element\Template; -use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\View\Element\Block\ArgumentInterface; +use Opengento\Snowflake\Model\Config\OpenWeather as OpenWeatherConfig; use Opengento\Snowflake\Model\Config\Snowflake as SnowflakeConfig; -class Snowflake extends Template +final class Snowflake implements ArgumentInterface { - protected SnowflakeConfig $snowflakeConfig; - protected ScopeConfigInterface $scopeConfig; + private SnowflakeConfig $snowflakeConfig; + + private OpenWeatherConfig $openWeatherConfig; public function __construct( - Template\Context $context, SnowflakeConfig $snowflakeConfig, - array $data = [] + OpenWeatherConfig $openWeatherConfig ) { $this->snowflakeConfig = $snowflakeConfig; - parent::__construct($context, $data); + $this->openWeatherConfig = $openWeatherConfig; } public function getSnowflakeChar(): string @@ -30,34 +30,34 @@ public function getSnowflakeChar(): string return $this->snowflakeConfig->getSnowflakeChar(); } - public function getSnowflakeVSpeed(): string + public function getSnowflakeVSpeed(): float { return $this->snowflakeConfig->getSnowflakeVSpeed(); } - public function getSnowflakeHSpeed(): string + public function getSnowflakeHSpeed(): float { return $this->snowflakeConfig->getSnowflakeHSpeed(); } - public function getSnowflakeRotSpeed(): string + public function getSnowflakeRotSpeed(): int { return $this->snowflakeConfig->getSnowflakeRotSpeed(); } public function getSnowflakeQty(): int { - return (int)$this->snowflakeConfig->getSnowflakeQty(); + return $this->snowflakeConfig->getSnowflakeQty(); } public function getSnowflakeMinSize(): int { - return (int)$this->snowflakeConfig->getSnowflakeMinSize(); + return $this->snowflakeConfig->getSnowflakeMinSize(); } public function getSnowflakeMaxSize(): int { - return (int)$this->snowflakeConfig->getSnowflakeMaxSize(); + return $this->snowflakeConfig->getSnowflakeMaxSize(); } public function isForceSnow(): bool @@ -65,13 +65,13 @@ public function isForceSnow(): bool return $this->snowflakeConfig->isForceSnow(); } - public function isApiEnable(): bool + public function isApiEnabled(): bool { - return $this->snowflakeConfig->isApiEnable(); + return $this->openWeatherConfig->isEnabled(); } - public function getAjaxUrl(): string + public function getIpLocatorApiUrl(): string { - return $this->snowflakeConfig->getAjaxUrl(); + return $this->openWeatherConfig->getIpLocatorApiUrl(); } } diff --git a/composer.json b/composer.json index cd92358..b1e914c 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,10 @@ ], "require": { "php": "^7.4||^8.0", + "ext-json": "*", "magento/framework": "^103.0", + "magento/module-config": "*", + "magento/module-store": "*", "cmfcmf/openweathermap-php-api": "^3.3", "http-interop/http-factory-guzzle": "^1.0", "php-http/guzzle6-adapter": "^2.0" @@ -62,5 +65,8 @@ "psr-4": { "Opengento\\Snowflake\\": "" } + }, + "archive": { + "exclude": ["/doc"] } } diff --git a/doc/config1.png b/doc/config1.png new file mode 100644 index 0000000..8b22d38 Binary files /dev/null and b/doc/config1.png differ diff --git a/doc/config2.png b/doc/config2.png new file mode 100644 index 0000000..405aae0 Binary files /dev/null and b/doc/config2.png differ diff --git a/doc/snowflake.png b/doc/snowflake.png new file mode 100644 index 0000000..328b025 Binary files /dev/null and b/doc/snowflake.png differ diff --git a/etc/acl.xml b/etc/acl.xml new file mode 100644 index 0000000..6ae0647 --- /dev/null +++ b/etc/acl.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 920d0cc..0fbdb50 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -7,39 +7,35 @@ --> - - -
separator-top general Opengento_Snowflake::config - + - - + + snowflake/general/enable - Magento\Config\Model\Config\Source\Yesno + Magento\Config\Model\Config\Source\Enabledisable - + - Icon to display as a snowflake ❄️. + more emoji.]]> Opengento\Snowflake\Model\Config\Backend\EmojiConverter 1 - + - snowflake/general/force Magento\Config\Model\Config\Source\Yesno - ⚠️ Display snow whatever is the weather (this makes OpenWeatherMap API useless). + 1 - + Quantity of icons displayed. validate-digits @@ -47,7 +43,7 @@ 1 - + Minimum size of icon in pixels. validate-digits @@ -55,7 +51,7 @@ 1 - + Maximum size of icon in pixels. validate-digits @@ -63,21 +59,21 @@ 1 - + Positive value to go right, negatives values to go left. 1 - + Positive value to fall down, negatives values to ascend. 1 - + Duration in seconds to do a complete turn on itself. Set to 0 to keep icon still. @@ -85,30 +81,25 @@ - - 0 Force Display.]]> - - - snowflake/general/enable_api - Magento\Config\Model\Config\Source\Yesno + + + Magento\Config\Model\Config\Source\Enabledisable 1 - - + - snowflake/general/api_api_key + Magento\Config\Model\Config\Backend\Encrypted 1 openweathermap.org to get the API Key. You will not be able to use the integration without the API Key.]]> -
diff --git a/etc/config.xml b/etc/config.xml index d1d79a8..44bf1f7 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -10,17 +10,19 @@ 0 - sss + "\u2744\ufe0f" + 0 + 0.75 + 0.75 70 8 36 - 0.75 - 0.75 6 6 - 0 + + https://ipinfo.io/json diff --git a/etc/frontend/routes.xml b/etc/frontend/routes.xml index 77641cd..905af1e 100644 --- a/etc/frontend/routes.xml +++ b/etc/frontend/routes.xml @@ -1,3 +1,10 @@ + + diff --git a/etc/module.xml b/etc/module.xml index 478bd99..696e9bb 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -9,6 +9,7 @@ + diff --git a/i18n/en_US.csv b/i18n/en_US.csv new file mode 100644 index 0000000..a9bf89c --- /dev/null +++ b/i18n/en_US.csv @@ -0,0 +1,18 @@ +"Snowflake Meteo","Snowflake Meteo" +"❄️ Snowflake","❄️ Snowflake" +"General Configuration","General Configuration" +Status,Status +Icon,Icon +"Icon to display as a snowflake ❄️, get more emoji.","Icon to display as a snowflake ❄️, get more emoji." +"Force Display","Force Display" +"⚠️ Display snow whatever is the weather (this makes OpenWeatherMap API useless).","⚠️ Display snow whatever is the weather (this makes OpenWeatherMap API useless)." +Quantity,Quantity +"Quantity of icons displayed.","Quantity of icons displayed." +"Minimum size","Minimum size" +"Maximum size","Maximum size" +"Horizontal Speed","Horizontal Speed" +"Vertical Speed","Vertical Speed" +"Rotation Speed","Rotation Speed" +"OpenWeatherMap API","OpenWeatherMap API" +"API Key","API Key" +"⚠️ Configure an OpenWeatherMap account on openweathermap.org to get the API Key. You will not be able to use the integration without the API Key.","⚠️ Configure an OpenWeatherMap account on openweathermap.org to get the API Key. You will not be able to use the integration without the API Key." diff --git a/view/frontend/layout/default.xml b/view/frontend/layout/default.xml index bda234b..4f255af 100644 --- a/view/frontend/layout/default.xml +++ b/view/frontend/layout/default.xml @@ -8,12 +8,12 @@ - + + + Opengento\Snowflake\ViewModel\Snowflake + + + diff --git a/view/frontend/templates/snowflake.phtml b/view/frontend/templates/snowflake.phtml index feaf096..805882f 100644 --- a/view/frontend/templates/snowflake.phtml +++ b/view/frontend/templates/snowflake.phtml @@ -5,52 +5,53 @@ */ declare(strict_types=1); -/** @var \Opengento\Snowflake\Block\Snowflake $block */ +use Magento\Framework\View\Element\Template; +use Opengento\Snowflake\ViewModel\Snowflake; + +/** @var Template $block */ +/** @var Snowflake $viewModel */ +$viewModel = $block->getData('viewModel'); ?>