ref(env) wip
This commit is contained in:
parent
5529e91915
commit
730184704e
10 changed files with 58 additions and 36 deletions
|
|
@ -8,6 +8,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use Roots\WPConfig\Config;
|
use Roots\WPConfig\Config;
|
||||||
|
|
||||||
|
use function base64_encode;
|
||||||
use function Env\env;
|
use function Env\env;
|
||||||
|
|
||||||
Config::define('SAVEQUERIES', true);
|
Config::define('SAVEQUERIES', true);
|
||||||
|
|
@ -25,6 +26,10 @@ Config::define('DISALLOW_FILE_MODS', false);
|
||||||
// WooCommerce
|
// WooCommerce
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
||||||
|
Config::define(
|
||||||
|
'WOOCOMMERCE_API_AUTH_STRING',
|
||||||
|
base64_encode(env('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . env('WOOCOMMERCE_API_CONSUMER_SECRET')),
|
||||||
|
);
|
||||||
|
|
||||||
// Stripe
|
// Stripe
|
||||||
Config::define('STRIPE_API_SECRET', env('STRIPE_API_SECRET'));
|
Config::define('STRIPE_API_SECRET', env('STRIPE_API_SECRET'));
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use Roots\WPConfig\Config;
|
use Roots\WPConfig\Config;
|
||||||
|
|
||||||
|
use function base64_encode;
|
||||||
use function Env\env;
|
use function Env\env;
|
||||||
|
|
||||||
Config::define('WP_DEBUG', true);
|
Config::define('WP_DEBUG', true);
|
||||||
|
|
@ -20,6 +21,10 @@ Config::define('DISALLOW_FILE_MODS', false);
|
||||||
|
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
||||||
|
Config::define(
|
||||||
|
'WOOCOMMERCE_API_AUTH_STRING',
|
||||||
|
base64_encode(env('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . env('WOOCOMMERCE_API_CONSUMER_SECRET')),
|
||||||
|
);
|
||||||
|
|
||||||
// Stripe
|
// Stripe
|
||||||
Config::define('STRIPE_API_SECRET', env('STRIPE_API_SECRET'));
|
Config::define('STRIPE_API_SECRET', env('STRIPE_API_SECRET'));
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,13 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use Roots\WPConfig\Config;
|
use Roots\WPConfig\Config;
|
||||||
|
|
||||||
|
use function base64_encode;
|
||||||
use function Env\env;
|
use function Env\env;
|
||||||
|
|
||||||
Config::define('DISALLOW_INDEXING', true);
|
Config::define('DISALLOW_INDEXING', true);
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_KEY', env('WOOCOMMERCE_API_CONSUMER_KEY'));
|
||||||
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
Config::define('WOOCOMMERCE_API_CONSUMER_SECRET', env('WOOCOMMERCE_API_CONSUMER_SECRET'));
|
||||||
|
Config::define(
|
||||||
|
'WOOCOMMERCE_API_AUTH_STRING',
|
||||||
|
base64_encode(env('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . env('WOOCOMMERCE_API_CONSUMER_SECRET')),
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ use WC_Product;
|
||||||
use function add_action;
|
use function add_action;
|
||||||
use function array_map;
|
use function array_map;
|
||||||
use function assert;
|
use function assert;
|
||||||
use function base64_encode;
|
|
||||||
use function is_string;
|
use function is_string;
|
||||||
use function wc_get_products;
|
use function wc_get_products;
|
||||||
use function wp_create_nonce;
|
use function wp_create_nonce;
|
||||||
|
|
@ -33,12 +32,7 @@ $products = array_map(callback: Product::from_wc_product(...), array: $wc_produc
|
||||||
$context['products'] = $products;
|
$context['products'] = $products;
|
||||||
|
|
||||||
// Injecte les états initiaux des données du Produit sous forme de JSON dans le contexte.
|
// Injecte les états initiaux des données du Produit sous forme de JSON dans le contexte.
|
||||||
$page_states = [
|
$page_states = ['authString' => Config::get('WOOCOMMERCE_API_AUTH_STRING'), 'nonce' => wp_create_nonce('wc_store_api')]
|
||||||
'nonce' => wp_create_nonce('wc_store_api'),
|
|
||||||
'authString' => base64_encode(
|
|
||||||
Config::get('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . Config::get('WOOCOMMERCE_API_CONSUMER_SECRET'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|> wp_json_encode(...);
|
|> wp_json_encode(...);
|
||||||
assert(is_string($page_states));
|
assert(is_string($page_states));
|
||||||
$context['page_states'] = $page_states;
|
$context['page_states'] = $page_states;
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,8 @@ function retire_merdes_wc(): void {
|
||||||
*/
|
*/
|
||||||
function genere_balises_img_dans_produit_dans_reponse_rest(
|
function genere_balises_img_dans_produit_dans_reponse_rest(
|
||||||
WP_REST_Response $response,
|
WP_REST_Response $response,
|
||||||
mixed $_product,
|
WC_Data $_product,
|
||||||
|
WP_REST_Request $_request,
|
||||||
): WP_REST_Response {
|
): WP_REST_Response {
|
||||||
// Vérifie que la Réponse a des données
|
// Vérifie que la Réponse a des données
|
||||||
if (empty($response->data)) {
|
if (empty($response->data)) {
|
||||||
|
|
@ -169,37 +170,34 @@ function genere_balises_img_dans_produit_dans_reponse_rest(
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_filter('woocommerce_rest_prepare_product_object', 'genere_balises_img_dans_produit_dans_reponse_rest', 10, 2);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO.
|
* TODO.
|
||||||
*/
|
*/
|
||||||
function genere_prix_maximal_produit_variable_dans_reponse_rest(
|
function genere_prix_maximal_produit_variable_dans_reponse_rest(
|
||||||
WP_REST_Response $reponse,
|
WP_REST_Response $response,
|
||||||
WC_Data $_produit,
|
WC_Data $_product,
|
||||||
|
WP_REST_Request $_request,
|
||||||
): WP_REST_Response {
|
): WP_REST_Response {
|
||||||
// Vérifie que la Réponse a des données
|
// Vérifie que la Réponse a des données
|
||||||
if (empty($reponse->data)) {
|
if (empty($response->data)) {
|
||||||
return $reponse;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si le Produit n'est pas Variable, assigner le prix du Produit comme prix maximal
|
// Si le Produit n'est pas Variable, assigner le prix du Produit comme prix maximal
|
||||||
if ('variable' !== $reponse->data['type']) {
|
if ('variable' !== $response->data['type']) {
|
||||||
$reponse->data['prix_maximal'] = $reponse->data['regular_price'];
|
$response->data['prix_maximal'] = $response->data['regular_price'];
|
||||||
|
|
||||||
return $reponse;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assigne le prix de la Variation la plus chère dans la Réponse
|
// Assigne le prix de la Variation la plus chère dans la Réponse
|
||||||
$reponse->data['prix_maximal'] = collect($reponse->data['variations'])
|
$response->data['prix_maximal'] = collect($response->data['variations'])
|
||||||
->map(wc_get_product(...))
|
->map(wc_get_product(...))
|
||||||
->map(static fn($p) => $p->get_price())->max();
|
->map(static fn($p) => $p->get_price())->max();
|
||||||
|
|
||||||
return $reponse;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_filter('woocommerce_rest_prepare_product_object', 'genere_prix_maximal_produit_variable_dans_reponse_rest', 10, 2);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retire la propagande commerciale de WooCommerce du menu.
|
* Retire la propagande commerciale de WooCommerce du menu.
|
||||||
*/
|
*/
|
||||||
|
|
@ -216,3 +214,8 @@ add_action('init', 'retire_script_galerie');
|
||||||
add_action('template_redirect', 'retire_merdes_wc');
|
add_action('template_redirect', 'retire_merdes_wc');
|
||||||
add_action('wp_enqueue_scripts', 'dequeue_woocommerce_styles_scripts');
|
add_action('wp_enqueue_scripts', 'dequeue_woocommerce_styles_scripts');
|
||||||
add_filter('woocommerce_enqueue_styles', '__return_empty_array');
|
add_filter('woocommerce_enqueue_styles', '__return_empty_array');
|
||||||
|
add_filter('woocommerce_rest_prepare_product_object', 'genere_balises_img_dans_produit_dans_reponse_rest', 10, 3);
|
||||||
|
add_filter('woocommerce_rest_prepare_product_object', 'genere_prix_maximal_produit_variable_dans_reponse_rest', 10, 3);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
// add_filter('woocommerce_store_api_disable_nonce_check', '__return_true');
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Console, Context, Effect, Layer, Match, pipe, References, Schedule, Schema, SchemaIssue } from "effect";
|
import { Console, Context, Effect, Layer, Match, pipe, Schedule, Schema, SchemaIssue } from "effect";
|
||||||
import type { SchemaError } from "effect/Schema";
|
import type { SchemaError } from "effect/Schema";
|
||||||
import type {
|
import type {
|
||||||
HttpClientError,
|
HttpClientError,
|
||||||
|
|
@ -13,6 +13,7 @@ import { HttpClientErrorSchema } from "effect/unstable/http/HttpClientError";
|
||||||
import type { CartProduct, GetProducts } from "../schemas/api.ts";
|
import type { CartProduct, GetProducts } from "../schemas/api.ts";
|
||||||
import { Product } from "../schemas/api.ts";
|
import { Product } from "../schemas/api.ts";
|
||||||
import { WooCommerceCart } from "../schemas/cart.ts";
|
import { WooCommerceCart } from "../schemas/cart.ts";
|
||||||
|
import { AppConfig, Provider } from "./config.ts";
|
||||||
|
|
||||||
/** Le nombre maximal d'essais pour une Requête. */
|
/** Le nombre maximal d'essais pour une Requête. */
|
||||||
const MAX_RETRIES = 3;
|
const MAX_RETRIES = 3;
|
||||||
|
|
@ -81,6 +82,8 @@ class APIClient extends Context.Service<APIClient>()("haikuatelier.fr/APIClient"
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const config = yield* AppConfig.parse(Provider);
|
||||||
|
|
||||||
const matchAPIError = (error: HttpClientError.HttpClientError | SchemaError): APIError => {
|
const matchAPIError = (error: HttpClientError.HttpClientError | SchemaError): APIError => {
|
||||||
if (error._tag === "SchemaError") {
|
if (error._tag === "SchemaError") {
|
||||||
return new APIRequestError({
|
return new APIRequestError({
|
||||||
|
|
@ -126,9 +129,6 @@ class APIClient extends Context.Service<APIClient>()("haikuatelier.fr/APIClient"
|
||||||
Effect.flatMap(HttpClientResponse.schemaBodyJson(WooCommerceCart)),
|
Effect.flatMap(HttpClientResponse.schemaBodyJson(WooCommerceCart)),
|
||||||
Effect.mapError(error => matchAPIError(error)),
|
Effect.mapError(error => matchAPIError(error)),
|
||||||
Effect.tapError(error => printErrorAsSuccinctMessage(error)),
|
Effect.tapError(error => printErrorAsSuccinctMessage(error)),
|
||||||
// Effect.catchTag("APIResponseError", error => {
|
|
||||||
// if (error.cause.)
|
|
||||||
// }),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|
@ -142,8 +142,8 @@ class APIClient extends Context.Service<APIClient>()("haikuatelier.fr/APIClient"
|
||||||
HttpClientRequest.setHeader("Nonce", nonce),
|
HttpClientRequest.setHeader("Nonce", nonce),
|
||||||
// TODO: Utiliser l'environnement
|
// TODO: Utiliser l'environnement
|
||||||
HttpClientRequest.basicAuth(
|
HttpClientRequest.basicAuth(
|
||||||
"ck_ed966a2265099a6dfe9915db692cbd2450cceed6",
|
config.WOOCOMMERCE_API_CONSUMER_KEY,
|
||||||
"cs_a046c91647af95188a3e39a736ebe02f2024e430",
|
config.WOOCOMMERCE_API_CONSUMER_SECRET,
|
||||||
),
|
),
|
||||||
// Le corps de la Requête a été validée en amont, on peut utiliser Unsafe.
|
// Le corps de la Requête a été validée en amont, on peut utiliser Unsafe.
|
||||||
HttpClientRequest.setUrlParams(queryParams),
|
HttpClientRequest.setUrlParams(queryParams),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
/**
|
||||||
|
* `Config<A>` décrit la Configuration nécessaire. `ConfigProvider` est le _backend_ qui la charge. Par défault, la Configuration est lue depuis les variables d'environnement, mais d'autres sources peuvent être utilisées.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Config, ConfigProvider } from "effect";
|
||||||
|
|
||||||
|
const AppConfig = Config.all({
|
||||||
|
WOOCOMMERCE_API_CONSUMER_KEY: Config.redacted("WOOCOMMERCE_API_CONSUMER_KEY"),
|
||||||
|
WOOCOMMERCE_API_CONSUMER_SECRET: Config.redacted("WOOCOMMERCE_API_CONSUMER_SECRET"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const Provider = ConfigProvider.fromUnknown({
|
||||||
|
WOOCOMMERCE_API_CONSUMER_KEY: "ck_329c944b248aa7cc837c7662d9c6e09d638802df",
|
||||||
|
WOOCOMMERCE_API_CONSUMER_SECRET: "cs_5687d0c694bd519b231145afa7177c0c987f7155",
|
||||||
|
});
|
||||||
|
|
||||||
|
export { AppConfig, Provider };
|
||||||
|
|
@ -11,7 +11,7 @@ const ShopPageRuntime = ManagedRuntime.make(
|
||||||
Layer.provideMerge(ShopPageMessages.Live),
|
Layer.provideMerge(ShopPageMessages.Live),
|
||||||
Layer.provideMerge(ShopPageElements.Live),
|
Layer.provideMerge(ShopPageElements.Live),
|
||||||
Layer.provide(APIClient.Live),
|
Layer.provide(APIClient.Live),
|
||||||
Layer.tapError(error => Console.error("ProductPageRuntime", "Impossible de créer le Layer :", error)),
|
Layer.tapError(error => Console.error("ProductPageRuntime", "Impossible de créer le Layer :", error.message)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
export default ShopPageRuntime;
|
export default ShopPageRuntime;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import {
|
import {
|
||||||
Array as FxArray,
|
Array as FxArray,
|
||||||
Console,
|
|
||||||
Context,
|
Context,
|
||||||
Effect,
|
Effect,
|
||||||
Layer,
|
Layer,
|
||||||
|
|
@ -118,8 +117,6 @@ class ShopPageDOM extends Context.Service<ShopPageDOM>()("haikuatelier.fr/Shop/S
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMoreProductsWantedHandler = Effect.fn("onMoreProductsWantedHandler")(function*() {
|
const onMoreProductsWantedHandler = Effect.fn("onMoreProductsWantedHandler")(function*() {
|
||||||
yield* Console.debug("onMoreProductsWantedHandler");
|
|
||||||
|
|
||||||
/** Le numéro de page souhaitée. */
|
/** Le numéro de page souhaitée. */
|
||||||
const newPageNumber = yield* Ref.updateAndGet(PageNumber, pageNumber => pageNumber + 1);
|
const newPageNumber = yield* Ref.updateAndGet(PageNumber, pageNumber => pageNumber + 1);
|
||||||
/** L'ID de la Catégorie de Produits affichée dans la page si elle existe. */
|
/** L'ID de la Catégorie de Produits affichée dans la page si elle existe. */
|
||||||
|
|
@ -137,7 +134,6 @@ class ShopPageDOM extends Context.Service<ShopPageDOM>()("haikuatelier.fr/Shop/S
|
||||||
yield* SubscriptionRef.set(ShowMoreButtonText, "Getting Products...");
|
yield* SubscriptionRef.set(ShowMoreButtonText, "Getting Products...");
|
||||||
|
|
||||||
const newProducts = yield* API.GetProducts(nonce, requestBody);
|
const newProducts = yield* API.GetProducts(nonce, requestBody);
|
||||||
yield* Console.debug("onMoreProductsWantedHandler", newProducts);
|
|
||||||
|
|
||||||
// Rétablis le texte du Bouton et réactive les interactions.
|
// Rétablis le texte du Bouton et réactive les interactions.
|
||||||
yield* SubscriptionRef.set(ShowMoreButtonText, "Show more");
|
yield* SubscriptionRef.set(ShowMoreButtonText, "Show more");
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,14 @@ import ShopPageElements from "./page-boutique/service-elements.ts";
|
||||||
import ShopPageMessages from "./page-boutique/service-messages.ts";
|
import ShopPageMessages from "./page-boutique/service-messages.ts";
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", (): void => {
|
document.addEventListener("DOMContentLoaded", (): void => {
|
||||||
console.debug("scripts-page-boutique");
|
|
||||||
// initialisePageBoutique();
|
// initialisePageBoutique();
|
||||||
ShopPageRuntime.runFork(Effect.gen(function*() {
|
ShopPageRuntime.runFork(Effect.gen(function*() {
|
||||||
const Elements = yield* ShopPageElements;
|
const Elements = yield* ShopPageElements;
|
||||||
const DOM = yield* ShopPageDOM;
|
const DOM = yield* ShopPageDOM;
|
||||||
const Messages = yield* ShopPageMessages;
|
const Messages = yield* ShopPageMessages;
|
||||||
|
|
||||||
yield* Effect.all([DOM.initLoadMoreProductsOnButtonClick(), Messages.initShowMoreButtonUpdates()], {
|
yield* Effect.all([DOM.initMoreProductsOnButtonClick(), Messages.initShowMoreButtonUpdates()], {
|
||||||
concurrency: "unbounded",
|
concurrency: "unbounded",
|
||||||
}).pipe(Effect.tapCause(Console.error));
|
}).pipe(Effect.tapCause(Console.error));
|
||||||
|
|
||||||
console.debug(Elements.ProductsGrid);
|
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue