diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 4413514f..80e9eb2d 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -12,7 +12,7 @@ $finder = new Finder()->in(__DIR__)->exclude([ 'web/wp', 'web/app/languages', 'web/app/plugins', - 'web/app/mu-plugins' + 'web/app/mu-plugins', ]); return new Config() @@ -29,7 +29,7 @@ return new Config() 'const' => 'none', 'method' => 'one', 'property' => 'one', - 'trait_import' => 'none' + 'trait_import' => 'none', ]], 'class_reference_name_casing' => true, 'clean_namespace' => true, @@ -103,7 +103,7 @@ return new Config() 'return', 'switch_case', 'yield', - 'yield_from' + 'yield_from', ]], 'no_unneeded_final_method' => true, 'no_unneeded_import_alias' => true, @@ -138,7 +138,7 @@ return new Config() 'random_api_migration' => ['replacements' => [ 'getrandmax' => 'mt_getrandmax', 'rand' => 'mt_rand', - 'srand' => 'mt_srand' + 'srand' => 'mt_srand', ]], 'return_assignment' => true, 'self_accessor' => true, @@ -177,7 +177,7 @@ return new Config() 'no_superfluous_phpdoc_tags' => [ 'allow_hidden_params' => false, 'allow_mixed' => false, - 'allow_unused_params' => false + 'allow_unused_params' => false, ], // PHPDoc should contain @param for all params. 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], @@ -223,7 +223,7 @@ return new Config() 'never-returns', 'no-return', 'real', - 'str' + 'str', ]], // Annotations in PHPDoc should be grouped together so that annotations of the same type immediately follow each other. Annotations of a different type are separated by a single blank line. 'phpdoc_separation' => [ @@ -232,9 +232,9 @@ return new Config() ['author', 'copyright', 'license'], ['category', 'package', 'subpackage'], ['property', 'property-read', 'property-write'], - ['deprecated', 'link', 'see', 'since'] + ['deprecated', 'link', 'see', 'since'], ], - 'skip_unlisted_annotations' => false + 'skip_unlisted_annotations' => false, ], // Single line @var PHPDoc should have proper spacing. 'phpdoc_single_line_var_spacing' => true, @@ -253,7 +253,7 @@ return new Config() // @var and @type annotations must have type and name in the correct order. 'phpdoc_var_annotation_correct_order' => true, // @var and @type annotations of classy properties should not contain the name. - 'phpdoc_var_without_name' => true + 'phpdoc_var_without_name' => true, ]) ->setFinder($finder) ->setParallelConfig(Runner\Parallel\ParallelConfigFactory::detect()); diff --git a/.phpactor.json b/.phpactor.json index 3d74f9af..05f1edd9 100755 --- a/.phpactor.json +++ b/.phpactor.json @@ -10,7 +10,7 @@ "language_server.diagnostics_on_save": true, "language_server.diagnostics_on_update": true, "language_server_highlight.enabled": true, - "language_server_php_cs_fixer.enabled": true, + "language_server_php_cs_fixer.enabled": false, "language_server_phpstan.config": "phpstan.neon", "language_server_phpstan.enabled": true, "language_server_psalm.enabled": false, diff --git a/bun.lock b/bun.lock index c4ccd2c9..889275b5 100644 --- a/bun.lock +++ b/bun.lock @@ -17,12 +17,12 @@ "devDependencies": { "@effect/language-service": "^0.84.3", "@gcch/configuration-eslint": "git+https://git.gcch.fr/gcch/configuration-eslint#62ee424274", - "@gcch/configuration-oxlint": "git+https://git.gcch.fr/gcch/configuration-oxlint#c53b1c1f78", + "@gcch/configuration-oxlint": "git+https://git.gcch.fr/gcch/configuration-oxlint#93dd909919", "@gcch/configuration-prettier": "git+https://git.gcch.fr/gcch/configuration-prettier#8de937e801", "@playwright/test": "^1.59.1", "@sentry/core": "^10.47.0", "@types/bun": "^1.3.11", - "@types/node": "^25.5.0", + "@types/node": "^25.5.1", "@vitejs/plugin-legacy": "^8.0.1", "better-typescript-lib": "^2.12.0", "browserslist": "^4.28.2", @@ -36,7 +36,7 @@ "fdir": "^6.5.0", "globals": "^17.4.0", "jiti": "^2.6.1", - "knip": "^6.1.1", + "knip": "^6.3.0", "lightningcss": "^1.32.0", "lightningcss-cli": "^1.32.0", "oxlint": "^1.58.0", @@ -45,7 +45,7 @@ "prettier": "^3.8.1", "prettier-plugin-pkg": "^0.22.1", "prettier-plugin-sh": "^0.18.0", - "sass-embedded": "^1.98.0", + "sass-embedded": "^1.99.0", "stylelint": "^17.6.0", "stylelint-config-clean-order": "^8.0.1", "stylelint-config-sass-guidelines": "^13.0.0", @@ -268,11 +268,11 @@ "@effect/language-service": ["@effect/language-service@0.84.3", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-zpxi6rLCwst/cBQd7ElwDvt36Y6Jvz8v6bCLnNiOL6OXvdLmqjOFWyzWZdMh92vvBQA/aVKhfIAAOP3o4wKt0A=="], - "@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="], + "@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], - "@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="], + "@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], - "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="], + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], "@es-joy/jsdoccomment": ["@es-joy/jsdoccomment@0.86.0", "", { "dependencies": { "@types/estree": "^1.0.8", "@typescript-eslint/types": "^8.58.0", "comment-parser": "1.4.6", "esquery": "^1.7.0", "jsdoc-type-pratt-parser": "~7.2.0" } }, "sha512-ukZmRQ81WiTpDWO6D/cTBM7XbrNtutHKvAVnZN/8pldAwLoJArGOvkNyxPTBGsPjsoaQBJxlH+tE2TNA/92Qgw=="], @@ -296,7 +296,7 @@ "@gcch/configuration-eslint": ["@gcch/configuration-eslint@git+https://git.gcch.fr/gcch/configuration-eslint#62ee424274f0bfebd5135a728960644f4b1cdcb8", { "dependencies": { "@eslint/js": "^10.0.1", "astro-eslint-parser": "^1.3.0", "eslint": "^10.0.3", "eslint-plugin-astro": "^1.6.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsdoc": "^62.8.0", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-perfectionist": "^5.6.0", "eslint-plugin-sonarjs": "^4.0.2", "eslint-plugin-unicorn": "^63.0.0", "globals": "^17.4.0", "typescript-eslint": "^8.57.0" }, "peerDependencies": { "eslint": "^10.0.3", "typescript": "^6.0.1-rc" } }, "62ee424274f0bfebd5135a728960644f4b1cdcb8"], - "@gcch/configuration-oxlint": ["@gcch/configuration-oxlint@git+https://git.gcch.fr/gcch/configuration-oxlint#c53b1c1f78ab2ac790cf7d3d8d22810e440a47e9", { "dependencies": { "globals": "^17.4.0", "oxlint": "^1.58.0", "oxlint-tsgolint": "^0.19.0" }, "optionalDependencies": { "eslint-plugin-astro": "^1.6.0" }, "peerDependencies": { "eslint-plugin-astro": "^1.6.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-perfectionist": "^5.7.0", "eslint-plugin-sonarjs": "^4.0.2", "oxlint": "^1.58.0", "oxlint-tsgolint": "^0.19.0", "typescript": "^6.0.2" } }, "c53b1c1f78ab2ac790cf7d3d8d22810e440a47e9"], + "@gcch/configuration-oxlint": ["@gcch/configuration-oxlint@git+https://git.gcch.fr/gcch/configuration-oxlint#93dd9099199603d2fe2c334227e8051104b8f1a0", { "dependencies": { "globals": "^17.4.0", "oxlint": "^1.58.0", "oxlint-tsgolint": "^0.19.0" }, "optionalDependencies": { "eslint-plugin-astro": "^1.6.0" }, "peerDependencies": { "eslint-plugin-astro": "^1.6.0", "eslint-plugin-functional": "^9.0.4", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-perfectionist": "^5.7.0", "eslint-plugin-sonarjs": "^4.0.2", "oxlint": "^1.58.0", "oxlint-tsgolint": "^0.19.0", "typescript": "^6.0.2" } }, "93dd9099199603d2fe2c334227e8051104b8f1a0"], "@gcch/configuration-prettier": ["@gcch/configuration-prettier@git+https://git.gcch.fr/gcch/configuration-prettier#8de937e801bd44784ac91e0ff6e038d838f7eea1", { "dependencies": { "prettier": "^3.8.1", "prettier-plugin-curly": "^0.4.1", "prettier-plugin-ini": "^1.3.0", "prettier-plugin-jsdoc": "^1.8.0", "prettier-plugin-pkg": "^0.22.0", "prettier-plugin-sh": "^0.18.0", "prettier-plugin-sort-json": "^4.2.0" }, "peerDependencies": { "prettier": "^3.8.1" } }, "8de937e801bd44784ac91e0ff6e038d838f7eea1"], @@ -580,7 +580,7 @@ "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], - "@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], + "@types/node": ["@types/node@25.5.2", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg=="], "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], @@ -798,7 +798,7 @@ "effect": ["effect@4.0.0-beta.43", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.5.3", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.8", "multipasta": "^0.2.7", "toml": "^3.0.0", "uuid": "^13.0.0", "yaml": "^2.8.2" } }, "sha512-AJYyDimIwJOn87uUz/JzmgDc5GfjxJbXvEbTvNzMa+M3Uer344bLo/O5mMRkqc1vBleA+Ygs4+dbE3QsqOkKTQ=="], - "electron-to-chromium": ["electron-to-chromium@1.5.330", "", {}, "sha512-jFNydB5kFtYUobh4IkWUnXeyDbjf/r9gcUEXe1xcrcUxIGfTdzPXA+ld6zBRbwvgIGVzDll/LTIiDztEtckSnA=="], + "electron-to-chromium": ["electron-to-chromium@1.5.331", "", {}, "sha512-IbxXrsTlD3hRodkLnbxAPP4OuJYdWCeM3IOdT+CpcMoIwIoDfCmRpEtSPfwBXxVkg9xmBeY7Lz2Eo2TDn/HC3Q=="], "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], @@ -1076,7 +1076,7 @@ "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], - "knip": ["knip@6.2.0", "", { "dependencies": { "@nodelib/fs.walk": "^1.2.3", "fast-glob": "^3.3.3", "formatly": "^0.3.0", "get-tsconfig": "4.13.7", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.121.0", "oxc-resolver": "^11.19.1", "picocolors": "^1.1.1", "picomatch": "^4.0.1", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "unbash": "^2.2.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-4OMUMJARvNble8e8TeFv12flp4fKzAITrQec1eKO4g2eA4HnNqEa8CXy2UOPLjuYuAETpe0N0r25jF9yY9FLig=="], + "knip": ["knip@6.3.0", "", { "dependencies": { "@nodelib/fs.walk": "^1.2.3", "fast-glob": "^3.3.3", "formatly": "^0.3.0", "get-tsconfig": "4.13.7", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-parser": "^0.121.0", "oxc-resolver": "^11.19.1", "picocolors": "^1.1.1", "picomatch": "^4.0.1", "smol-toml": "^1.6.1", "strip-json-comments": "5.0.3", "unbash": "^2.2.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-g6dVPoTw6iNm3cubC5IWxVkVsd0r5hXhTBTbAGIEQN53GdA2ZM/slMTPJ7n5l8pBebNQPHpxjmKxuR4xVQ2/hQ=="], "known-css-properties": ["known-css-properties@0.37.0", "", {}, "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ=="], @@ -1232,7 +1232,7 @@ "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="], - "node-releases": ["node-releases@2.0.36", "", {}, "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA=="], + "node-releases": ["node-releases@2.0.37", "", {}, "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg=="], "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], @@ -1380,45 +1380,45 @@ "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="], - "sass": ["sass@1.98.0", "", { "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.1.5", "source-map-js": ">=0.6.2 <2.0.0" }, "optionalDependencies": { "@parcel/watcher": "^2.4.1" }, "bin": { "sass": "sass.js" } }, "sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A=="], + "sass": ["sass@1.99.0", "", { "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.1.5", "source-map-js": ">=0.6.2 <2.0.0" }, "optionalDependencies": { "@parcel/watcher": "^2.4.1" }, "bin": { "sass": "sass.js" } }, "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q=="], - "sass-embedded": ["sass-embedded@1.98.0", "", { "dependencies": { "@bufbuild/protobuf": "^2.5.0", "colorjs.io": "^0.5.0", "immutable": "^5.1.5", "rxjs": "^7.4.0", "supports-color": "^8.1.1", "sync-child-process": "^1.0.2", "varint": "^6.0.0" }, "optionalDependencies": { "sass-embedded-all-unknown": "1.98.0", "sass-embedded-android-arm": "1.98.0", "sass-embedded-android-arm64": "1.98.0", "sass-embedded-android-riscv64": "1.98.0", "sass-embedded-android-x64": "1.98.0", "sass-embedded-darwin-arm64": "1.98.0", "sass-embedded-darwin-x64": "1.98.0", "sass-embedded-linux-arm": "1.98.0", "sass-embedded-linux-arm64": "1.98.0", "sass-embedded-linux-musl-arm": "1.98.0", "sass-embedded-linux-musl-arm64": "1.98.0", "sass-embedded-linux-musl-riscv64": "1.98.0", "sass-embedded-linux-musl-x64": "1.98.0", "sass-embedded-linux-riscv64": "1.98.0", "sass-embedded-linux-x64": "1.98.0", "sass-embedded-unknown-all": "1.98.0", "sass-embedded-win32-arm64": "1.98.0", "sass-embedded-win32-x64": "1.98.0" }, "bin": { "sass": "dist/bin/sass.js" } }, "sha512-Do7u6iRb6K+lrllcTkB1BXcHwOxcKe3rEfOF/GcCLE2w3WpddakRAosJOHFUR37DpsvimQXEt5abs3NzUjEIqg=="], + "sass-embedded": ["sass-embedded@1.99.0", "", { "dependencies": { "@bufbuild/protobuf": "^2.5.0", "colorjs.io": "^0.5.0", "immutable": "^5.1.5", "rxjs": "^7.4.0", "supports-color": "^8.1.1", "sync-child-process": "^1.0.2", "varint": "^6.0.0" }, "optionalDependencies": { "sass-embedded-all-unknown": "1.99.0", "sass-embedded-android-arm": "1.99.0", "sass-embedded-android-arm64": "1.99.0", "sass-embedded-android-riscv64": "1.99.0", "sass-embedded-android-x64": "1.99.0", "sass-embedded-darwin-arm64": "1.99.0", "sass-embedded-darwin-x64": "1.99.0", "sass-embedded-linux-arm": "1.99.0", "sass-embedded-linux-arm64": "1.99.0", "sass-embedded-linux-musl-arm": "1.99.0", "sass-embedded-linux-musl-arm64": "1.99.0", "sass-embedded-linux-musl-riscv64": "1.99.0", "sass-embedded-linux-musl-x64": "1.99.0", "sass-embedded-linux-riscv64": "1.99.0", "sass-embedded-linux-x64": "1.99.0", "sass-embedded-unknown-all": "1.99.0", "sass-embedded-win32-arm64": "1.99.0", "sass-embedded-win32-x64": "1.99.0" }, "bin": { "sass": "dist/bin/sass.js" } }, "sha512-gF/juR1aX02lZHkvwxdF80SapkQeg2fetoDF6gIQkNbSw5YEUFspMkyGTjPjgZSgIHuZpy+Wz4PlebKnLXMjdg=="], - "sass-embedded-all-unknown": ["sass-embedded-all-unknown@1.98.0", "", { "dependencies": { "sass": "1.98.0" }, "cpu": [ "!arm", "!x64", "!arm64", ] }, "sha512-6n4RyK7/1mhdfYvpP3CClS3fGoYqDvRmLClCESS6I7+SAzqjxvGG6u5Fo+cb1nrPNbbilgbM4QKdgcgWHO9NCA=="], + "sass-embedded-all-unknown": ["sass-embedded-all-unknown@1.99.0", "", { "dependencies": { "sass": "1.99.0" }, "cpu": [ "!arm", "!x64", "!arm64", ] }, "sha512-qPIRG8Uhjo6/OKyAKixTnwMliTz+t9K6Duk0mx5z+K7n0Ts38NSJz2sjDnc7cA/8V9Lb3q09H38dZ1CLwD+ssw=="], - "sass-embedded-android-arm": ["sass-embedded-android-arm@1.98.0", "", { "os": "android", "cpu": "arm" }, "sha512-LjGiMhHgu7VL1n7EJxTCre1x14bUsWd9d3dnkS2rku003IWOI/fxc7OXgaKagoVzok1kv09rzO3vFXJR5ZeONQ=="], + "sass-embedded-android-arm": ["sass-embedded-android-arm@1.99.0", "", { "os": "android", "cpu": "arm" }, "sha512-EHvJ0C7/VuP78Qr6f8gIUVUmCqIorEQpw2yp3cs3SMg02ZuumlhjXvkTcFBxHmFdFR23vTNk1WnhY6QSeV1nFQ=="], - "sass-embedded-android-arm64": ["sass-embedded-android-arm64@1.98.0", "", { "os": "android", "cpu": "arm64" }, "sha512-M9Ra98A6vYJHpwhoC/5EuH1eOshQ9ZyNwC8XifUDSbRl/cGeQceT1NReR9wFj3L7s1pIbmes1vMmaY2np0uAKQ=="], + "sass-embedded-android-arm64": ["sass-embedded-android-arm64@1.99.0", "", { "os": "android", "cpu": "arm64" }, "sha512-fNHhdnP23yqqieCbAdym4N47AleSwjbNt6OYIYx4DdACGdtERjQB4iOX/TaKsW034MupfF7SjnAAK8w7Ptldtg=="], - "sass-embedded-android-riscv64": ["sass-embedded-android-riscv64@1.98.0", "", { "os": "android", "cpu": "none" }, "sha512-WPe+0NbaJIZE1fq/RfCZANMeIgmy83x4f+SvFOG7LhUthHpZWcOcrPTsCKKmN3xMT3iw+4DXvqTYOCYGRL3hcQ=="], + "sass-embedded-android-riscv64": ["sass-embedded-android-riscv64@1.99.0", "", { "os": "android", "cpu": "none" }, "sha512-4zqDFRvgGDTL5vTHuIhRxUpXFoh0Cy7Gm5Ywk19ASd8Settmd14YdPRZPmMxfgS1GH292PofV1fq1ifiSEJWBw=="], - "sass-embedded-android-x64": ["sass-embedded-android-x64@1.98.0", "", { "os": "android", "cpu": "x64" }, "sha512-zrD25dT7OHPEgLWuPEByybnIfx4rnCtfge4clBgjZdZ3lF6E7qNLRBtSBmoFflh6Vg0RlEjJo5VlpnTMBM5MQQ=="], + "sass-embedded-android-x64": ["sass-embedded-android-x64@1.99.0", "", { "os": "android", "cpu": "x64" }, "sha512-Uk53k/dGYt04RjOL4gFjZ0Z9DH9DKh8IA8WsXUkNqsxerAygoy3zqRBS2zngfE9K2jiOM87q+1R1p87ory9oQQ=="], - "sass-embedded-darwin-arm64": ["sass-embedded-darwin-arm64@1.98.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-cgr1z9rBnCdMf8K+JabIaYd9Rag2OJi5mjq08XJfbJGMZV/TA6hFJCLGkr5/+ZOn4/geTM5/3aSfQ8z5EIJAOg=="], + "sass-embedded-darwin-arm64": ["sass-embedded-darwin-arm64@1.99.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-u61/7U3IGLqoO6gL+AHeiAtlTPFwJK1+964U8gp45ZN0hzh1yrARf5O1mivXv8NnNgJvbG2wWJbiNZP0lG/lTg=="], - "sass-embedded-darwin-x64": ["sass-embedded-darwin-x64@1.98.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-OLBOCs/NPeiMqTdOrMFbVHBQFj19GS3bSVSxIhcCq16ZyhouUkYJEZjxQgzv9SWA2q6Ki8GCqp4k6jMeUY9dcA=="], + "sass-embedded-darwin-x64": ["sass-embedded-darwin-x64@1.99.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-j/kkk/NcXdIameLezSfXjgCiBkVcA+G60AXrX768/3g0miK1g7M9dj7xOhCb1i7/wQeiEI3rw2LLuO63xRIn4A=="], - "sass-embedded-linux-arm": ["sass-embedded-linux-arm@1.98.0", "", { "os": "linux", "cpu": "arm" }, "sha512-03baQZCxVyEp8v1NWBRlzGYrmVT/LK7ZrHlF1piscGiGxwfdxoLXVuxsylx3qn/dD/4i/rh7Bzk7reK1br9jvQ=="], + "sass-embedded-linux-arm": ["sass-embedded-linux-arm@1.99.0", "", { "os": "linux", "cpu": "arm" }, "sha512-d4IjJZrX2+AwB2YCy1JySwdptJECNP/WfAQLUl8txI3ka8/d3TUI155GtelnoZUkio211PwIeFvvAeZ9RXPQnw=="], - "sass-embedded-linux-arm64": ["sass-embedded-linux-arm64@1.98.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-axOE3t2MTBwCtkUCbrdM++Gj0gC0fdHJPrgzQ+q1WUmY9NoNMGqflBtk5mBZaWUeha2qYO3FawxCB8lctFwCtw=="], + "sass-embedded-linux-arm64": ["sass-embedded-linux-arm64@1.99.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-btNcFpItcB56L40n8hDeL7sRSMLDXQ56nB5h2deddJx1n60rpKSElJmkaDGHtpkrY+CTtDRV0FZDjHeTJddYew=="], - "sass-embedded-linux-musl-arm": ["sass-embedded-linux-musl-arm@1.98.0", "", { "os": "linux", "cpu": "arm" }, "sha512-OBkjTDPYR4hSaueOGIM6FDpl9nt/VZwbSRpbNu9/eEJcxE8G/vynRugW8KRZmCFjPy8j/jkGBvvS+k9iOqKV3g=="], + "sass-embedded-linux-musl-arm": ["sass-embedded-linux-musl-arm@1.99.0", "", { "os": "linux", "cpu": "arm" }, "sha512-2gvHOupgIw3ytatXT4nFUow71LFbuOZPEwG+HUzcNQDH8ue4Ez8cr03vsv5MDv3lIjOKcXwDvWD980t18MwkoQ=="], - "sass-embedded-linux-musl-arm64": ["sass-embedded-linux-musl-arm64@1.98.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-LeqNxQA8y4opjhe68CcFvMzCSrBuJqYVFbwElEj9bagHXQHTp9xVPJRn6VcrC+0VLEDq13HVXMv7RslIuU0zmA=="], + "sass-embedded-linux-musl-arm64": ["sass-embedded-linux-musl-arm64@1.99.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Hi2bt/IrM5P4FBKz6EcHAlniwfpoz9mnTdvSd58y+avA3SANM76upIkAdSayA8ZGwyL3gZokru1AKDPF9lJDNw=="], - "sass-embedded-linux-musl-riscv64": ["sass-embedded-linux-musl-riscv64@1.98.0", "", { "os": "linux", "cpu": "none" }, "sha512-7w6hSuOHKt8FZsmjRb3iGSxEzM87fO9+M8nt5JIQYMhHTj5C+JY/vcske0v715HCVj5e1xyTnbGXf8FcASeAIw=="], + "sass-embedded-linux-musl-riscv64": ["sass-embedded-linux-musl-riscv64@1.99.0", "", { "os": "linux", "cpu": "none" }, "sha512-mKqGvVaJ9rHMqyZsF0kikQe4NO0f4osb67+X6nLhBiVDKvyazQHJ3zJQreNefIE36yL2sjHIclSB//MprzaQDg=="], - "sass-embedded-linux-musl-x64": ["sass-embedded-linux-musl-x64@1.98.0", "", { "os": "linux", "cpu": "x64" }, "sha512-QikNyDEJOVqPmxyCFkci8ZdCwEssdItfjQFJB+D+Uy5HFqcS5Lv3d3GxWNX/h1dSb23RPyQdQc267ok5SbEyJw=="], + "sass-embedded-linux-musl-x64": ["sass-embedded-linux-musl-x64@1.99.0", "", { "os": "linux", "cpu": "x64" }, "sha512-huhgOMmOc30r7CH7qbRbT9LerSEGSnWuS4CYNOskr9BvNeQp4dIneFufNRGZ7hkOAxUM8DglxIZJN/cyAT95Ew=="], - "sass-embedded-linux-riscv64": ["sass-embedded-linux-riscv64@1.98.0", "", { "os": "linux", "cpu": "none" }, "sha512-E7fNytc/v4xFBQKzgzBddV/jretA4ULAPO6XmtBiQu4zZBdBozuSxsQLe2+XXeb0X4S2GIl72V7IPABdqke/vA=="], + "sass-embedded-linux-riscv64": ["sass-embedded-linux-riscv64@1.99.0", "", { "os": "linux", "cpu": "none" }, "sha512-mevFPIFAVhrH90THifxLfOntFmHtcEKOcdWnep2gJ0X4DVva4AiVIRlQe/7w9JFx5+gnDRE1oaJJkzuFUuYZsA=="], - "sass-embedded-linux-x64": ["sass-embedded-linux-x64@1.98.0", "", { "os": "linux", "cpu": "x64" }, "sha512-VsvP0t/uw00mMNPv3vwyYKUrFbqzxQHnRMO+bHdAMjvLw4NFf6mscpym9Bzf+NXwi1ZNKnB6DtXjmcpcvqFqYg=="], + "sass-embedded-linux-x64": ["sass-embedded-linux-x64@1.99.0", "", { "os": "linux", "cpu": "x64" }, "sha512-9k7IkULqIZdCIVt4Mboryt6vN8Mjmm3EhI1P3mClU5y5i3wLK5ExC3cbVWk047KsID/fvB1RLslqghXJx5BoxA=="], - "sass-embedded-unknown-all": ["sass-embedded-unknown-all@1.98.0", "", { "dependencies": { "sass": "1.98.0" }, "os": [ "!linux", "!win32", "!darwin", "!android", ] }, "sha512-C4MMzcAo3oEDQnW7L8SBgB9F2Fq5qHPnaYTZRMOH3Mp/7kM4OooBInXpCiiFjLnjY95hzP4KyctVx0uYR6MYlQ=="], + "sass-embedded-unknown-all": ["sass-embedded-unknown-all@1.99.0", "", { "dependencies": { "sass": "1.99.0" }, "os": [ "!linux", "!win32", "!darwin", "!android", ] }, "sha512-P7MxiUtL/XzGo3PX0CaB8lNNEFLQWKikPA8pbKytx9ZCLZSDkt2NJcdAbblB/sqMs4AV3EK2NadV8rI/diq3xg=="], - "sass-embedded-win32-arm64": ["sass-embedded-win32-arm64@1.98.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-nP/10xbAiPbhQkMr3zQfXE4TuOxPzWRQe1Hgbi90jv2R4TbzbqQTuZVOaJf7KOAN4L2Bo6XCTRjK5XkVnwZuwQ=="], + "sass-embedded-win32-arm64": ["sass-embedded-win32-arm64@1.99.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8whpsW7S+uO8QApKfQuc36m3P9EISzbVZOgC79goob4qGy09u8Gz/rYvw8h1prJDSjltpHGhOzBE6LDz7WvzVw=="], - "sass-embedded-win32-x64": ["sass-embedded-win32-x64@1.98.0", "", { "os": "win32", "cpu": "x64" }, "sha512-/lbrVsfbcbdZQ5SJCWcV0NVPd6YRs+FtAnfedp4WbCkO/ZO7Zt/58MvI4X2BVpRY/Nt5ZBo1/7v2gYcQ+J4svQ=="], + "sass-embedded-win32-x64": ["sass-embedded-win32-x64@1.99.0", "", { "os": "win32", "cpu": "x64" }, "sha512-ipuOv1R2K4MHeuCEAZGpuUbAgma4gb0sdacyrTjJtMOy/OY9UvWfVlwErdB09KIkp4fPDpQJDJfvYN6bC8jeNg=="], "scslre": ["scslre@0.3.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.8.0", "refa": "^0.12.0", "regexp-ast-analysis": "^0.7.0" } }, "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ=="], @@ -1632,8 +1632,6 @@ "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], - "@gcch/configuration-eslint/eslint-plugin-perfectionist": ["eslint-plugin-perfectionist@5.7.0", "", { "dependencies": { "@typescript-eslint/utils": "^8.57.1", "natural-orderby": "^5.0.0" }, "peerDependencies": { "eslint": "^8.45.0 || ^9.0.0 || ^10.0.0" } }, "sha512-WRHj7OZS/INutQ/gKN5C1ZGnMhkQ3oKZQAA2I7rl5yM8keBtSd9oj/qlJaHuwh5873FhMPqYlttcadF0YsTN7g=="], - "@keyv/bigmap/keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="], "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], diff --git a/composer.json b/composer.json index afd82bbf..a108182d 100755 --- a/composer.json +++ b/composer.json @@ -53,11 +53,10 @@ ], "require": { "php": ">=8.5", - "php-standard-library/php-standard-library": "^4.3", "composer/installers": "^2.3", "crell/fp": "^1.0", "htmlburger/carbon-fields": "^3.6.9", - "illuminate/support": "^12.56", + "illuminate/support": "^13.3", "laravel/helpers": "^1.8.3", "log1x/wp-smtp": "^1.0.2", "lstrojny/functional-php": "^1.18", @@ -67,9 +66,10 @@ "roots/bedrock-autoloader": "^1.1.0", "roots/bedrock-disallow-indexing": "^2.1", "roots/wordpress": "^6.9.4", + "php-standard-library/php-standard-library": "^6.1.1", "roots/wp-config": "^1.0", "stripe/stripe-php": "^19.4.1", - "symfony/uid": "^8.0.4", + "symfony/uid": "^8.0.8", "timber/timber": "^2.3.3", "vlucas/phpdotenv": "^5.6.3", "wpackagist-plugin/falcon": "^2.9.3", @@ -78,7 +78,7 @@ "wpackagist-plugin/redis-cache": "^2.7.0", "wpackagist-plugin/wc-multishipping": "^3.0.2", "wpackagist-plugin/woo-preview-emails": "^2.2.14", - "wpackagist-plugin/woocommerce": "^10.6.1", + "wpackagist-plugin/woocommerce": "^10.6.2", "wpackagist-plugin/wp-mail-logging": "^1.16.0", "wpackagist-plugin/wp-mail-smtp": "^4.7.1", "wpackagist-plugin/wp-openapi": "^1.0.27", @@ -88,7 +88,7 @@ "friendsofphp/php-cs-fixer": "^3.94.2", "php-standard-library/phpstan-extension": "^2.1", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.45", + "phpstan/phpstan": "^2.1.46", "roave/security-advisories": "dev-latest", "szepeviktor/phpstan-wordpress": "2.x-dev", "vincentlanglet/twig-cs-fixer": "^3.14" diff --git a/composer.lock b/composer.lock index a885c6e4..fcf3835a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d29045fefbe0199423856ab6ff3d9888", + "content-hash": "8fa8994b91f6fdfb99db59a67eb54ac5", "packages": [ { "name": "carbonphp/carbon-doctrine-types", @@ -585,35 +585,34 @@ }, { "name": "illuminate/collections", - "version": "v12.56.0", + "version": "v13.3.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "83313b009c4afb6f02dbc090bdb67809756eefa2" + "reference": "389c5008087f8c48d35b85585b4315107b5a0f9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/83313b009c4afb6f02dbc090bdb67809756eefa2", - "reference": "83313b009c4afb6f02dbc090bdb67809756eefa2", + "url": "https://api.github.com/repos/illuminate/collections/zipball/389c5008087f8c48d35b85585b4315107b5a0f9e", + "reference": "389c5008087f8c48d35b85585b4315107b5a0f9e", "shasum": "" }, "require": { - "illuminate/conditionable": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "php": "^8.2", - "symfony/polyfill-php83": "^1.33", + "illuminate/conditionable": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "php": "^8.3", "symfony/polyfill-php84": "^1.33", "symfony/polyfill-php85": "^1.33" }, "suggest": { - "illuminate/http": "Required to convert collections to API resources (^12.0).", - "symfony/var-dumper": "Required to use the dump method (^7.2)." + "illuminate/http": "Required to convert collections to API resources (^13.0).", + "symfony/var-dumper": "Required to use the dump method (^7.4 || ^8.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "autoload": { @@ -641,29 +640,29 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-03-11T14:13:25+00:00" + "time": "2026-03-30T19:06:46+00:00" }, { "name": "illuminate/conditionable", - "version": "v12.56.0", + "version": "v13.3.0", "source": { "type": "git", "url": "https://github.com/illuminate/conditionable.git", - "reference": "ec677967c1f2faf90b8428919124d2184a4c9b49" + "reference": "7f1ef52d9a346f829421b296adfb7644a951b216" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/conditionable/zipball/ec677967c1f2faf90b8428919124d2184a4c9b49", - "reference": "ec677967c1f2faf90b8428919124d2184a4c9b49", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/7f1ef52d9a346f829421b296adfb7644a951b216", + "reference": "7f1ef52d9a346f829421b296adfb7644a951b216", "shasum": "" }, "require": { - "php": "^8.2" + "php": "^8.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "autoload": { @@ -687,31 +686,31 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-05-13T15:08:45+00:00" + "time": "2026-02-25T16:07:55+00:00" }, { "name": "illuminate/contracts", - "version": "v12.56.0", + "version": "v13.3.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "099fd9b56ccaf776facaa27699b960a3f2451127" + "reference": "8796cc5f30124b81210ae2f3b2ae0f69ad4fc7f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/099fd9b56ccaf776facaa27699b960a3f2451127", - "reference": "099fd9b56ccaf776facaa27699b960a3f2451127", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/8796cc5f30124b81210ae2f3b2ae0f69ad4fc7f8", + "reference": "8796cc5f30124b81210ae2f3b2ae0f69ad4fc7f8", "shasum": "" }, "require": { - "php": "^8.2", - "psr/container": "^1.1.1|^2.0.1", - "psr/simple-cache": "^1.0|^2.0|^3.0" + "php": "^8.3", + "psr/container": "^1.1.1 || ^2.0.1", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "autoload": { @@ -735,20 +734,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-02-20T14:37:40+00:00" + "time": "2026-03-26T17:13:01+00:00" }, { "name": "illuminate/macroable", - "version": "v12.56.0", + "version": "v13.3.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", - "reference": "e862e5648ee34004fa56046b746f490dfa86c613" + "reference": "f108cb3a8680f26e23c6ce7367c64525412d85b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/macroable/zipball/e862e5648ee34004fa56046b746f490dfa86c613", - "reference": "e862e5648ee34004fa56046b746f490dfa86c613", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/f108cb3a8680f26e23c6ce7367c64525412d85b0", + "reference": "f108cb3a8680f26e23c6ce7367c64525412d85b0", "shasum": "" }, "require": { @@ -757,7 +756,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "autoload": { @@ -781,31 +780,31 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-07-23T16:31:01+00:00" + "time": "2026-03-28T19:16:13+00:00" }, { "name": "illuminate/reflection", - "version": "v12.56.0", + "version": "v13.3.0", "source": { "type": "git", "url": "https://github.com/illuminate/reflection.git", - "reference": "348cf5da9de89b596d7723be6425fb048e2bf4bb" + "reference": "4fe1659f068ab2b50131cf906c5d8bba4e34df0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/reflection/zipball/348cf5da9de89b596d7723be6425fb048e2bf4bb", - "reference": "348cf5da9de89b596d7723be6425fb048e2bf4bb", + "url": "https://api.github.com/repos/illuminate/reflection/zipball/4fe1659f068ab2b50131cf906c5d8bba4e34df0c", + "reference": "4fe1659f068ab2b50131cf906c5d8bba4e34df0c", "shasum": "" }, "require": { - "illuminate/collections": "^12.0", - "illuminate/contracts": "^12.0", - "php": "^8.2" + "illuminate/collections": "^13.0", + "illuminate/contracts": "^13.0", + "php": "^8.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "autoload": { @@ -832,20 +831,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-02-25T15:25:18+00:00" + "time": "2026-03-10T20:04:12+00:00" }, { "name": "illuminate/support", - "version": "v12.56.0", + "version": "v13.3.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "cd8a3c5a95501b9ae0828ac785b5af5ffccdca45" + "reference": "f31e168e236a90d96d7894cd1f107b1ba095de69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/cd8a3c5a95501b9ae0828ac785b5af5ffccdca45", - "reference": "cd8a3c5a95501b9ae0828ac785b5af5ffccdca45", + "url": "https://api.github.com/repos/illuminate/support/zipball/f31e168e236a90d96d7894cd1f107b1ba095de69", + "reference": "f31e168e236a90d96d7894cd1f107b1ba095de69", "shasum": "" }, "require": { @@ -853,14 +852,13 @@ "ext-ctype": "*", "ext-filter": "*", "ext-mbstring": "*", - "illuminate/collections": "^12.0", - "illuminate/conditionable": "^12.0", - "illuminate/contracts": "^12.0", - "illuminate/macroable": "^12.0", - "illuminate/reflection": "^12.0", + "illuminate/collections": "^13.0", + "illuminate/conditionable": "^13.0", + "illuminate/contracts": "^13.0", + "illuminate/macroable": "^13.0", + "illuminate/reflection": "^13.0", "nesbot/carbon": "^3.8.4", - "php": "^8.2", - "symfony/polyfill-php83": "^1.33", + "php": "^8.3", "symfony/polyfill-php85": "^1.33", "voku/portable-ascii": "^2.0.2" }, @@ -871,20 +869,20 @@ "spatie/once": "*" }, "suggest": { - "illuminate/filesystem": "Required to use the Composer class (^12.0).", - "laravel/serializable-closure": "Required to use the once function (^1.3|^2.0).", + "illuminate/filesystem": "Required to use the Composer class (^13.0).", + "laravel/serializable-closure": "Required to use the once function (^2.0.10).", "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.7).", "league/uri": "Required to use the Uri class (^7.5.1).", "ramsey/uuid": "Required to use Str::uuid() (^4.7).", - "symfony/process": "Required to use the Composer class (^7.2).", - "symfony/uid": "Required to use Str::ulid() (^7.2).", - "symfony/var-dumper": "Required to use the dd function (^7.2).", + "symfony/process": "Required to use the Composer class (^7.4 || ^8.0).", + "symfony/uid": "Required to use Str::ulid() (^7.4 || ^8.0).", + "symfony/var-dumper": "Required to use the dd function (^7.4 || ^8.0).", "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.6.1)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "12.x-dev" + "dev-master": "13.0.x-dev" } }, "autoload": { @@ -912,7 +910,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-03-17T13:55:49+00:00" + "time": "2026-03-30T13:32:27+00:00" }, { "name": "laravel/helpers", @@ -1382,16 +1380,16 @@ }, { "name": "php-standard-library/php-standard-library", - "version": "4.3.0", + "version": "6.1.1", "source": { "type": "git", "url": "https://github.com/php-standard-library/php-standard-library.git", - "reference": "74c95be0214eb7ea39146ed00ac4eb71b45d787b" + "reference": "b7d151cb1c21589cdde17a6adff50d3375de0919" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-standard-library/php-standard-library/zipball/74c95be0214eb7ea39146ed00ac4eb71b45d787b", - "reference": "74c95be0214eb7ea39146ed00ac4eb71b45d787b", + "url": "https://api.github.com/repos/php-standard-library/php-standard-library/zipball/b7d151cb1c21589cdde17a6adff50d3375de0919", + "reference": "b7d151cb1c21589cdde17a6adff50d3375de0919", "shasum": "" }, "require": { @@ -1399,16 +1397,88 @@ "ext-intl": "*", "ext-json": "*", "ext-mbstring": "*", + "ext-openssl": "*", "ext-sodium": "*", - "php": "~8.3.0 || ~8.4.0 || ~8.5.0", - "revolt/event-loop": "^1.0.7" + "php": "~8.4.0 || ~8.5.0", + "revolt/event-loop": "^1.0.8" + }, + "conflict": { + "azjezz/psl": "*" + }, + "replace": { + "php-standard-library/ansi": "self.version", + "php-standard-library/async": "self.version", + "php-standard-library/binary": "self.version", + "php-standard-library/cache": "self.version", + "php-standard-library/channel": "self.version", + "php-standard-library/cidr": "self.version", + "php-standard-library/class": "self.version", + "php-standard-library/collection": "self.version", + "php-standard-library/comparison": "self.version", + "php-standard-library/compression": "self.version", + "php-standard-library/crypto": "self.version", + "php-standard-library/data-structure": "self.version", + "php-standard-library/date-time": "self.version", + "php-standard-library/default": "self.version", + "php-standard-library/dict": "self.version", + "php-standard-library/either": "self.version", + "php-standard-library/encoding": "self.version", + "php-standard-library/env": "self.version", + "php-standard-library/file": "self.version", + "php-standard-library/filesystem": "self.version", + "php-standard-library/foundation": "self.version", + "php-standard-library/fun": "self.version", + "php-standard-library/graph": "self.version", + "php-standard-library/h2": "self.version", + "php-standard-library/hash": "self.version", + "php-standard-library/hpack": "self.version", + "php-standard-library/html": "self.version", + "php-standard-library/interface": "self.version", + "php-standard-library/interoperability": "self.version", + "php-standard-library/io": "self.version", + "php-standard-library/ip": "self.version", + "php-standard-library/iri": "self.version", + "php-standard-library/iter": "self.version", + "php-standard-library/json": "self.version", + "php-standard-library/locale": "self.version", + "php-standard-library/math": "self.version", + "php-standard-library/network": "self.version", + "php-standard-library/observer": "self.version", + "php-standard-library/option": "self.version", + "php-standard-library/os": "self.version", + "php-standard-library/password": "self.version", + "php-standard-library/process": "self.version", + "php-standard-library/promise": "self.version", + "php-standard-library/pseudo-random": "self.version", + "php-standard-library/punycode": "self.version", + "php-standard-library/random-sequence": "self.version", + "php-standard-library/range": "self.version", + "php-standard-library/regex": "self.version", + "php-standard-library/result": "self.version", + "php-standard-library/runtime": "self.version", + "php-standard-library/secure-random": "self.version", + "php-standard-library/shell": "self.version", + "php-standard-library/socks": "self.version", + "php-standard-library/str": "self.version", + "php-standard-library/tcp": "self.version", + "php-standard-library/terminal": "self.version", + "php-standard-library/tls": "self.version", + "php-standard-library/trait": "self.version", + "php-standard-library/tree": "self.version", + "php-standard-library/type": "self.version", + "php-standard-library/udp": "self.version", + "php-standard-library/unix": "self.version", + "php-standard-library/uri": "self.version", + "php-standard-library/url": "self.version", + "php-standard-library/vec": "self.version" }, "require-dev": { - "carthage-software/mago": "^1.6.0", - "infection/infection": "^0.31.2", - "php-coveralls/php-coveralls": "^2.7.0", - "phpbench/phpbench": "^1.4.0", - "phpunit/phpunit": "^9.6.22" + "carthage-software/mago": "^1.15.2", + "ext-brotli": "*", + "infection/infection": "^0.32.6", + "php-coveralls/php-coveralls": "^2.9.1", + "phpbench/phpbench": "^1.5.1", + "phpunit/phpunit": "^13.0.5" }, "suggest": { "php-standard-library/phpstan-extension": "PHPStan integration", @@ -1416,17 +1486,132 @@ }, "type": "library", "extra": { - "thanks": { - "url": "https://github.com/hhvm/hsl", - "name": "hhvm/hsl" + "branch-alias": { + "dev-next": "6.1.x-dev" } }, "autoload": { "files": [ - "src/bootstrap.php" + "packages/foundation/src/Psl/bootstrap.php", + "packages/ansi/src/Psl/bootstrap.php", + "packages/async/src/Psl/bootstrap.php", + "packages/binary/src/Psl/bootstrap.php", + "packages/cache/src/Psl/bootstrap.php", + "packages/channel/src/Psl/bootstrap.php", + "packages/class/src/Psl/bootstrap.php", + "packages/comparison/src/Psl/bootstrap.php", + "packages/compression/src/Psl/bootstrap.php", + "packages/crypto/src/Psl/bootstrap.php", + "packages/date-time/src/Psl/bootstrap.php", + "packages/dict/src/Psl/bootstrap.php", + "packages/encoding/src/Psl/bootstrap.php", + "packages/env/src/Psl/bootstrap.php", + "packages/file/src/Psl/bootstrap.php", + "packages/filesystem/src/Psl/bootstrap.php", + "packages/fun/src/Psl/bootstrap.php", + "packages/graph/src/Psl/bootstrap.php", + "packages/h2/src/Psl/bootstrap.php", + "packages/hash/src/Psl/bootstrap.php", + "packages/hpack/src/Psl/bootstrap.php", + "packages/html/src/Psl/bootstrap.php", + "packages/interface/src/Psl/bootstrap.php", + "packages/io/src/Psl/bootstrap.php", + "packages/iter/src/Psl/bootstrap.php", + "packages/json/src/Psl/bootstrap.php", + "packages/math/src/Psl/bootstrap.php", + "packages/network/src/Psl/bootstrap.php", + "packages/option/src/Psl/bootstrap.php", + "packages/os/src/Psl/bootstrap.php", + "packages/password/src/Psl/bootstrap.php", + "packages/pseudo-random/src/Psl/bootstrap.php", + "packages/punycode/src/Psl/bootstrap.php", + "packages/range/src/Psl/bootstrap.php", + "packages/regex/src/Psl/bootstrap.php", + "packages/result/src/Psl/bootstrap.php", + "packages/runtime/src/Psl/bootstrap.php", + "packages/secure-random/src/Psl/bootstrap.php", + "packages/shell/src/Psl/bootstrap.php", + "packages/socks/src/Psl/bootstrap.php", + "packages/str/src/Psl/bootstrap.php", + "packages/tcp/src/Psl/bootstrap.php", + "packages/terminal/src/Psl/bootstrap.php", + "packages/tls/src/Psl/bootstrap.php", + "packages/trait/src/Psl/bootstrap.php", + "packages/tree/src/Psl/bootstrap.php", + "packages/type/src/Psl/bootstrap.php", + "packages/udp/src/Psl/bootstrap.php", + "packages/unix/src/Psl/bootstrap.php", + "packages/uri/src/Psl/bootstrap.php", + "packages/url/src/Psl/bootstrap.php", + "packages/iri/src/Psl/bootstrap.php", + "packages/vec/src/Psl/bootstrap.php" ], "psr-4": { - "Psl\\": "src/Psl" + "Psl\\": "packages/foundation/src/Psl/", + "Psl\\H2\\": "packages/h2/src/Psl/H2/", + "Psl\\IO\\": "packages/io/src/Psl/IO/", + "Psl\\IP\\": "packages/ip/src/Psl/IP/", + "Psl\\OS\\": "packages/os/src/Psl/OS/", + "Psl\\Env\\": "packages/env/src/Psl/Env/", + "Psl\\Fun\\": "packages/fun/src/Psl/Fun/", + "Psl\\IRI\\": "packages/iri/src/Psl/IRI/", + "Psl\\Str\\": "packages/str/src/Psl/Str/", + "Psl\\TCP\\": "packages/tcp/src/Psl/TCP/", + "Psl\\TLS\\": "packages/tls/src/Psl/TLS/", + "Psl\\UDP\\": "packages/udp/src/Psl/UDP/", + "Psl\\URI\\": "packages/uri/src/Psl/URI/", + "Psl\\URL\\": "packages/url/src/Psl/URL/", + "Psl\\Vec\\": "packages/vec/src/Psl/Vec/", + "Psl\\Ansi\\": "packages/ansi/src/Psl/Ansi/", + "Psl\\CIDR\\": "packages/cidr/src/Psl/CIDR/", + "Psl\\Dict\\": "packages/dict/src/Psl/Dict/", + "Psl\\File\\": "packages/file/src/Psl/File/", + "Psl\\Hash\\": "packages/hash/src/Psl/Hash/", + "Psl\\Html\\": "packages/html/src/Psl/Html/", + "Psl\\Iter\\": "packages/iter/src/Psl/Iter/", + "Psl\\Json\\": "packages/json/src/Psl/Json/", + "Psl\\Math\\": "packages/math/src/Psl/Math/", + "Psl\\Tree\\": "packages/tree/src/Psl/Tree/", + "Psl\\Type\\": "packages/type/src/Psl/Type/", + "Psl\\Unix\\": "packages/unix/src/Psl/Unix/", + "Psl\\Async\\": "packages/async/src/Psl/Async/", + "Psl\\Cache\\": "packages/cache/src/Psl/Cache/", + "Psl\\Class\\": "packages/class/src/Psl/Class/", + "Psl\\Graph\\": "packages/graph/src/Psl/Graph/", + "Psl\\HPACK\\": "packages/hpack/src/Psl/HPACK/", + "Psl\\Range\\": "packages/range/src/Psl/Range/", + "Psl\\Regex\\": "packages/regex/src/Psl/Regex/", + "Psl\\Shell\\": "packages/shell/src/Psl/Shell/", + "Psl\\Socks\\": "packages/socks/src/Psl/Socks/", + "Psl\\Trait\\": "packages/trait/src/Psl/Trait/", + "Psl\\Binary\\": "packages/binary/src/Psl/Binary/", + "Psl\\Crypto\\": "packages/crypto/src/Psl/Crypto/", + "Psl\\Either\\": "packages/either/src/Psl/Either/", + "Psl\\Locale\\": "packages/locale/src/Psl/Locale/", + "Psl\\Option\\": "packages/option/src/Psl/Option/", + "Psl\\Result\\": "packages/result/src/Psl/Result/", + "Psl\\Channel\\": "packages/channel/src/Psl/Channel/", + "Psl\\Default\\": "packages/default/src/Psl/Default/", + "Psl\\Network\\": "packages/network/src/Psl/Network/", + "Psl\\Process\\": "packages/process/src/Psl/Process/", + "Psl\\Promise\\": "packages/promise/src/Psl/Promise/", + "Psl\\Runtime\\": "packages/runtime/src/Psl/Runtime/", + "Psl\\DateTime\\": "packages/date-time/src/Psl/DateTime/", + "Psl\\Encoding\\": "packages/encoding/src/Psl/Encoding/", + "Psl\\Observer\\": "packages/observer/src/Psl/Observer/", + "Psl\\Password\\": "packages/password/src/Psl/Password/", + "Psl\\Punycode\\": "packages/punycode/src/Psl/Punycode/", + "Psl\\Terminal\\": "packages/terminal/src/Psl/Terminal/", + "Psl\\Interface\\": "packages/interface/src/Psl/Interface/", + "Psl\\Collection\\": "packages/collection/src/Psl/Collection/", + "Psl\\Comparison\\": "packages/comparison/src/Psl/Comparison/", + "Psl\\Filesystem\\": "packages/filesystem/src/Psl/Filesystem/", + "Psl\\Compression\\": "packages/compression/src/Psl/Compression/", + "Psl\\PseudoRandom\\": "packages/pseudo-random/src/Psl/PseudoRandom/", + "Psl\\SecureRandom\\": "packages/secure-random/src/Psl/SecureRandom/", + "Psl\\DataStructure\\": "packages/data-structure/src/Psl/DataStructure/", + "Psl\\RandomSequence\\": "packages/random-sequence/src/Psl/RandomSequence/", + "Psl\\Interoperability\\": "packages/interoperability/src/Psl/Interoperability/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1442,7 +1627,7 @@ "description": "PHP Standard Library", "support": { "issues": "https://github.com/php-standard-library/php-standard-library/issues", - "source": "https://github.com/php-standard-library/php-standard-library/tree/4.3.0" + "source": "https://github.com/php-standard-library/php-standard-library/tree/6.1.1" }, "funding": [ { @@ -1454,7 +1639,7 @@ "type": "github" } ], - "time": "2026-02-24T01:58:53+00:00" + "time": "2026-03-20T08:09:20+00:00" }, { "name": "phpoption/phpoption", @@ -2571,86 +2756,6 @@ ], "time": "2025-01-02T08:10:11+00:00" }, - { - "name": "symfony/polyfill-php83", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php83\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2025-07-08T02:45:35+00:00" - }, { "name": "symfony/polyfill-php84", "version": "v1.33.0", @@ -5024,12 +5129,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "61130731cdf896e60028ed82193a1bc3c50d032a" + "reference": "958bc6ccdb194912236265e4f36256e55bb0c9da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/61130731cdf896e60028ed82193a1bc3c50d032a", - "reference": "61130731cdf896e60028ed82193a1bc3c50d032a", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/958bc6ccdb194912236265e4f36256e55bb0c9da", + "reference": "958bc6ccdb194912236265e4f36256e55bb0c9da", "shasum": "" }, "conflict": { @@ -5080,9 +5185,9 @@ "aureuserp/aureuserp": "<1.3.0.0-beta1", "austintoddj/canvas": "<=3.4.2", "auth0/auth0-php": ">=3.3,<=8.18", - "auth0/login": "<7.20", - "auth0/symfony": "<=5.5", - "auth0/wordpress": "<=5.4", + "auth0/login": "<=7.20", + "auth0/symfony": "<=5.7", + "auth0/wordpress": "<=5.5", "automad/automad": "<2.0.0.0-alpha5", "automattic/jetpack": "<9.8", "avideo/avideo": "<=26", @@ -6066,7 +6171,7 @@ "type": "tidelift" } ], - "time": "2026-04-02T00:32:12+00:00" + "time": "2026-04-03T04:48:53+00:00" }, { "name": "sebastian/diff", @@ -7378,5 +7483,5 @@ "php": ">=8.5" }, "platform-dev": {}, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } diff --git a/containers/conf/php.ini b/containers/conf/php.ini index d65098bf..06ffdc5f 100755 --- a/containers/conf/php.ini +++ b/containers/conf/php.ini @@ -1,10 +1,13 @@ -allow_url_fopen=0 -allow_url_include=0 -cgi.fix_pathinfo=0 -display_errors=0 -display_startup_errors=0 -expose_php=0 +allow_url_fopen=Off +allow_url_include=Off +cgi.fix_pathinfo=Off +display_errors=On +display_startup_errors=On +expose_php=Off file_uploads=On +html_errors=On +error_prepend_string="
"
+error_append_string="
" max_execution_time=600 max_input_time=600 max_input_vars=2000 diff --git a/justfile b/justfile index b7cc1afd..90fd2f49 100755 --- a/justfile +++ b/justfile @@ -27,7 +27,7 @@ format: # TwigCsFixher -vendor/bin/twig-cs-fixer fix web/app/themes/haiku-atelier-2024/ # PhpCsFixer - -vendor/bin/php-cs-fixer fix --allow-risky yes + # -vendor/bin/php-cs-fixer fix --allow-risky yes dprint --config "~/.config/dprint/dprint.jsonc" fmt fish scripts/format-sort-files.fish diff --git a/package.json b/package.json index 5f11e702..a91ed454 100755 --- a/package.json +++ b/package.json @@ -23,12 +23,12 @@ "devDependencies": { "@effect/language-service": "^0.84.3", "@gcch/configuration-eslint": "git+https://git.gcch.fr/gcch/configuration-eslint#62ee424274", - "@gcch/configuration-oxlint": "git+https://git.gcch.fr/gcch/configuration-oxlint#c53b1c1f78", + "@gcch/configuration-oxlint": "git+https://git.gcch.fr/gcch/configuration-oxlint#93dd909919", "@gcch/configuration-prettier": "git+https://git.gcch.fr/gcch/configuration-prettier#8de937e801", "@playwright/test": "^1.59.1", "@sentry/core": "^10.47.0", "@types/bun": "^1.3.11", - "@types/node": "^25.5.0", + "@types/node": "^25.5.1", "@vitejs/plugin-legacy": "^8.0.1", "better-typescript-lib": "^2.12.0", "browserslist": "^4.28.2", @@ -42,7 +42,7 @@ "fdir": "^6.5.0", "globals": "^17.4.0", "jiti": "^2.6.1", - "knip": "^6.1.1", + "knip": "^6.3.0", "lightningcss": "^1.32.0", "lightningcss-cli": "^1.32.0", "oxlint": "^1.58.0", @@ -51,7 +51,7 @@ "prettier": "^3.8.1", "prettier-plugin-pkg": "^0.22.1", "prettier-plugin-sh": "^0.18.0", - "sass-embedded": "^1.98.0", + "sass-embedded": "^1.99.0", "stylelint": "^17.6.0", "stylelint-config-clean-order": "^8.0.1", "stylelint-config-sass-guidelines": "^13.0.0", diff --git a/scripts/pull-container-images.ts b/scripts/pull-container-images.ts index 2be6b24a..f3b47da6 100644 --- a/scripts/pull-container-images.ts +++ b/scripts/pull-container-images.ts @@ -1,40 +1,63 @@ -import { BunFile, YAML } from "bun"; -import { Array, Console, Effect, Option, pipe, Record, Schema } from "effect"; -import { type UnknownException } from "effect/Cause"; -import { type ParseError } from "effect/ParseResult"; +import { YAML } from "bun"; +import { Array as EffectArray, Console, Data, Effect, pipe, Record, Schema, SchemaIssue } from "effect"; +import { NoSuchElementError } from "effect/Cause"; import { type ReadonlyRecord } from "effect/Record"; +import { SchemaError } from "effect/Schema"; const COMPOSE_PATH = "compose.yaml"; -const getServicesKey = (yaml: ReadonlyRecord): Option.Option> => +class ScriptError extends Data.TaggedError("ScriptError")<{ cause: unknown }> {} + +const ComposeSchema = Schema.Record(Schema.Union([Schema.String, Schema.Symbol]), Schema.Any); + +type ComposeYaml = ReadonlyRecord; + +const getObjectKey = (key: string, yaml: ComposeYaml): Effect.Effect, ScriptError> => pipe( - Record.get("services")(yaml), - Option.andThen((yaml) => Record.keys(yaml)), + Record.get(key)(yaml), + Effect.fromOption, + Effect.map((yaml: any) => Record.keys(yaml)), + Effect.mapError((e: NoSuchElementError) => new ScriptError({ cause: e })), ); -const getComposeYaml = ( - filePath: string, - schema: Schema.Schema, -): Effect.Effect => - pipe( - Effect.try(() => Bun.file(filePath)), - Effect.andThen((file: BunFile) => Effect.tryPromise(() => file.text())), - Effect.andThen((text: string) => Effect.try(() => YAML.parse(text))), - Effect.andThen((yaml: unknown) => Schema.decodeUnknown(schema)(yaml)), - ); +const getFileContent = Effect.fn("getFileContent")(function* (filePath: string) { + const fileRef = Bun.file(filePath); -const programEffect: Effect.Effect> = Effect.gen(function* () { - return yield* pipe( - // Récupère le contenu du fichier compose.yaml sous forme de Record. - getComposeYaml(COMPOSE_PATH, Schema.Record({ key: Schema.String, value: Schema.Unknown })), - // Récupère la clé des services. - Effect.andThen((yaml: ReadonlyRecord) => getServicesKey(yaml)), - // Retire la clé de l'image WordPress. - Effect.andThen((keys: ReadonlyArray) => Array.filter(keys, (key) => key !== "wordpress")), - Effect.orElseSucceed(() => [""]), - // Exécute la commande podman. - Effect.tap((services) => Bun.spawn({ cmd: ["podman", "compose", "pull", ...services], timeout: 10000 })), - ); + yield* Effect.tryPromise({ + try: () => fileRef.exists(), + catch: (_) => new ScriptError({ cause: "The wanted file does not exist." }), + }); + + return yield* Effect.tryPromise({ + try: () => fileRef.text(), + catch: (_) => new ScriptError({ cause: "Can't retrieve the file's text content." }), + }); }); -Effect.runFork(programEffect).pipe(Effect.tapErrorCause(Console.error)); +const getComposeYaml = (filePath: string, schema: Schema.Schema) => + pipe( + getFileContent(filePath), + Effect.map((text: string) => YAML.parse(text)), + Effect.flatMap((yaml: unknown) => Schema.decodeUnknownEffect(schema)(yaml, { errors: "all" })), + Effect.mapError((error) => { + if (error instanceof SchemaError) { + return new ScriptError({ cause: SchemaIssue.makeFormatterStandardSchemaV1()(error.issue) }); + } else { + return error; + } + }), + ); + +const program: Effect.Effect, ScriptError> = pipe( + getComposeYaml(COMPOSE_PATH, ComposeSchema), + Effect.flatMap((yaml: ComposeYaml) => getObjectKey("services", yaml)), + Effect.map((keys: ReadonlyArray) => EffectArray.filter(keys, (key) => key !== "wordpress")), + Effect.orElseSucceed(() => [""]), + Effect.tap((services: ReadonlyArray) => { + Bun.spawn({ cmd: ["podman", "compose", "pull", ...services], timeout: 10000 }); + return Effect.succeed(services); + }), + Effect.tapCause(Console.error), +); + +Effect.runFork(program); diff --git a/tests/playwright/utils.ts b/tests/playwright/utils.ts index eb151d08..0c12dda9 100644 --- a/tests/playwright/utils.ts +++ b/tests/playwright/utils.ts @@ -11,7 +11,7 @@ export type BackendHeaders = { */ export const getBackendHeadersFromHtml = async (page: Page): Promise => { const backendHeaders: BackendHeaders | undefined = pipe( - Option.fromNullable(await page.locator("#injection-v2").textContent()), + Option.fromNullishOr(await page.locator("#injection-v2").textContent()), Option.andThen((j) => JSON.parse(j) as BackendHeaders), Option.getOrUndefined, ); diff --git a/web/app/themes/haiku-atelier-2024/404.php b/web/app/themes/haiku-atelier-2024/404.php index b51659ba..cc280047 100755 --- a/web/app/themes/haiku-atelier-2024/404.php +++ b/web/app/themes/haiku-atelier-2024/404.php @@ -25,7 +25,7 @@ $templates = ['404.twig']; function load_page_resources(): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-a-propos', - path: '/assets/css/pages/page-modele-simple.css' + path: '/assets/css/pages/page-modele-simple.css', ); } @@ -33,5 +33,5 @@ add_action('wp_enqueue_scripts', load_page_resources(...)); Timber::render( data: $context, - filenames: $templates + filenames: $templates, ); diff --git a/web/app/themes/haiku-atelier-2024/archive-product.php b/web/app/themes/haiku-atelier-2024/archive-product.php index 8aac03b1..6e6c7788 100755 --- a/web/app/themes/haiku-atelier-2024/archive-product.php +++ b/web/app/themes/haiku-atelier-2024/archive-product.php @@ -28,7 +28,7 @@ $wc_products = wc_get_products(['limit' => 12, 'order' => 'DESC', 'orderby' => ' $products = array_map( callback: Product::new(...), - array: $wc_products + array: $wc_products, ); $context['products'] = $products; @@ -40,15 +40,15 @@ $context['products'] = $products; function load_page_resources(): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-boutique', - path: '/assets/css/pages/page-boutique.css' + path: '/assets/css/pages/page-boutique.css', ); Resource::enqueue_script_module_file( id: 'haiku-atelier-2024-scripts-page-boutique', - path: '/assets/js/scripts-page-boutique.js' + path: '/assets/js/scripts-page-boutique.js', ); Resource::enqueue_script_module_file( id: 'haiku-atelier-2024-scripts-menu-categories', - path: '/assets/js/scripts-menu-categories.js' + path: '/assets/js/scripts-menu-categories.js', ); } @@ -56,5 +56,5 @@ add_action('wp_enqueue_scripts', load_page_resources(...)); Timber::render( data: $context, - filenames: $templates + filenames: $templates, ); diff --git a/web/app/themes/haiku-atelier-2024/front-page.php b/web/app/themes/haiku-atelier-2024/front-page.php index 714fc96d..bcf1a730 100755 --- a/web/app/themes/haiku-atelier-2024/front-page.php +++ b/web/app/themes/haiku-atelier-2024/front-page.php @@ -22,20 +22,20 @@ $templates = ['accueil.twig']; * * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger */ -function load_resources(): void { +function load_page_resources(): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-accueil', - path: '/assets/css/pages/page-accueil.css' + path: '/assets/css/pages/page-accueil.css', ); Resource::enqueue_script_module_file( id: 'haiku-atelier-2024-scripts-page-accueil', - path: '/assets/js/scripts-page-accueil.js' + path: '/assets/js/scripts-page-accueil.js', ); } -add_action('wp_enqueue_scripts', load_resources(...)); +add_action('wp_enqueue_scripts', load_page_resources(...)); Timber::render( data: $context, - filenames: $templates + filenames: $templates, ); diff --git a/web/app/themes/haiku-atelier-2024/functions.php b/web/app/themes/haiku-atelier-2024/functions.php index f99c8d9a..824e9e0d 100755 --- a/web/app/themes/haiku-atelier-2024/functions.php +++ b/web/app/themes/haiku-atelier-2024/functions.php @@ -33,19 +33,19 @@ function load_scripts(): void { id: 'haiku-atelier-2024-bouton-panier', deps: [], src: get_template_directory_uri() . '/assets/js/scripts-bouton-panier.js', - version: filemtime(get_template_directory() . '/assets/js/scripts-bouton-panier.js') + version: filemtime(get_template_directory() . '/assets/js/scripts-bouton-panier.js'), ); wp_enqueue_script_module( id: 'haiku-atelier-2024-menu-mobile', deps: [], src: get_template_directory_uri() . '/assets/js/scripts-menu-mobile.js', - version: filemtime(get_template_directory() . '/assets/js/scripts-menu-mobile.js') + version: filemtime(get_template_directory() . '/assets/js/scripts-menu-mobile.js'), ); wp_enqueue_script_module( id: 'haiku-atelier-2024-bouton-retour-sommet', deps: [], src: get_template_directory_uri() . '/assets/js/scripts-bouton-retour-sommet.js', - version: filemtime(get_template_directory() . '/assets/js/scripts-bouton-retour-sommet.js') + version: filemtime(get_template_directory() . '/assets/js/scripts-bouton-retour-sommet.js'), ); } @@ -58,7 +58,7 @@ function charge_styles_haiku_atelier_2024(): void { src: get_template_directory_uri() . '/assets/css/main.css', deps: [], ver: filemtime(get_template_directory() . '/assets/css/main.css'), - media: 'all' + media: 'all', ); } @@ -74,7 +74,7 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void { // Section « Réseaux sociaux » $wp_customize->add_section('liens_reseaux_sociaux', [ 'title' => __('Liens des réseaux sociaux'), - 'description' => __("Liens des réseaux sociaux s'affichant dans le pied de page.") + 'description' => __("Liens des réseaux sociaux s'affichant dans le pied de page."), ]); // Instagram @@ -82,7 +82,7 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void { $wp_customize->add_control('lien_instagram', [ 'type' => 'url', 'section' => 'liens_reseaux_sociaux', - 'label' => __('Profil Instagram') + 'label' => __('Profil Instagram'), ]); // Facebook @@ -90,7 +90,7 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void { $wp_customize->add_control('lien_facebook', [ 'type' => 'url', 'section' => 'liens_reseaux_sociaux', - 'label' => __('Profil Facebook') + 'label' => __('Profil Facebook'), ]); // Pinterest @@ -98,13 +98,13 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void { $wp_customize->add_control('lien_pinterest', [ 'type' => 'url', 'section' => 'liens_reseaux_sociaux', - 'label' => __('Profil Pinterest') + 'label' => __('Profil Pinterest'), ]); // Section « Descriptions Produits » $wp_customize->add_section('descriptions_produits', [ 'title' => __('Textes des descriptions Produits'), - 'description' => __('Textes des descriptions apparaissant sur les pages Produit.') + 'description' => __('Textes des descriptions apparaissant sur les pages Produit.'), ]); $wp_customize->add_setting('texte_conditions_livraison', [ @@ -112,7 +112,7 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void { 'default' => '', 'sanitize_callback' => 'wp_kses_post', 'transport' => 'postMessage', - 'type' => 'theme_mod' + 'type' => 'theme_mod', ]); $wp_customize->add_control(new Controle_Personnalise_TinyMCE($wp_customize, 'texte_conditions_livraison', [ 'label' => __('Conditions de livraison'), @@ -120,8 +120,8 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void { 'section' => 'descriptions_produits', 'input_attrs' => [ 'toolbar1' => 'bold italic bullist numlist alignleft aligncenter alignright link', - 'mediaButtons' => true - ] + 'mediaButtons' => true, + ], ])); $wp_customize->add_setting('texte_entretien_produit', [ @@ -129,7 +129,7 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void { 'default' => '', 'sanitize_callback' => 'wp_kses_post', 'transport' => 'postMessage', - 'type' => 'theme_mod' + 'type' => 'theme_mod', ]); $wp_customize->add_control(new Controle_Personnalise_TinyMCE($wp_customize, 'texte_entretien_produit', [ 'label' => __('Entretien du Produit'), @@ -137,8 +137,8 @@ function enregistre_personnalisations_theme(mixed $wp_customize): void { 'section' => 'descriptions_produits', 'input_attrs' => [ 'toolbar1' => 'bold italic bullist numlist alignleft aligncenter alignright link', - 'mediaButtons' => true - ] + 'mediaButtons' => true, + ], ])); } diff --git a/web/app/themes/haiku-atelier-2024/index.php b/web/app/themes/haiku-atelier-2024/index.php index c39a88f9..c31016a1 100755 --- a/web/app/themes/haiku-atelier-2024/index.php +++ b/web/app/themes/haiku-atelier-2024/index.php @@ -9,5 +9,5 @@ $templates = ['base.twig']; Timber::render( data: $context, - filenames: $templates + filenames: $templates, ); diff --git a/web/app/themes/haiku-atelier-2024/page-about.php b/web/app/themes/haiku-atelier-2024/page-about.php index e45b2fcd..c57e6c1b 100755 --- a/web/app/themes/haiku-atelier-2024/page-about.php +++ b/web/app/themes/haiku-atelier-2024/page-about.php @@ -34,20 +34,20 @@ $context['image_dimensions'] = $image_dimensions; * * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger */ -function load_resources(): void { +function load_page_resources(): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-a-propos', - path: '/assets/css/pages/page-a-propos.css' + path: '/assets/css/pages/page-a-propos.css', ); Resource::enqueue_script_module_file( id: 'haiku-atelier-2024-scripts-page-a-propos', - path: '/assets/js/scripts-page-a-propos.js' + path: '/assets/js/scripts-page-a-propos.js', ); } -add_action('wp_enqueue_scripts', load_resources(...)); +add_action('wp_enqueue_scripts', load_page_resources(...)); Timber::render( data: $context, - filenames: $templates + filenames: $templates, ); diff --git a/web/app/themes/haiku-atelier-2024/page-cart.php b/web/app/themes/haiku-atelier-2024/page-cart.php index 2c96bd2f..6fe3b726 100755 --- a/web/app/themes/haiku-atelier-2024/page-cart.php +++ b/web/app/themes/haiku-atelier-2024/page-cart.php @@ -9,127 +9,47 @@ declare(strict_types=1); namespace HaikuAtelier; use Exception; +use HaikuAtelier\Data\Cart; use HaikuAtelier\WP\Resource; use Illuminate\Support\Number; use Timber\Timber; +use WC_Shipping_Rate; use function add_action; use function collect; use function Crell\fp\pipe; -use function filemtime; use function genere_balise_img_multiformats; -use function get_template_directory; -use function get_template_directory_uri; -use function is_bool; use function recupere_et_formate_attributs_produit; use function WC; -use function wp_enqueue_script_module; -use function wp_enqueue_style; // Importe la fonction pour récupérer les informations affichées des Produits dans le Panier require_once __DIR__ . '/src/inc/TraitementInformations.php'; -// Contexte et modèles -$contexte = Timber::context(); -$modeles = ['panier.twig']; - -$allowed_countries = [ - 'AD', - 'AL', - 'AM', - 'AR', - 'AT', - 'AU', - 'BA', - 'BE', - 'BG', - 'BR', - 'CA', - 'CH', - 'CL', - 'CR', - 'CU', - 'CY', - 'CZ', - 'DE', - 'DK', - 'DZ', - 'EE', - 'EG', - 'ES', - 'FI', - 'FR', - 'GF', - 'GP', - 'GR', - 'HR', - 'HU', - 'IE', - 'IS', - 'IT', - 'JP', - 'KR', - 'LB', - 'LI', - 'LT', - 'LU', - 'LV', - 'MA', - 'MD', - 'ME', - 'MF', - 'MQ', - 'MT', - 'MX', - 'NC', - 'NL', - 'NO', - 'NZ', - 'PF', - 'PL', - 'PM', - 'PS', - 'PT', - 'RE', - 'RO', - 'SE', - 'SI', - 'SK', - 'SM', - 'TN', - 'TR', - 'TW', - 'US', - 'YT', - 'ZA' -]; +$context = Timber::context(); +$templates = ['panier.twig']; // Récupère les informations affichés des Produits du Panier $cart = []; -/** Le sous-total de la Commande dans le Panier. */ -$cart_subtotal = WC()->cart->get_subtotal(); +/** @var array */ +$cart_totals = WC()->cart->get_totals(); /** @var string|null $promo_code Le code promo appliqué au Panier s'il existe. */ $promo_code = collect(WC()->cart->get_applied_coupons())->first(); -/** @var array */ -$cart_totals = WC()->cart->get_totals(); +/** Le sous-total de la Commande dans le Panier. */ +$cart_subtotal = Cart::parse_cart_value($cart_totals['subtotal'] ?? 0); -/** @var string $cart_subtotal_with_discount Le total du montant de la Réduction appliquée au Panier. */ -$cart_subtotal_with_discount = $cart_totals['discount_total'] - |> (static fn(int $number) => Number::format($number, maxPrecision: 2)) - |> (static fn(false|string $number) => is_bool($number) ? '0' : $number); -/** @var float $cart_total Le total de la Commande dans le Panier. */ -$cart_total = $cart_totals['total'] - |> (static fn(int $number) => Number::format($number, maxPrecision: 2)) - |> (static fn(false|string $number) => is_bool($number) ? '0' : $number) - |> (static fn(string $number) => (float) $number); -/** @var string $shipping_subtotal Le sous-total de la livraison. */ -$shipping_subtotal = $cart_totals['shipping_total'] - |> (static fn(int $number) => Number::format($number, precision: 0)) - |> (static fn(false|string $number) => is_bool($number) ? '0' : $number); +/** Le total du montant de la Réduction appliquée au Panier. */ +$cart_subtotal_with_discount = Cart::parse_cart_value($cart_totals['discount_total'] ?? 0); +/** Le total de la Commande dans le Panier. */ +$cart_total = Cart::parse_cart_value($cart_totals['total'] ?? 0); + +/** Le sous-total de la livraison. */ +$shipping_subtotal = Cart::parse_cart_value($cart_totals['shipping_total'] ?? 0); + +// TODO: Nettoyer ça. foreach (WC()->cart->get_cart() as $cle_panier => $article_panier) { $cart[$cle_panier] = [ 'attributs' => $article_panier['data']?->get_type() === 'variation' @@ -140,12 +60,12 @@ foreach (WC()->cart->get_cart() as $cle_panier => $article_panier) { 'id_variation' => $article_panier['variation_id'], 'image' => pipe($article_panier['data']?->get_image_id(), static fn($id): string => genere_balise_img_multiformats( id: (string) $id, - lazy: true + lazy: true, )), 'prix' => $article_panier['data']?->get_price(), 'quantite' => $article_panier['quantity'], 'url' => $article_panier['data']?->get_permalink(), - 'titre' => $article_panier['data']?->get_title() + 'titre' => $article_panier['data']?->get_title(), ]; } @@ -154,49 +74,51 @@ $email = WC()->customer->get_billing_email(); $adresse_livraison = WC()->customer->get_shipping(); $adresse_facturation = WC()->customer->get_billing(); $adresse_renseignee = $adresse_livraison['city'] !== ''; -$allowed_countries = collect(WC()->countries->get_countries())->only($allowed_countries)->toArray(); +// TODO: Déplacer ça dans une fonction statique de Cart. +$allowed_countries = collect(WC()->countries->get_countries())->only(Cart::get_allowed_countries())->toArray(); +// TODO: Nettoyer ça. $methodes_livraison = collect(WC()->session->get('shipping_for_package_0')['rates']) ->values() ->map(static fn(WC_Shipping_Rate $methode): array => [ 'id' => $methode->get_method_id(), - 'prix' => Number::format((int) $methode->get_cost(), maxPrecision: 2), + 'prix' => Number::format((int) $methode->get_cost(), precision: 2), 'selectionnee' => collect(WC()->session->get('chosen_shipping_methods'))->first() === $methode->get_id(), - 'titre' => $methode->get_label() + 'titre' => $methode->get_label(), ]); -$contexte['email'] = $email; -$contexte['adresse_livraison'] = $adresse_livraison; -$contexte['adresse_facturation'] = $adresse_facturation; -$contexte['adresse_renseignee'] = $adresse_renseignee; -$contexte['sous_total_panier'] = $cart_subtotal; -$contexte['code_promo'] = $promo_code; -$contexte['sous_total_reduction'] = $cart_subtotal_with_discount; -$contexte['total_panier'] = $cart_total; -$contexte['produits_panier'] = $cart; -$contexte['pays_livraison'] = $allowed_countries; -$contexte['sous_total_livraison'] = $shipping_subtotal; -$contexte['methodes_livraison'] = $methodes_livraison; +$context['email'] = $email; +$context['adresse_livraison'] = $adresse_livraison; +$context['adresse_facturation'] = $adresse_facturation; +$context['adresse_renseignee'] = $adresse_renseignee; +$context['sous_total_panier'] = $cart_subtotal; +$context['code_promo'] = $promo_code; +$context['sous_total_reduction'] = $cart_subtotal_with_discount; +$context['total_panier'] = $cart_total; +$context['produits_panier'] = $cart; +$context['pays_livraison'] = $allowed_countries; +$context['sous_total_livraison'] = $shipping_subtotal; +$context['methodes_livraison'] = $methodes_livraison; /** * Charge les scripts et styles de la page. * * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger */ -function load_resources(): void { +function load_page_resources(): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-panier', - path: '/assets/css/pages/page-panier.css' + path: '/assets/css/pages/page-panier.css', ); Resource::enqueue_script_module_file( id: 'haiku-atelier-2024-scripts-page-panier', - path: '/assets/js/scripts-page-panier.js' + path: '/assets/js/scripts-page-panier.js', ); } -add_action('wp_enqueue_scripts', load_resources(...)); +add_action('wp_enqueue_scripts', load_page_resources(...)); // Rendu Timber::render( - filenames: $modeles, - data: $contexte + filenames: $templates, + data: $context, ); diff --git a/web/app/themes/haiku-atelier-2024/page-checkout.php b/web/app/themes/haiku-atelier-2024/page-checkout.php index 71707f1b..fa08f444 100755 --- a/web/app/themes/haiku-atelier-2024/page-checkout.php +++ b/web/app/themes/haiku-atelier-2024/page-checkout.php @@ -1,17 +1,23 @@ session; $urls = [ 'accueil' => get_page_link(get_page_by_path('home')), 'succes_commande' => get_page_link(get_page_by_path('successful-order')), - 'echec_commande' => get_page_link(get_page_by_path('failed-order')) + 'echec_commande' => get_page_link(get_page_by_path('failed-order')), ]; // Redirige à la page d'accueil si le Panier est vide @@ -86,7 +92,7 @@ $articles = collect($panier->get_cart()) . ' (' . explode(': ', (string) $article_panier['data']?->get_attribute_summary())[1] . ')', - false => $article_panier['data']?->get_title() + false => $article_panier['data']?->get_title(), }; return [ @@ -94,11 +100,11 @@ $articles = collect($panier->get_cart()) 'currency' => 'EUR', 'product_data' => [ 'name' => $titre_produit, - 'images' => [wp_get_attachment_image_url($article_panier['data']?->get_image_id())] + 'images' => [wp_get_attachment_image_url($article_panier['data']?->get_image_id())], ], - 'unit_amount' => $article_panier['data']?->get_price() * 100 + 'unit_amount' => $article_panier['data']?->get_price() * 100, ], - 'quantity' => $article_panier['quantity'] + 'quantity' => $article_panier['quantity'], ]; }) ->values() @@ -126,7 +132,7 @@ $coupons_wc = collect(WC()->cart->get_coupons()) 'duration' => get_discount_duration($coupon), 'fixed_cart' === $coupon->get_discount_type() ? 'amount_off' : 'percent_off' => get_discount_amount($coupon), 'id' => $coupon->get_code(), - 'name' => $coupon->get_code() + 'name' => $coupon->get_code(), ]) ->each(static function (array $item) use ($coupons_stripe): void { // Si le code promo n'existe pas, le créer @@ -140,7 +146,7 @@ $reductions_stripe = $coupons_wc ->toArray(); /** @var Session $session_checkout_stripe */ -$session_checkout_stripe = \Stripe\Checkout\Session::create([ +$session_checkout_stripe = Session::create([ 'cancel_url' => $urls['echec_commande'], 'customer_email' => $email_client, 'discounts' => $reductions_stripe, @@ -152,8 +158,8 @@ $session_checkout_stripe = \Stripe\Checkout\Session::create([ 'display_name' => $methode_livraison['nom'], 'fixed_amount' => ['amount' => $methode_livraison['cout'], 'currency' => 'EUR'], 'tax_behavior' => 'inclusive', - 'type' => 'fixed_amount' - ]]] + 'type' => 'fixed_amount', + ]]], ], ['idempotency_key' => Uuid::v4()]); // echo json_encode($session_checkout_stripe); header('HTTP/1.1 303 See Other'); diff --git a/web/app/themes/haiku-atelier-2024/page-contact.php b/web/app/themes/haiku-atelier-2024/page-contact.php index 653d92ad..51004234 100755 --- a/web/app/themes/haiku-atelier-2024/page-contact.php +++ b/web/app/themes/haiku-atelier-2024/page-contact.php @@ -3,30 +3,36 @@ declare(strict_types=1); /** - * Modèle de la Page Contact. + * Modèle de la Page « Contact ». */ +namespace HaikuAtelier; + +use Exception; +use HaikuAtelier\WP\Resource; use Timber\Timber; -// Contexte et modèles -$contexte = Timber::context(); -$modeles = ['contact.twig']; +use function add_action; -// Charge les scripts et styles de la page -function charge_scripts_styles_page_contact(): void { - wp_enqueue_style( +$context = Timber::context(); +$templates = ['contact.twig']; + +/** + * Charge les scripts et styles de la page. + * + * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger + */ +function load_page_resources(): void { + Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-contact', - src: get_template_directory_uri() . '/assets/css/pages/page-modele-simple.css', - deps: [], - ver: filemtime(get_template_directory() . '/assets/css/pages/page-modele-simple.css'), - media: 'all' + path: '/assets/css/pages/page-contact.css', ); } -add_action('wp_enqueue_scripts', 'charge_scripts_styles_page_contact'); +add_action('wp_enqueue_scripts', load_page_resources(...)); // Rendu Timber::render( - filenames: $modeles, - data: $contexte + filenames: $templates, + data: $context, ); diff --git a/web/app/themes/haiku-atelier-2024/page-failed-order.php b/web/app/themes/haiku-atelier-2024/page-failed-order.php index ed31db76..81826e7f 100755 --- a/web/app/themes/haiku-atelier-2024/page-failed-order.php +++ b/web/app/themes/haiku-atelier-2024/page-failed-order.php @@ -1,32 +1,38 @@ empty_cart(); } - // Contexte et modèles - $contexte = Timber::context(); - $modeles = ['succes-commande.twig']; + $context = Timber::context(); + $templates = ['succes-commande.twig']; // Récupère les données des Produits /** @var mixed $produits Les Produits de la Commande sous forme de tableau contenant uniquement les données affichées nécessaires pour le Page. */ @@ -85,16 +89,16 @@ try { 'id_produit' => $id_produit, 'image' => pipe($produit->get_image_id(), static fn($id): string => genere_balise_img_multiformats( id: $id, - lazy: true + lazy: true, )), 'permalien' => $produit->get_permalink(), 'prix' => $produit_commande->get_data()['total'], 'quantite' => $produit_commande->get_quantity(), - 'titre' => $produit->get_title() + 'titre' => $produit->get_title(), ]; }); - $contexte['produits'] = $produits; + $context['produits'] = $produits; // Charge les scripts et styles de la page function charge_scripts_styles_page_succes_commande(): void { @@ -103,7 +107,7 @@ try { src: get_template_directory_uri() . '/assets/css/pages/page-succes-commande.css', deps: [], ver: filemtime(get_template_directory() . '/assets/css/pages/page-succes-commande.css'), - media: 'all' + media: 'all', ); } @@ -111,8 +115,8 @@ try { // Rendu Timber::render( - filenames: $modeles, - data: $contexte + filenames: $templates, + data: $context, ); } catch (Error $error) { http_response_code(500); diff --git a/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php b/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php index 416a1461..d9b9f1ea 100755 --- a/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php +++ b/web/app/themes/haiku-atelier-2024/page-terms-and-conditions.php @@ -6,27 +6,31 @@ declare(strict_types=1); * Le modèle de la Page « Terms & Conditions ». */ +namespace HaikuAtelier; + +use Exception; +use HaikuAtelier\WP\Resource; use Timber\Timber; -// Contexte et modèles -$contexte = Timber::context(); -$modeles = ['cgv.twig']; +$context = Timber::context(); +$templates = ['cgv.twig']; -// Charge les scripts et styles de la page -function charge_scripts_styles_page_cgv(): void { - wp_enqueue_style( - handle: 'haiku-atelier-2024-styles-page-cgv', - src: get_template_directory_uri() . '/assets/css/pages/page-modele-simple.css', - deps: [], - ver: filemtime(get_template_directory() . '/assets/css/pages/page-modele-simple.css'), - media: 'all' +/** + * Charge les scripts et styles de la page. + * + * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger + */ +function load_page_resources(): void { + Resource::enqueue_style_file( + handle: '/assets/css/pages/page-modele-simple.css', + path: '/assets/css/pages/page-modele-simple.css', ); } -add_action('wp_enqueue_scripts', 'charge_scripts_styles_page_cgv'); +add_action('wp_enqueue_scripts', load_page_resources(...)); // Rendu Timber::render( - filenames: $modeles, - data: $contexte + filenames: $templates, + data: $context, ); diff --git a/web/app/themes/haiku-atelier-2024/single-product.php b/web/app/themes/haiku-atelier-2024/single-product.php index 185ee529..6d706129 100755 --- a/web/app/themes/haiku-atelier-2024/single-product.php +++ b/web/app/themes/haiku-atelier-2024/single-product.php @@ -6,33 +6,50 @@ declare(strict_types=1); * Le modèle de la Page d'un Produit. */ -use HaikuAtelier\Data\Product; -use Timber\Timber; +namespace HaikuAtelier; + +use Exception; +use HaikuAtelier\Data\Product; +use HaikuAtelier\WP\Resource; +use Illuminate\Support\Arr; +use stdClass; +use Timber\Timber; +use WC_Product; + +use function add_action; +use function assert; +use function collect; +use function is_array; +use function is_bool; +use function recupere_produits_meme_collection; +use function wc_get_product; +use function wp_json_encode; -require_once __DIR__ . '/src/inc/HTML.php'; require_once __DIR__ . '/src/inc/TraitementInformations.php'; -// Contexte et modèles $context = Timber::context(); $templates = ['produit.twig']; $raw_product = wc_get_product(); // Le Produit DOIT exister. -if ($raw_product === null || is_bool($raw_product)) { +if ($raw_product === null || $raw_product === false) { throw new Exception("Le Produit n'existe pas."); } // Assemble les données d'intérêt pour la page au sein d'une Classe. $product = Product::new($raw_product); -/** @var int $prix_maximal Le prix de la Variation la plus chère */ +/** @var int $maximum_price Le prix de la Variation la plus chère */ $maximum_price = collect($product->variations)->max('price'); -$same_collection_products = array_map( - array: recupere_produits_meme_collection($product->collection)($product->id), - callback: Product::new(...) -); +/** @var list Les Produits de la même collection que celui affiché dans la Page. */ +$same_collection_products = recupere_produits_meme_collection($product->collection)($product->id) + |> function (/** @var list|stdClass */ mixed $products): array { + assert(is_array($products), 'Les Produits de la même collection doivent être un tableau.'); + return $products; + } + |> (static fn(/** @var list */ array $products): array => Arr::map($products, Product::new(...))); $context['product'] = $product; $context['product_json'] = wp_json_encode($product); @@ -40,27 +57,25 @@ $context['maximum_price'] = $maximum_price; $context['same_collection_products'] = $same_collection_products; /** - * Charge les Scripts nécessaires pour la page Produit. + * Charge les scripts et styles de la page. + * + * @throws Exception une exception est levée s'il est impossible d'obtenir la date de modification du fichier à charger */ -function charge_scripts_page_produit(): void { - wp_enqueue_script_module( +function load_page_resources(): void { + Resource::enqueue_script_module_file( id: 'haiku-atelier-2024-scripts-page-produit', - src: get_template_directory_uri() . '/assets/js/scripts-page-produit.js', - deps: [], - version: filemtime(get_template_directory() . '/assets/js/scripts-page-produit.js') + path: '/assets/js/scripts-page-produit.js', ); - wp_enqueue_script_module( + Resource::enqueue_script_module_file( id: 'haiku-atelier-2024-scripts-menu-categories', - src: get_template_directory_uri() . '/assets/js/scripts-menu-categories.js', - deps: [], - version: filemtime(get_template_directory() . '/assets/js/scripts-menu-categories.js') + path: '/assets/js/scripts-menu-categories.js', ); } -add_action('wp_enqueue_scripts', 'charge_scripts_page_produit'); +add_action('wp_enqueue_scripts', load_page_resources(...)); // Rendu Timber::render( filenames: $templates, - data: $context + data: $context, ); diff --git a/web/app/themes/haiku-atelier-2024/src/StarterSite.php b/web/app/themes/haiku-atelier-2024/src/StarterSite.php index a104cf61..5f3fcca0 100755 --- a/web/app/themes/haiku-atelier-2024/src/StarterSite.php +++ b/web/app/themes/haiku-atelier-2024/src/StarterSite.php @@ -54,21 +54,21 @@ final class StarterSite extends Site { $liens_reseaux_sociaux = [ 'facebook' => ['nom' => 'Facebook', 'url' => $personnalisations_theme['lien_facebook'] ?? ''], 'instagram' => ['nom' => 'Instagram', 'url' => $personnalisations_theme['lien_instagram'] ?? ''], - 'pinterest' => ['nom' => 'Pinterest', 'url' => $personnalisations_theme['lien_pinterest'] ?? ''] + 'pinterest' => ['nom' => 'Pinterest', 'url' => $personnalisations_theme['lien_pinterest'] ?? ''], ]; $context['liens_reseaux_sociaux'] = $liens_reseaux_sociaux; // Récupère les textes apparaissant sur les pages Produits $descriptions_produits = [ 'texte_conditions_livraison' => wpautop($personnalisations_theme['texte_conditions_livraison']) ?? '', - 'texte_entretien_produit' => wpautop($personnalisations_theme['texte_entretien_produit']) ?? '' + 'texte_entretien_produit' => wpautop($personnalisations_theme['texte_entretien_produit']) ?? '', ]; $context['descriptions_produits'] = $descriptions_produits; // Logo personnalisée $context['logo'] = pipe(get_theme_mod('custom_logo'), static fn($id) => wp_get_attachment_image_src( attachment_id: $id, - size: 'full' + size: 'full', )); // Informations des Pages @@ -88,7 +88,7 @@ final class StarterSite extends Site { 'failed_order' => $recupere_informations_page('failed_order'), 'home' => $recupere_informations_page('home'), 'shop' => $recupere_informations_page('shop'), - 'successful_order' => $recupere_informations_page('successful_order') + 'successful_order' => $recupere_informations_page('successful_order'), ]; // Récupère la Page courante @@ -96,19 +96,19 @@ final class StarterSite extends Site { $context['page_courante'] = $url_courante; $context['est_page_tous_produits'] = preg_match( pattern: '/(\bshop\b)/', - subject: $url_courante + subject: $url_courante, ); $context['est_page_boutique'] = preg_match( pattern: '/(\bshop\b)/', - subject: $url_courante + subject: $url_courante, ) || preg_match( pattern: '/(\bproduct\b)/', - subject: $url_courante + subject: $url_courante, ) || preg_match( pattern: '/(\bproduct-category\b)/', - subject: $url_courante + subject: $url_courante, ); // Politique de confidentialité @@ -125,15 +125,15 @@ final class StarterSite extends Site { // Détermine si l'URL courante est celle de la Page d'Archive d'une Catégorie de Produits 'courante' => preg_match( pattern: "/(\\b{$categorie->slug}\\b)/", - subject: (string) pipe(URLHelper::get_current_url(), URLHelper::get_rel_url(...)) - ) + subject: (string) pipe(URLHelper::get_current_url(), URLHelper::get_rel_url(...)), + ), ]; $entrees_menu_categories = pipe( get_categories(['hide_empty' => false, 'orderby' => 'menu_order', 'taxonomy' => 'product_cat']), static fn($categories): array => array_map( callback: $cree_entree_menu, - array: $categories - ) + array: $categories, + ), ); $context['categories_produits'] = $entrees_menu_categories; @@ -152,7 +152,7 @@ final class StarterSite extends Site { $context['nonce_wc'] = $nonce_wc; // TODO: Utiliser des variables d'environnement $auth_string = base64_encode( - Config::get('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . Config::get('WOOCOMMERCE_API_CONSUMER_SECRET') + Config::get('WOOCOMMERCE_API_CONSUMER_KEY') . ':' . Config::get('WOOCOMMERCE_API_CONSUMER_SECRET'), ); $context['auth_string'] = $auth_string; diff --git a/web/app/themes/haiku-atelier-2024/src/inc/ChampsPersonnalises.php b/web/app/themes/haiku-atelier-2024/src/inc/ChampsPersonnalises.php index 05d882cc..9d509e72 100755 --- a/web/app/themes/haiku-atelier-2024/src/inc/ChampsPersonnalises.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/ChampsPersonnalises.php @@ -22,7 +22,7 @@ function cree_champs_personnalises_produit(): void { ->set_type(['image']) ->set_duplicates_allowed(false), // Texte des détails du Produit - Field::make('rich_text', 'haiku_details_produit', __("Product's Details")) + Field::make('rich_text', 'haiku_details_produit', __("Product's Details")), ]); } @@ -31,7 +31,7 @@ function cree_champ_personnalise_commande($order): void { 'id' => 'tracking_number', 'label' => 'Tracking Number:', 'value' => $order->get_meta('tracking_number'), - 'wrapper_class' => 'form-field-wide' + 'wrapper_class' => 'form-field-wide', ]); } diff --git a/web/app/themes/haiku-atelier-2024/src/inc/ControlesPersonnalises.php b/web/app/themes/haiku-atelier-2024/src/inc/ControlesPersonnalises.php index 0063c1cd..78d633cd 100755 --- a/web/app/themes/haiku-atelier-2024/src/inc/ControlesPersonnalises.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/ControlesPersonnalises.php @@ -30,7 +30,7 @@ function enregistre_controle_personnalise_tinymce(): void { src: get_template_directory_uri() . '/assets/vendor/controle-personnalise-tinymce.js', deps: ['jquery'], ver: '1.3', - args: true + args: true, ); wp_enqueue_editor(); } diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php index 3657fe7b..d50dad4a 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php @@ -15,7 +15,7 @@ final readonly class Attribute { public function __construct( public string $name, public string $slug, - public array $options + public array $options, ) {} public static function new(WC_Product_Attribute $attribute): self { @@ -29,7 +29,7 @@ final readonly class Attribute { return new self( name: $name, slug: $slug, - options: $options + options: $options, ); } } diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/AttributeOption.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/AttributeOption.php index e1ac97e0..e8d00a71 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/AttributeOption.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/AttributeOption.php @@ -10,7 +10,7 @@ final readonly class AttributeOption { public function __construct( public int $id, public string $name, - public string $slug + public string $slug, ) {} public static function new(WP_Term $term): self { @@ -21,7 +21,7 @@ final readonly class AttributeOption { return new self( id: $id, name: $name, - slug: $slug + slug: $slug, ); } } diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/Cart.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/Cart.php new file mode 100644 index 00000000..f4eecd5f --- /dev/null +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/Cart.php @@ -0,0 +1,122 @@ + + */ + public static function get_allowed_countries(): array { + return [ + 'AD', + 'AL', + 'AM', + 'AR', + 'AT', + 'AU', + 'BA', + 'BE', + 'BG', + 'BR', + 'CA', + 'CH', + 'CL', + 'CR', + 'CU', + 'CY', + 'CZ', + 'DE', + 'DK', + 'DZ', + 'EE', + 'EG', + 'ES', + 'FI', + 'FR', + 'GF', + 'GP', + 'GR', + 'HR', + 'HU', + 'IE', + 'IS', + 'IT', + 'JP', + 'KR', + 'LB', + 'LI', + 'LT', + 'LU', + 'LV', + 'MA', + 'MD', + 'ME', + 'MF', + 'MQ', + 'MT', + 'MX', + 'NC', + 'NL', + 'NO', + 'NZ', + 'PF', + 'PL', + 'PM', + 'PS', + 'PT', + 'RE', + 'RO', + 'SE', + 'SI', + 'SK', + 'SM', + 'TN', + 'TR', + 'TW', + 'US', + 'YT', + 'ZA', + ]; + } + + public static function parse_cart_value(int|float|string|bool $cart_value): string { + if (is_int($cart_value) || is_float($cart_value)) { + return self::format_number($cart_value); + } + + if (is_string($cart_value)) { + $number = Number::parseInt($cart_value); + $number = is_bool($number) ? 0 : $number; + + return self::format_number($number); + } + + return '0.00'; + } + + private static function format_number(int|float $number): string { + $formatted_number = Number::format( + number: $number, + // precision et max_precision sont mutuellement exclusifs. + precision: 2, + locale: 'fr', + ); + return is_bool($formatted_number) ? self::DEFAULT_VALUE : $formatted_number; + } +} diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/Product.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/Product.php index 325581ab..caace9aa 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/Product.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/Product.php @@ -35,7 +35,7 @@ final readonly class Product { public string $slug, public int $stock, public array $variations, - public string $url + public string $url, ) {} /** @@ -94,7 +94,7 @@ final readonly class Product { slug: $slug, stock: $stock, variations: $variations, - url: $url + url: $url, ); } } diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariation.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariation.php index 643067d5..11104db0 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariation.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariation.php @@ -15,7 +15,7 @@ final readonly class ProductVariation { private function __construct( public int $id, public string $price, - public array $attributes + public array $attributes, ) {} /** @@ -29,7 +29,7 @@ final readonly class ProductVariation { /** @phpstan-ignore argument.type (Impossible à satisfaire) */ static fn(string $key, string $value) => new ProductVariationAttribute($key, $value), array_keys($product->get_attributes()), - array_values($product->get_attributes()) + array_values($product->get_attributes()), ); return new self($id, $price, $attributes); diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariationAttribute.php b/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariationAttribute.php index b7e81e8f..988ee3b4 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariationAttribute.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Data/ProductVariationAttribute.php @@ -11,6 +11,6 @@ final readonly class ProductVariationAttribute { */ public function __construct( public string $attribute, - public string $value + public string $value, ) {} } diff --git a/web/app/themes/haiku-atelier-2024/src/inc/FonctionnalitesWooCommerce.php b/web/app/themes/haiku-atelier-2024/src/inc/FonctionnalitesWooCommerce.php index 4603e5af..26089f92 100755 --- a/web/app/themes/haiku-atelier-2024/src/inc/FonctionnalitesWooCommerce.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/FonctionnalitesWooCommerce.php @@ -131,7 +131,7 @@ function retire_merdes_wc(): void { */ function genere_balises_img_dans_produit_dans_reponse_rest( WP_REST_Response $response, - mixed $_product + mixed $_product, ): WP_REST_Response { // Vérifie que la Réponse a des données if (empty($response->data)) { @@ -143,16 +143,16 @@ function genere_balises_img_dans_produit_dans_reponse_rest( $response->data['meta_data'], static fn($metadata): array => array_filter( array: $metadata, - callback: static fn($entree): bool => '_photos_colonne_gauche|||0|value' === $entree->key + callback: static fn($entree): bool => '_photos_colonne_gauche|||0|value' === $entree->key, ), static fn($metadata): array => array_map( array: $metadata, callback: static fn($entree): string => genere_balise_img_multiformats( id: $entree?->value, - lazy: true - ) + lazy: true, + ), ), - static fn($image) => array_values(array: $image)[0] + static fn($image) => array_values(array: $image)[0], ); // Génère la balise pour l'image au survol @@ -160,16 +160,16 @@ function genere_balises_img_dans_produit_dans_reponse_rest( $response->data['meta_data'], static fn($metadata): array => array_filter( array: $metadata, - callback: static fn($entree): bool => '_photos_colonne_droite|||0|value' === $entree->key + callback: static fn($entree): bool => '_photos_colonne_droite|||0|value' === $entree->key, ), static fn($metadata): array => array_map( array: $metadata, callback: static fn($entree): string => genere_balise_img_multiformats( id: $entree?->value, - lazy: true - ) + lazy: true, + ), ), - static fn($image) => array_values(array: $image)[0] + static fn($image) => array_values(array: $image)[0], ); return $response; @@ -182,7 +182,7 @@ add_filter('woocommerce_rest_prepare_product_object', 'genere_balises_img_dans_p */ function genere_prix_maximal_produit_variable_dans_reponse_rest( WP_REST_Response $reponse, - WC_Data $_produit + WC_Data $_produit, ): WP_REST_Response { // Vérifie que la Réponse a des données if (empty($reponse->data)) { diff --git a/web/app/themes/haiku-atelier-2024/src/inc/HTML.php b/web/app/themes/haiku-atelier-2024/src/inc/HTML.php deleted file mode 100755 index 8db76ab5..00000000 --- a/web/app/themes/haiku-atelier-2024/src/inc/HTML.php +++ /dev/null @@ -1,17 +0,0 @@ -` d'un Média attaché à un Produit selon son ID. - */ -function genere_balise_img(int $id_image): string { - return wp_get_attachment_image( - attachment_id: $id_image, - size: 'full' - ); -} diff --git a/web/app/themes/haiku-atelier-2024/src/inc/Taxonomies.php b/web/app/themes/haiku-atelier-2024/src/inc/Taxonomies.php index f2fcaaaf..005de14d 100755 --- a/web/app/themes/haiku-atelier-2024/src/inc/Taxonomies.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/Taxonomies.php @@ -19,7 +19,7 @@ function enregistre_taxonomie_collection(): void { 'new_item_name' => __('New Collection Name'), 'search_items' => __('Search Collections'), 'singular_name' => __('Collection'), - 'update_item' => __('Update Collection') + 'update_item' => __('Update Collection'), ]; $args = [ 'description' => __('An ensemble of pieces thematically or chronologically grouped together.'), @@ -31,7 +31,7 @@ function enregistre_taxonomie_collection(): void { 'show_admin_column' => true, 'show_in_menu' => true, 'show_in_quick_edit' => true, - 'show_ui' => true + 'show_ui' => true, ]; register_taxonomy('collection', ['product'], $args); diff --git a/web/app/themes/haiku-atelier-2024/src/inc/TraitementInformations.php b/web/app/themes/haiku-atelier-2024/src/inc/TraitementInformations.php index d6600e8e..57f5f67e 100755 --- a/web/app/themes/haiku-atelier-2024/src/inc/TraitementInformations.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/TraitementInformations.php @@ -35,14 +35,13 @@ function genere_balise_img_multiformats(string $id, bool $lazy = false): string $avif = $chemin ? realpath(pathinfo($chemin)['dirname'] . '/' . pathinfo($chemin)['filename'] . '.avif') : false; $jxl = $chemin ? realpath(pathinfo($chemin)['dirname'] . '/' . pathinfo($chemin)['filename'] . '.jxl') : false; - $webp = $chemin ? realpath(pathinfo($chemin)['dirname'] . '/' . pathinfo($chemin)['filename'] . '.webp') : false; // Génère un tableau avec les différents formats valides $formats = pipe( - [$avif, $jxl, $webp], + [$avif, $jxl], static fn($tableau): array => array_filter( array: $tableau, - callback: static fn($chemin_format): bool => false !== $chemin_format + callback: static fn($chemin_format): bool => false !== $chemin_format, ), static fn($tableau): array => array_map( array: $tableau, @@ -54,13 +53,13 @@ function genere_balise_img_multiformats(string $id, bool $lazy = false): string . '/' . pathinfo($url)['filename'] . '.' - . pathinfo((string) $chemin_format)['extension'] - ] - ) + . pathinfo((string) $chemin_format)['extension'], + ], + ), ); usort( array: $formats, - callback: static fn($a, $b): int => $a['taille'] <=> $b['taille'] + callback: static fn($a, $b): int => $a['taille'] <=> $b['taille'], ); // Construis les balises avec les formats valides @@ -109,17 +108,17 @@ function recupere_informations_produit_shop(WC_Product $produit): mixed { // Récupère les informations de chaque Variation static fn($enfants): array => array_map( callback: wc_get_product(...), - array: $enfants + array: $enfants, ), // Trie les Variations par prix descendant static fn($variations): array => array_map( callback: static fn($variation) => $variation->get_price(), - array: $variations + array: $variations, ), // Récupère le Prix de la Variation la plus chère static fn($prix) => collect($prix)->max(), // Récupère le Prix pour la Variation la plus chère OU le prix du Produit simple - static fn($prix_variation_maximale) => $prix_variation_maximale ?? $produit->get_price() + static fn($prix_variation_maximale) => $prix_variation_maximale ?? $produit->get_price(), ); // TEMP: Cas de la Carte Cadeau où aucun prix ne doit être affiché. Idéalement utiliser un système d'étiquettes pour ces cas là. @@ -137,15 +136,15 @@ function recupere_informations_produit_shop(WC_Product $produit): mixed { // Photo du Produit affichée par défaut 'photo_repos' => genere_balise_img_multiformats( get_post_meta($post_id = $produit->get_id(), $key = '_photos_colonne_gauche|||0|value')[0] ?? -1, - false + false, ), // Photo du Produit affichée au survol de l'image 'photo_survol' => genere_balise_img_multiformats( get_post_meta($post_id = $produit->get_id(), $key = '_photos_colonne_droite|||0|value')[0] ?? -1, - true + true, ), // URL du Produit pour les liens vers celui-ci - 'url' => $produit->get_permalink() + 'url' => $produit->get_permalink(), ]; } @@ -175,19 +174,19 @@ function recupere_informations_produit_page_produit(WC_Product $product): mixed 'prix' => $product->get_price(), 'photos_colonne_gauche' => array_map( callback: genere_balise_img_multiformats(...), - array: get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_gauche|||0|value') + array: get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_gauche|||0|value'), ), 'photos_colonne_droite' => array_map( callback: genere_balise_img_multiformats(...), - array: carbon_get_the_post_meta('photos_colonne_droite') + array: carbon_get_the_post_meta('photos_colonne_droite'), ), 'photo_repos' => genere_balise_img_multiformats( get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_gauche|||0|value')[0] ?? -1, - false + false, ), 'photo_survol' => genere_balise_img_multiformats( get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_droite|||0|value')[0] ?? -1, - true + true, ), // Slug du Produit 'slug' => $product->get_slug(), @@ -196,7 +195,7 @@ function recupere_informations_produit_page_produit(WC_Product $product): mixed // Variations du Produit 'variations_ids' => $product->get_children(), // URL du Produit - 'url' => $product->get_permalink() + 'url' => $product->get_permalink(), ]; } @@ -206,15 +205,14 @@ function recupere_informations_produit_page_produit(WC_Product $product): mixed * * Pour faciliter l'usage avec `array_map`, utilise une fonction avec curryfication. */ -function recupere_produits_meme_collection(string $slug_collection): mixed { - // @param int $id_produit - return static fn($id_produit) => wc_get_products([ +function recupere_produits_meme_collection(string $slug_collection): callable { + return static fn(int $id_produit): array|stdClass => wc_get_products([ 'exclude' => [$id_produit], 'limit' => 4, 'order' => 'DESC', 'orderby' => 'date', 'status' => 'publish', - 'tax_query' => [['taxonomy' => 'collection', 'field' => 'slug', 'terms' => $slug_collection]] + 'tax_query' => [['taxonomy' => 'collection', 'field' => 'slug', 'terms' => $slug_collection]], ]); } @@ -224,6 +222,6 @@ function recupere_et_formate_attributs_produit(mixed $attributs_produit): mixed return [ 'taille' => ['nom' => 'Size', 'valeur' => $attributs_produit['pa_size'] ?? false], 'pierre' => ['nom' => 'Stone', 'valeur' => $attributs_produit['pa_stone'] ?? false], - 'cote' => ['nom' => 'Side', 'valeur' => $attributs_produit['pa_side'] ?? false] + 'cote' => ['nom' => 'Side', 'valeur' => $attributs_produit['pa_side'] ?? false], ]; } diff --git a/web/app/themes/haiku-atelier-2024/src/inc/WP/Resource.php b/web/app/themes/haiku-atelier-2024/src/inc/WP/Resource.php index 121c2e29..05d10bad 100644 --- a/web/app/themes/haiku-atelier-2024/src/inc/WP/Resource.php +++ b/web/app/themes/haiku-atelier-2024/src/inc/WP/Resource.php @@ -25,7 +25,7 @@ final readonly class Resource { id: $id, src: $file_uri, deps: [], - version: $version + version: $version, ); } @@ -46,7 +46,7 @@ final readonly class Resource { src: $file_uri, deps: [], ver: $ver, - media: 'all' + media: 'all', ); } } diff --git a/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/dom.ts b/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/dom.ts index 7aa8e3fa..68fdfdbf 100644 --- a/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/dom.ts +++ b/web/app/themes/haiku-atelier-2024/src/scripts-effect/lib/dom.ts @@ -9,7 +9,7 @@ export type ParentElement = Document | Element; export const getFirstSelectorFromParent = (parent: ParentElement) => (selector: string): Option.Option> => - Option.fromNullable(parent.querySelector(selector)); + Option.fromNullishOr(parent.querySelector(selector)); export const getFirstSelectorFromDocument = ( selector: string, diff --git a/web/app/themes/haiku-atelier-2024/style.css b/web/app/themes/haiku-atelier-2024/style.css index d89f20d3..cf8fbfab 100755 --- a/web/app/themes/haiku-atelier-2024/style.css +++ b/web/app/themes/haiku-atelier-2024/style.css @@ -7,7 +7,7 @@ Description: Hé. Version: 1.0 Requires at least: 5.0 Tested up to: 5.4 -Requires PHP: 7.0 +Requires PHP: 8.5 License: Tous droits réservés Text Domain: haiku-atelier-2024 */ diff --git a/web/app/themes/haiku-atelier-2024/taxonomy-product_cat.php b/web/app/themes/haiku-atelier-2024/taxonomy-product_cat.php index f1dee851..5939114f 100755 --- a/web/app/themes/haiku-atelier-2024/taxonomy-product_cat.php +++ b/web/app/themes/haiku-atelier-2024/taxonomy-product_cat.php @@ -6,19 +6,23 @@ declare(strict_types=1); * Le modèle de la Page d'Archive d'une Catégorie de Produits. */ +namespace HaikuAtelier; + +use Exception; use HaikuAtelier\Data\Product; use HaikuAtelier\WP\Resource; +use Illuminate\Support\Arr; use Timber\Timber; +use WC_Product; +use WP_Term; require_once __DIR__ . '/src/inc/TraitementInformations.php'; -// Contexte et modèles $context = Timber::context(); $templates = ['boutique.twig']; /** @var WP_Term */ $current_term = get_queried_object(); -/** @var string */ $category_slug = $current_term->slug; /** @var list $raw_products Les informations brutes des Produits. */ @@ -27,14 +31,11 @@ $raw_products = wc_get_products([ 'limit' => 12, 'order' => 'DESC', 'orderby' => 'date', - 'status' => 'publish' + 'status' => 'publish', ]); /** @var list */ -$products = array_map( - callback: Product::new(...), - array: $raw_products -); +$products = Arr::map($raw_products, Product::new(...)); $context['products'] = $products; /** @var string */ @@ -49,22 +50,22 @@ $context['products_category_id'] = $products_category_id; function load_page_resources(): void { Resource::enqueue_style_file( handle: 'haiku-atelier-2024-styles-page-boutique', - path: '/assets/css/pages/page-boutique.css' + path: '/assets/css/pages/page-boutique.css', ); Resource::enqueue_script_module_file( id: 'haiku-atelier-2024-scripts-page-boutique', - path: '/assets/js/scripts-page-boutique.js' + path: '/assets/js/scripts-page-boutique.js', ); Resource::enqueue_script_module_file( id: 'haiku-atelier-2024-scripts-menu-categories', - path: '/assets/js/scripts-menu-categories.js' + path: '/assets/js/scripts-menu-categories.js', ); } -add_action('wp_enqueue_scripts', 'load_page_resources'); +add_action('wp_enqueue_scripts', load_page_resources(...)); // Rendu Timber::render( filenames: $templates, - data: $context + data: $context, ); diff --git a/web/app/themes/haiku-atelier-2024/views/macros/images.twig b/web/app/themes/haiku-atelier-2024/views/macros/images.twig index e9485e34..c3438269 100755 --- a/web/app/themes/haiku-atelier-2024/views/macros/images.twig +++ b/web/app/themes/haiku-atelier-2024/views/macros/images.twig @@ -8,10 +8,6 @@ srcset="{{ rel_url }}.avif" type="image/avif" /> - Str::of($commande->get_shipping_method())->replace(' (Free)', ''), 'numero_suivi' => blank($commande->get_meta('tracking_number')) ? 'UNKNOWN_TRACKING_NUMBER' - : $commande->get_meta('tracking_number') - ] + : $commande->get_meta('tracking_number'), + ], ]; -$contexte['commande'] = $email; +$context['commande'] = $email; // Rendu Timber::render( - filenames: $modeles, - data: $contexte + filenames: $templates, + data: $context, ); diff --git a/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-invoice.php b/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-invoice.php index 0778ee4a..5b30f537 100755 --- a/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-invoice.php +++ b/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-invoice.php @@ -20,9 +20,9 @@ if (!defined('ABSPATH')) { Timber::init(); // Sélectionne le répertoire contenant les modèles Twig Timber::$dirname = ['views']; -// Contexte et modèles -$contexte = Timber::context(); -$modeles = ['email-base.twig']; + +$context = Timber::context(); +$templates = ['email-base.twig']; /** @var Order $commande La Commande issue du contexte contenu dans la variable $order. */ $commande = $order; @@ -35,7 +35,7 @@ $email = [ 'commande' => ['date' => $date->toDateString(), 'id' => $commande->get_id()], 'livraison' => [ 'methode' => $commande->get_shipping_method(), - 'numero_suivi' => $commande->get_meta('tracking_number') + 'numero_suivi' => $commande->get_meta('tracking_number'), ], 'paiement' => ['methode' => ''], 'produits' => collect($commande->get_items())->map(static function (WC_Order_Item_Product $article) { @@ -51,14 +51,14 @@ $email = [ ? collect($produit->get_attributes()) ->mapWithKeys(static fn($_atr, $cle): array => [ 'nom' => Str::lower(wc_attribute_label($cle, $produit)), - 'valeur' => $produit->get_attribute($cle) + 'valeur' => $produit->get_attribute($cle), ]) ->toArray() : [], 'lien' => $produit->get_permalink(), 'nom' => $produit->get_title(), 'prix_total' => $article->get_total(), - 'quantite' => $article->get_quantity() + 'quantite' => $article->get_quantity(), ]; }), 'totaux' => [ @@ -67,16 +67,16 @@ $email = [ 'sous_total_reduction' => '0.00' === $commande->get_discount_total() ? '0' : Number::format((float) $commande->get_discount_total(), maxPrecision: 2) . '€', - 'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€' - ] + 'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€', + ], ]; // Transforme les codes de pays en noms de pays $email['adresses']['livraison']['country'] = WC()->countries->countries[$commande->get_shipping_country()]; $email['adresses']['facturation']['country'] = WC()->countries->countries[$commande->get_billing_country()]; -$contexte['commande'] = $email; +$context['commande'] = $email; // Rendu Timber::render( - filenames: $modeles, - data: $contexte + filenames: $templates, + data: $context, ); diff --git a/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-processing-order.php b/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-processing-order.php index 9dd4eed8..5fbaa72a 100755 --- a/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-processing-order.php +++ b/web/app/themes/haiku-atelier-2024/woocommerce/emails/customer-processing-order.php @@ -20,9 +20,9 @@ if (!defined('ABSPATH')) { Timber::init(); // Sélectionne le répertoire contenant les modèles Twig Timber::$dirname = ['views']; -// Contexte et modèles -$contexte = Timber::context(); -$modeles = ['email-commande-recue.twig']; + +$context = Timber::context(); +$templates = ['email-commande-recue.twig']; /** @var Order $commande La Commande issue du contexte contenu dans la variable $order. */ $commande = $order; @@ -47,14 +47,14 @@ $email = [ ? collect($produit->get_attributes()) ->mapWithKeys(static fn($_atr, $cle): array => [ 'nom' => Str::lower(wc_attribute_label($cle, $produit)), - 'valeur' => $produit->get_attribute($cle) + 'valeur' => $produit->get_attribute($cle), ]) ->toArray() : [], 'lien' => $produit->get_permalink(), 'nom' => $produit->get_title(), 'prix_total' => $article->get_total(), - 'quantite' => $article->get_quantity() + 'quantite' => $article->get_quantity(), ]; }), 'totaux' => [ @@ -63,17 +63,17 @@ $email = [ 'sous_total_reduction' => '0.00' === $commande->get_discount_total() ? '0' : Number::format((float) $commande->get_discount_total(), maxPrecision: 2) . '€', - 'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€' - ] + 'total' => Number::format((float) $commande->get_total(), maxPrecision: 2) . '€', + ], ]; // Transforme les codes de pays en noms de pays $email['adresses']['livraison']['country'] = WC()->countries->countries[$commande->get_shipping_country()]; $email['adresses']['facturation']['country'] = WC()->countries->countries[$commande->get_billing_country()]; -$contexte['commande'] = $email; +$context['commande'] = $email; // Rendu Timber::render( - filenames: $modeles, - data: $contexte + filenames: $templates, + data: $context, ); diff --git a/web/app/uploads/woocommerce_transient_files/index.html b/web/app/uploads/woocommerce_transient_files/index.html index e69de29b..8b137891 100644 --- a/web/app/uploads/woocommerce_transient_files/index.html +++ b/web/app/uploads/woocommerce_transient_files/index.html @@ -0,0 +1 @@ +