fonc(produit) implémente le multi-variations
This commit is contained in:
parent
1a3a431b34
commit
05baad8fdd
26 changed files with 1320 additions and 184 deletions
|
|
@ -1,4 +1,4 @@
|
|||
<?php
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
use PhpCsFixer\Config;
|
||||
use PhpCsFixer\Finder;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"$schema": "/phpactor.schema.json",
|
||||
"$schema": "./phpactor.schema.json",
|
||||
"indexer.exclude_patterns": [
|
||||
"/vendor/**/Tests/**/*",
|
||||
"/vendor/**/tests/**/*",
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
"/vendor/composer/**/*"
|
||||
],
|
||||
"language_server.diagnostic_outsource_timeout": 5,
|
||||
"language_server.diagnostics_on_update": true,
|
||||
"language_server.diagnostics_on_update": false,
|
||||
"language_server.diagnostics_on_save": true,
|
||||
"language_server_highlight.enabled": true,
|
||||
"language_server_php_cs_fixer.enabled": true,
|
||||
|
|
|
|||
4
bun.lock
4
bun.lock
|
|
@ -44,7 +44,7 @@
|
|||
"oxlint": "^1.31.0",
|
||||
"picomatch": "^4.0.3",
|
||||
"playwright": "^1.57.0",
|
||||
"prettier": "^3.7.4",
|
||||
"prettier": "^4.0.0-alpha.13",
|
||||
"prettier-plugin-pkg": "^0.21.2",
|
||||
"prettier-plugin-sh": "^0.18.0",
|
||||
"sass-embedded": "^1.93.3",
|
||||
|
|
@ -1182,7 +1182,7 @@
|
|||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"prettier": ["prettier@3.7.4", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA=="],
|
||||
"prettier": ["prettier@4.0.0-alpha.13", "http://localhost:4873/prettier/-/prettier-4.0.0-alpha.13.tgz", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-177K/2S5iYDKtvZkDC2ZMqpyXtoiiVQBVQZpcQsRs+ZIIUQxsXomWIjquAlwt2pXpio9riz5IgtaUEnoZH44tg=="],
|
||||
|
||||
"prettier-plugin-pkg": ["prettier-plugin-pkg@0.21.2", "", { "peerDependencies": { "prettier": "^3.0.3" } }, "sha512-CSlM5+51B7yTKcoRWT4M3ImcdFHD5NUz0Xu2t8J03B761zu6J3BjSo/XleKp2kB0tH49K7oG5Uuqn6ldI5LRLg=="],
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"autoload": { "psr-4": { "HaikuAtelier\\": "web/app/themes/haiku-atelier-2024/src/inc/" } },
|
||||
"authors": [
|
||||
{ "email": "scott.walkinshaw@gmail.com", "homepage": "https://github.com/swalkinshaw", "name": "Scott Walkinshaw" },
|
||||
{ "email": "ben@benword.com", "homepage": "https://github.com/retlehs", "name": "Ben Word" }
|
||||
|
|
@ -35,17 +36,18 @@
|
|||
{ "only": ["wpackagist-plugin/*", "wpackagist-theme/*"], "type": "composer", "url": "https://wpackagist.org" }
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.5",
|
||||
"azjezz/psl": "^4.2",
|
||||
"composer/installers": "^2.3",
|
||||
"crell/fp": "^1.0",
|
||||
"htmlburger/carbon-fields": "^3.6",
|
||||
"illuminate/support": "^12.18",
|
||||
"illuminate/support": "^12.43",
|
||||
"laravel/helpers": "^1.7.1",
|
||||
"log1x/wp-smtp": "^1.0.2",
|
||||
"lstrojny/functional-php": "^1.17",
|
||||
"mnsami/composer-custom-directory-installer": "^2.0",
|
||||
"nesbot/carbon": "^3.8.2",
|
||||
"oscarotero/env": "^2.1.1",
|
||||
"php": ">=8.4",
|
||||
"roots/bedrock-autoloader": "^1.0.4",
|
||||
"roots/bedrock-disallow-indexing": "^2.0",
|
||||
"roots/wordpress": "^6.8.1",
|
||||
|
|
@ -68,8 +70,10 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.89",
|
||||
"php-standard-library/phpstan-extension": "^2.0",
|
||||
"phpstan/extension-installer": "^1.4.3",
|
||||
"phpstan/phpstan": "^2.0.3",
|
||||
"rector/rector": "^2.2",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"szepeviktor/phpstan-wordpress": "2.x-dev",
|
||||
"vincentlanglet/twig-cs-fixer": "^3.10"
|
||||
|
|
|
|||
298
composer.lock
generated
298
composer.lock
generated
|
|
@ -4,8 +4,84 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "d87a6e00e0233e0f2255f18aadf2d42c",
|
||||
"content-hash": "656fefb6a4e896ee0c5f5d87f36db997",
|
||||
"packages": [
|
||||
{
|
||||
"name": "azjezz/psl",
|
||||
"version": "4.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/azjezz/psl.git",
|
||||
"reference": "15153a64c9824335ce11654522e7d88de762d39e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/azjezz/psl/zipball/15153a64c9824335ce11654522e7d88de762d39e",
|
||||
"reference": "15153a64c9824335ce11654522e7d88de762d39e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-bcmath": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-sodium": "*",
|
||||
"php": "~8.3.0 || ~8.4.0 || ~8.5.0",
|
||||
"revolt/event-loop": "^1.0.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"carthage-software/mago": "^1.0.0-beta.32",
|
||||
"infection/infection": "^0.31.2",
|
||||
"php-coveralls/php-coveralls": "^2.7.0",
|
||||
"phpbench/phpbench": "^1.4.0",
|
||||
"phpunit/phpunit": "^9.6.22"
|
||||
},
|
||||
"suggest": {
|
||||
"php-standard-library/phpstan-extension": "PHPStan integration",
|
||||
"php-standard-library/psalm-plugin": "Psalm integration"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/hhvm/hsl",
|
||||
"name": "hhvm/hsl"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Psl\\": "src/Psl"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "azjezz",
|
||||
"email": "azjezz@protonmail.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP Standard Library",
|
||||
"support": {
|
||||
"issues": "https://github.com/azjezz/psl/issues",
|
||||
"source": "https://github.com/azjezz/psl/tree/4.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/azjezz",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/veewee",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-10-25T08:31:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "carbonphp/carbon-doctrine-types",
|
||||
"version": "3.2.0",
|
||||
|
|
@ -585,7 +661,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/collections",
|
||||
"version": "v12.42.0",
|
||||
"version": "v12.43.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/collections.git",
|
||||
|
|
@ -644,7 +720,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/conditionable",
|
||||
"version": "v12.42.0",
|
||||
"version": "v12.43.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/conditionable.git",
|
||||
|
|
@ -690,7 +766,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/contracts",
|
||||
"version": "v12.42.0",
|
||||
"version": "v12.43.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/contracts.git",
|
||||
|
|
@ -738,7 +814,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/macroable",
|
||||
"version": "v12.42.0",
|
||||
"version": "v12.43.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/macroable.git",
|
||||
|
|
@ -784,7 +860,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/reflection",
|
||||
"version": "v12.42.0",
|
||||
"version": "v12.43.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/reflection.git",
|
||||
|
|
@ -835,16 +911,16 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/support",
|
||||
"version": "v12.42.0",
|
||||
"version": "v12.43.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/support.git",
|
||||
"reference": "d35411be5657e0b5560a5885f3c9140e4cbe0be5"
|
||||
"reference": "20014564c32e2e8c6a57e03d065bcf8706a458e7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/support/zipball/d35411be5657e0b5560a5885f3c9140e4cbe0be5",
|
||||
"reference": "d35411be5657e0b5560a5885f3c9140e4cbe0be5",
|
||||
"url": "https://api.github.com/repos/illuminate/support/zipball/20014564c32e2e8c6a57e03d065bcf8706a458e7",
|
||||
"reference": "20014564c32e2e8c6a57e03d065bcf8706a458e7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -911,7 +987,7 @@
|
|||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2025-12-09T15:26:52+00:00"
|
||||
"time": "2025-12-14T15:58:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/helpers",
|
||||
|
|
@ -1604,6 +1680,78 @@
|
|||
},
|
||||
"time": "2021-10-29T13:26:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "revolt/event-loop",
|
||||
"version": "v1.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/revoltphp/event-loop.git",
|
||||
"reference": "b6fc06dce8e9b523c9946138fa5e62181934f91c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/revoltphp/event-loop/zipball/b6fc06dce8e9b523c9946138fa5e62181934f91c",
|
||||
"reference": "b6fc06dce8e9b523c9946138fa5e62181934f91c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-json": "*",
|
||||
"jetbrains/phpstorm-stubs": "^2019.3",
|
||||
"phpunit/phpunit": "^9",
|
||||
"psalm/phar": "^5.15"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Revolt\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aaron Piotrowski",
|
||||
"email": "aaron@trowski.com"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "ceesjank@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering"
|
||||
},
|
||||
{
|
||||
"name": "Niklas Keller",
|
||||
"email": "me@kelunik.com"
|
||||
}
|
||||
],
|
||||
"description": "Rock-solid event loop for concurrent PHP applications.",
|
||||
"keywords": [
|
||||
"async",
|
||||
"asynchronous",
|
||||
"concurrency",
|
||||
"event",
|
||||
"event-loop",
|
||||
"non-blocking",
|
||||
"scheduler"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/revoltphp/event-loop/issues",
|
||||
"source": "https://github.com/revoltphp/event-loop/tree/v1.0.8"
|
||||
},
|
||||
"time": "2025-08-27T21:33:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "roots/bedrock-autoloader",
|
||||
"version": "1.0.4",
|
||||
|
|
@ -3930,16 +4078,16 @@
|
|||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.92.1",
|
||||
"version": "v3.92.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "ed33ad03313a019533ba065eba6c86af0a382873"
|
||||
"reference": "64fab3553dce507ce247f7d1a7d65f74ef658c3f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/ed33ad03313a019533ba065eba6c86af0a382873",
|
||||
"reference": "ed33ad03313a019533ba065eba6c86af0a382873",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/64fab3553dce507ce247f7d1a7d65f74ef658c3f",
|
||||
"reference": "64fab3553dce507ce247f7d1a7d65f74ef658c3f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4022,7 +4170,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.1"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -4030,7 +4178,61 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-15T23:09:01+00:00"
|
||||
"time": "2025-12-17T00:04:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-standard-library/phpstan-extension",
|
||||
"version": "2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-standard-library/phpstan-extension.git",
|
||||
"reference": "eaf787ddf91f1b22b3a4da052f42294e0a75836e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-standard-library/phpstan-extension/zipball/eaf787ddf91f1b22b3a4da052f42294e0a75836e",
|
||||
"reference": "eaf787ddf91f1b22b3a4da052f42294e0a75836e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"phpstan/phpstan": "^2.0"
|
||||
},
|
||||
"conflict": {
|
||||
"azjezz/psl": "<1.6||>=5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"azjezz/psl": "^1.6||^2.0||^3.0||^4.0",
|
||||
"composer/semver": "^3.3",
|
||||
"nikic/php-parser": "^4.14.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpstan/phpstan-phpunit": "^2.0",
|
||||
"phpstan/phpstan-strict-rules": "^2.0",
|
||||
"phpunit/phpunit": "^9.6"
|
||||
},
|
||||
"type": "phpstan-extension",
|
||||
"extra": {
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psl\\PHPStan\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "PHPStan PSL extension",
|
||||
"support": {
|
||||
"issues": "https://github.com/php-standard-library/phpstan-extension/issues",
|
||||
"source": "https://github.com/php-standard-library/phpstan-extension/tree/2.0.2"
|
||||
},
|
||||
"time": "2025-11-30T13:33:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-stubs/wordpress-stubs",
|
||||
|
|
@ -4810,6 +5012,66 @@
|
|||
],
|
||||
"time": "2024-06-11T12:45:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rector/rector",
|
||||
"version": "2.2.14",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rectorphp/rector.git",
|
||||
"reference": "6d56bb0e94d4df4f57a78610550ac76ab403657d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/rectorphp/rector/zipball/6d56bb0e94d4df4f57a78610550ac76ab403657d",
|
||||
"reference": "6d56bb0e94d4df4f57a78610550ac76ab403657d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4|^8.0",
|
||||
"phpstan/phpstan": "^2.1.33"
|
||||
},
|
||||
"conflict": {
|
||||
"rector/rector-doctrine": "*",
|
||||
"rector/rector-downgrade-php": "*",
|
||||
"rector/rector-phpunit": "*",
|
||||
"rector/rector-symfony": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "To manipulate phpunit.xml via the custom-rule command"
|
||||
},
|
||||
"bin": [
|
||||
"bin/rector"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Instant Upgrade and Automated Refactoring of any PHP code",
|
||||
"homepage": "https://getrector.com/",
|
||||
"keywords": [
|
||||
"automation",
|
||||
"dev",
|
||||
"migration",
|
||||
"refactoring"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/rectorphp/rector/issues",
|
||||
"source": "https://github.com/rectorphp/rector/tree/2.2.14"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/tomasvotruba",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-09T10:57:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "roave/security-advisories",
|
||||
"version": "dev-latest",
|
||||
|
|
@ -7106,7 +7368,7 @@
|
|||
"prefer-stable": true,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=8.4"
|
||||
"php": ">=8.5"
|
||||
},
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
|
|
|
|||
|
|
@ -76,12 +76,12 @@
|
|||
},
|
||||
"newLineKind": "lf",
|
||||
"plugins": [
|
||||
"https://plugins.dprint.dev/typescript-0.95.12.wasm",
|
||||
"https://plugins.dprint.dev/typescript-0.95.13.wasm",
|
||||
"https://plugins.dprint.dev/json-0.21.0.wasm",
|
||||
"https://plugins.dprint.dev/markdown-0.20.0.wasm",
|
||||
"https://plugins.dprint.dev/toml-0.7.0.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/malva-v0.15.0.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/markup_fmt-v0.24.0.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/malva-v0.15.1.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/markup_fmt-v0.25.3.wasm",
|
||||
"https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.1.wasm",
|
||||
"https://plugins.dprint.dev/exec-0.6.0.json@a054130d458f124f9b5c91484833828950723a5af3f8ff2bd1523bd47b83b364"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
"oxlint": "^1.31.0",
|
||||
"picomatch": "^4.0.3",
|
||||
"playwright": "^1.57.0",
|
||||
"prettier": "^3.7.4",
|
||||
"prettier": "^4.0.0-alpha.13",
|
||||
"prettier-plugin-pkg": "^0.21.2",
|
||||
"prettier-plugin-sh": "^0.18.0",
|
||||
"sass-embedded": "^1.93.3",
|
||||
|
|
|
|||
492
phpactor.schema.json
Normal file
492
phpactor.schema.json
Normal file
|
|
@ -0,0 +1,492 @@
|
|||
{
|
||||
"$schema": "https:\/\/json-schema.org\/draft-07\/schema",
|
||||
"title": "Phpactor Configuration Schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"$schema": {
|
||||
"description": "Path to JSON schema, which can be used for config autocompletion, use phpactor config:initialize to update",
|
||||
"default": ""
|
||||
},
|
||||
"console_dumper_default": {
|
||||
"description": "Name of the \"dumper\" (renderer) to use for some CLI commands",
|
||||
"default": "indented"
|
||||
},
|
||||
"xdebug_disable": { "description": "If XDebug should be automatically disabled", "default": true },
|
||||
"command": { "description": "Internal use only - name of the command which was executed" },
|
||||
"core.min_memory_limit": {
|
||||
"description": "Ensure that PHP has a memory_limit of at least this amount in bytes",
|
||||
"default": 1610612736
|
||||
},
|
||||
"class_to_file.project_root": {
|
||||
"description": "Root path of the project (e.g. where composer.json is)",
|
||||
"default": "%project_root%"
|
||||
},
|
||||
"class_to_file.brute_force_conversion": {
|
||||
"description": "If composer not found, fallback to scanning all files (very time consuming depending on project size)",
|
||||
"default": true
|
||||
},
|
||||
"code_transform.class_new.variants": {
|
||||
"description": "Variants which should be suggested when class-create is invoked",
|
||||
"default": []
|
||||
},
|
||||
"code_transform.template_paths": {
|
||||
"description": "Paths in which to look for code templates",
|
||||
"default": ["%project_config%\/templates", "%config%\/templates"]
|
||||
},
|
||||
"code_transform.indentation": {
|
||||
"description": "Indentation chars to use in code generation and transformation",
|
||||
"default": " "
|
||||
},
|
||||
"code_transform.refactor.generate_accessor.prefix": {
|
||||
"description": "Prefix to use for generated accessors",
|
||||
"default": ""
|
||||
},
|
||||
"code_transform.refactor.generate_accessor.upper_case_first": {
|
||||
"description": "If the first letter of a generated accessor should be made uppercase",
|
||||
"default": false
|
||||
},
|
||||
"code_transform.refactor.generate_mutator.prefix": {
|
||||
"description": "Prefix to use for generated mutators",
|
||||
"default": "set"
|
||||
},
|
||||
"code_transform.refactor.generate_mutator.upper_case_first": {
|
||||
"description": "If the first letter of a generated mutator should be made uppercase",
|
||||
"default": true
|
||||
},
|
||||
"code_transform.refactor.generate_mutator.fluent": {
|
||||
"description": "If the mutator should be fluent",
|
||||
"default": false
|
||||
},
|
||||
"code_transform.import_globals": {
|
||||
"description": "Import functions even if they are in the global namespace",
|
||||
"default": false
|
||||
},
|
||||
"code_transform.refactor.object_fill.hint": {
|
||||
"description": "Object fill refactoring: show hint as a comment",
|
||||
"default": true
|
||||
},
|
||||
"code_transform.refactor.object_fill.named_parameters": {
|
||||
"description": "Object fill refactoring: use named parameters",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.doctrine_annotation.enabled": {
|
||||
"description": "Enable or disable the ``doctrine_annotation`` completor.\n\nCompletion for annotations provided by the Doctrine annotation library.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.imported_names.enabled": {
|
||||
"description": "Enable or disable the ``imported_names`` completor.\n\nCompletion for names imported into the current namespace.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.worse_parameter.enabled": {
|
||||
"description": "Enable or disable the ``worse_parameter`` completor.\n\nCompletion for method or function parameters.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.named_parameter.enabled": {
|
||||
"description": "Enable or disable the ``named_parameter`` completor.\n\nCompletion for named parameters.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.constructor.enabled": {
|
||||
"description": "Enable or disable the ``constructor`` completor.\n\nCompletion for constructors.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.class_member.enabled": {
|
||||
"description": "Enable or disable the ``class_member`` completor.\n\nCompletion for class members.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.scf_class.enabled": {
|
||||
"description": "Enable or disable the ``scf_class`` completor.\n\nBrute force completion for class names (not recommended).",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.local_variable.enabled": {
|
||||
"description": "Enable or disable the ``local_variable`` completor.\n\nCompletion for local variables.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.subscript.enabled": {
|
||||
"description": "Enable or disable the ``subscript`` completor.\n\nCompletion for subscript (array access from array shapes).",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.declared_function.enabled": {
|
||||
"description": "Enable or disable the ``declared_function`` completor.\n\nCompletion for functions defined in the Phpactor runtime.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.declared_constant.enabled": {
|
||||
"description": "Enable or disable the ``declared_constant`` completor.\n\nCompletion for constants defined in the Phpactor runtime.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.declared_class.enabled": {
|
||||
"description": "Enable or disable the ``declared_class`` completor.\n\nCompletion for classes defined in the Phpactor runtime.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.expression_name_search.enabled": {
|
||||
"description": "Enable or disable the ``expression_name_search`` completor.\n\nCompletion for class names, constants and functions at expression positions that are located in the index.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.use.enabled": {
|
||||
"description": "Enable or disable the ``use`` completor.\n\nCompletion for use imports.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.attribute.enabled": {
|
||||
"description": "Enable or disable the ``attribute`` completor.\n\nCompletion for attribute class names.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.class_like.enabled": {
|
||||
"description": "Enable or disable the ``class_like`` completor.\n\nCompletion for class like contexts.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.type.enabled": {
|
||||
"description": "Enable or disable the ``type`` completor.\n\nCompletion for scalar types.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.keyword.enabled": {
|
||||
"description": "Enable or disable the ``keyword`` completor.\n\nCompletion for keywords (not very accurate).",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.docblock.enabled": {
|
||||
"description": "Enable or disable the ``docblock`` completor.\n\nDocblock completion.",
|
||||
"default": true
|
||||
},
|
||||
"completion_worse.completor.constant.enabled": { "description": null, "default": false },
|
||||
"completion_worse.completor.class.limit": {
|
||||
"description": "Suggestion limit for the filesystem based SCF class_completor",
|
||||
"default": 100
|
||||
},
|
||||
"completion_worse.name_completion_priority": {
|
||||
"description": "Strategy to use when ordering completion results for classes and functions:\n\n- `proximity`: Classes and functions will be ordered by their proximity to the text document being edited.\n- `none`: No ordering will be applied.",
|
||||
"default": "proximity"
|
||||
},
|
||||
"completion_worse.snippets": { "description": "Enable or disable completion snippets", "default": true },
|
||||
"completion_worse.experimantal": { "description": "Enable experimental functionality", "default": false },
|
||||
"completion_worse.debug": { "description": "Include debug info in completion results", "default": false },
|
||||
"completion.dedupe": { "description": "If results should be de-duplicated", "default": true },
|
||||
"completion.dedupe_match_fqn": {
|
||||
"description": "If ``completion.dedupe``, consider the class FQN in addition to the completion suggestion",
|
||||
"default": true
|
||||
},
|
||||
"completion.limit": { "description": "Sets a limit on the number of completion suggestions for any request" },
|
||||
"completion.label_formatter": {
|
||||
"description": "Definition of how to format entries in the completion list",
|
||||
"default": "helpful",
|
||||
"enum": ["helpful", "fqn"]
|
||||
},
|
||||
"navigator.destinations": { "description": null, "default": [] },
|
||||
"navigator.autocreate": { "description": null, "default": [] },
|
||||
"rpc.store_replay": { "description": "Should replays be stored?", "default": false },
|
||||
"rpc.replay_path": { "description": "Path where the replays should be stored", "default": "%cache%\/replay.json" },
|
||||
"source_code_filesystem.project_root": { "description": null, "default": "%project_root%" },
|
||||
"language_server_code_transform.import_globals": {
|
||||
"description": "Show hints for non-imported global classes and functions",
|
||||
"default": false
|
||||
},
|
||||
"worse_reflection.enable_cache": { "description": "If reflection caching should be enabled", "default": true },
|
||||
"worse_reflection.cache_lifetime": {
|
||||
"description": "If caching is enabled, limit the amount of time a cache entry can stay alive",
|
||||
"default": 1
|
||||
},
|
||||
"worse_reflection.enable_context_location": {
|
||||
"description": "If source code is passed to a ``Reflector`` then temporarily make it available as a\nsource location. Note this should NOT be enabled if the source code can be\nlocated in another (e.g. when running a Language Server)",
|
||||
"default": true
|
||||
},
|
||||
"worse_reflection.cache_dir": {
|
||||
"description": "Cache directory for stubs",
|
||||
"default": "%cache%\/worse-reflection"
|
||||
},
|
||||
"worse_reflection.stub_dir": {
|
||||
"description": "Location of the core PHP stubs - these will be scanned and cached on the first request",
|
||||
"default": "%application_root%\/vendor\/jetbrains\/phpstorm-stubs"
|
||||
},
|
||||
"worse_reflection.diagnostics.undefined_variable.suggestion_levenshtein_disatance": {
|
||||
"description": "Levenshtein distance to use when suggesting corrections for variable names",
|
||||
"type": ["integer"],
|
||||
"default": 4
|
||||
},
|
||||
"file_path_resolver.project_root": { "description": null, "default": "\/opt\/phpactor" },
|
||||
"file_path_resolver.app_name": { "description": null, "default": "phpactor" },
|
||||
"file_path_resolver.application_root": { "description": null },
|
||||
"file_path_resolver.enable_cache": { "description": null, "default": true },
|
||||
"file_path_resolver.enable_logging": { "description": null, "default": true },
|
||||
"logging.enabled": { "description": null, "type": ["boolean"], "default": false },
|
||||
"logging.fingers_crossed": { "description": null, "type": ["boolean"], "default": false },
|
||||
"logging.path": { "description": null, "type": ["string"], "default": "application.log" },
|
||||
"logging.level": {
|
||||
"description": null,
|
||||
"type": ["string"],
|
||||
"default": "warning",
|
||||
"enum": ["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"]
|
||||
},
|
||||
"logger.name": { "description": null, "type": ["string"], "default": "logger" },
|
||||
"logging.formatter": { "description": null },
|
||||
"composer.enable": {
|
||||
"description": "Include of the projects autoloader to facilitate class location. Note that when including an autoloader code _may_ be executed. This option may be disabled when using the indexer",
|
||||
"default": true
|
||||
},
|
||||
"composer.autoloader_path": {
|
||||
"description": "Path to project's autoloader, can be an array",
|
||||
"default": "%project_root%\/vendor\/autoload.php"
|
||||
},
|
||||
"composer.autoload_deregister": {
|
||||
"description": "Immediately de-register the autoloader once it has been included (prevent conflicts with Phpactor's autoloader). Some platforms may require this to be disabled",
|
||||
"default": true
|
||||
},
|
||||
"composer.class_maps_only": {
|
||||
"description": "Register the composer class maps only, do not register the autoloader - RECOMMENDED",
|
||||
"default": true
|
||||
},
|
||||
"console.verbosity": { "description": "Verbosity level", "default": 32, "enum": [16, 32, 64, 128, 256] },
|
||||
"console.decorated": {
|
||||
"description": "Whether to decorate messages (null for auto-guessing)",
|
||||
"enum": [true, false, null]
|
||||
},
|
||||
"php.version": {
|
||||
"description": "Consider this value to be the project\\'s version of PHP (e.g. `7.4`). If omitted\nit will check `composer.json` (by the configured platform then the PHP requirement) before\nfalling back to the PHP version of the current process."
|
||||
},
|
||||
"language_server.catch_errors": { "description": null, "default": true },
|
||||
"language_server.enable_workspace": {
|
||||
"description": "If workspace management \/ text synchronization should be enabled (this isn't required for some language server implementations, e.g. static analyzers)",
|
||||
"default": true
|
||||
},
|
||||
"language_server.session_parameters": {
|
||||
"description": "Phpactor parameters (config) that apply only to the language server session",
|
||||
"default": []
|
||||
},
|
||||
"language_server.method_alias_map": {
|
||||
"description": "Allow method names to be re-mapped. Useful for maintaining backwards compatibility",
|
||||
"default": []
|
||||
},
|
||||
"language_server.diagnostic_sleep_time": {
|
||||
"description": "Amount of time to wait before analyzing the code again for diagnostics",
|
||||
"default": 1000
|
||||
},
|
||||
"language_server.diagnostics_on_update": {
|
||||
"description": "Perform diagnostics when the text document is updated",
|
||||
"default": true
|
||||
},
|
||||
"language_server.diagnostics_on_save": {
|
||||
"description": "Perform diagnostics when the text document is saved",
|
||||
"default": true
|
||||
},
|
||||
"language_server.diagnostics_on_open": {
|
||||
"description": "Perform diagnostics when opening a text document",
|
||||
"default": true
|
||||
},
|
||||
"language_server.diagnostic_providers": {
|
||||
"description": "Specify which diagnostic providers should be active (default to all)"
|
||||
},
|
||||
"language_server.diagnostic_outsource": {
|
||||
"description": "If applicable diagnostics should be \"outsourced\" to a different process",
|
||||
"default": true
|
||||
},
|
||||
"language_server.diagnostic_exclude_paths": {
|
||||
"description": "List of paths to exclude from diagnostics, e.g. `vendor\/**\/*`",
|
||||
"default": []
|
||||
},
|
||||
"language_server.file_events": { "description": "Register to receive file events", "default": true },
|
||||
"language_server.file_event_globs": { "description": null, "default": ["**\/*.php"] },
|
||||
"language_server.profile": { "description": "Logs timing information for incoming LSP requests", "default": false },
|
||||
"language_server.trace": {
|
||||
"description": "Log incoming and outgoing messages (needs log formatter to be set to ``json``)",
|
||||
"default": false
|
||||
},
|
||||
"language_server.shutdown_grace_period": {
|
||||
"description": "Amount of time (in milliseconds) to wait before responding to a shutdown notification",
|
||||
"default": 200
|
||||
},
|
||||
"language_server.phpactor_bin": {
|
||||
"description": "Internal use only - name path to Phpactor binary",
|
||||
"default": "\/opt\/phpactor\/lib\/Extension\/LanguageServer\/..\/..\/..\/bin\/phpactor"
|
||||
},
|
||||
"language_server.self_destruct_timeout": {
|
||||
"description": "Wait this amount of time (in milliseconds) after a shutdown request before self-destructing",
|
||||
"default": 2500
|
||||
},
|
||||
"language_server.diagnostic_outsource_timeout": {
|
||||
"description": "Kill the diagnostics process if it outlives this timeout",
|
||||
"default": 5
|
||||
},
|
||||
"language_server_completion.trim_leading_dollar": {
|
||||
"description": "If the leading dollar should be trimmed for variable completion suggestions",
|
||||
"default": false
|
||||
},
|
||||
"language_server_reference_reference_finder.reference_timeout": {
|
||||
"description": "Stop searching for references after this time (in seconds) has expired",
|
||||
"default": 60
|
||||
},
|
||||
"language_server_worse_reflection.workspace_index.update_interval": {
|
||||
"description": "Minimum interval to update the workspace index as documents are updated (in milliseconds)",
|
||||
"default": 100
|
||||
},
|
||||
"language_server_worse_reflection.inlay_hints.enable": {
|
||||
"description": "Enable inlay hints (experimental)",
|
||||
"default": false
|
||||
},
|
||||
"language_server_worse_reflection.inlay_hints.types": {
|
||||
"description": "Show inlay type hints for variables",
|
||||
"default": false
|
||||
},
|
||||
"language_server_worse_reflection.inlay_hints.params": {
|
||||
"description": "Show inlay hints for parameters",
|
||||
"default": true
|
||||
},
|
||||
"language_server_worse_reflection.diagnostics.enable": { "description": "Enable diagnostics", "default": true },
|
||||
"language_server_indexer.workspace_symbol_search_limit": { "description": null, "default": 250 },
|
||||
"language_server_indexer.reindex_timeout": {
|
||||
"description": "Unconditionally reindex modified files every N seconds",
|
||||
"default": 300
|
||||
},
|
||||
"language_server_code_transform.import_name.report_non_existing_names": {
|
||||
"description": "Show an error if a diagnostic name cannot be resolved - can produce false positives",
|
||||
"default": true
|
||||
},
|
||||
"language_server_configuration.auto_config": {
|
||||
"description": "Prompt to enable extensions which apply to your project on language server start",
|
||||
"type": ["boolean"],
|
||||
"default": true
|
||||
},
|
||||
"indexer.enabled_watchers": {
|
||||
"description": "List of allowed watchers. The first watcher that supports the current system will be used",
|
||||
"type": ["object"],
|
||||
"default": ["inotify", "watchman", "find", "php"]
|
||||
},
|
||||
"indexer.index_path": {
|
||||
"description": "Path where the index should be saved",
|
||||
"type": ["string"],
|
||||
"default": "%cache%\/index\/%project_id%"
|
||||
},
|
||||
"indexer.include_patterns": {
|
||||
"description": "Glob patterns to include while indexing",
|
||||
"type": ["object"],
|
||||
"default": ["\/**\/*.php", "\/**\/*.phar"]
|
||||
},
|
||||
"indexer.exclude_patterns": {
|
||||
"description": "Glob patterns to exclude while indexing",
|
||||
"type": ["object"],
|
||||
"default": ["\/vendor\/**\/Tests\/**\/*", "\/vendor\/**\/tests\/**\/*", "\/vendor\/composer\/**\/*"]
|
||||
},
|
||||
"indexer.stub_paths": {
|
||||
"description": "Paths to external folders to index. They will be indexed only once, if you want to take any changes into account you will have to reindex your project manually.",
|
||||
"type": ["object"],
|
||||
"default": []
|
||||
},
|
||||
"indexer.poll_time": {
|
||||
"description": "For polling indexers only: the time, in milliseconds, between polls (e.g. filesystem scans)",
|
||||
"type": ["integer"],
|
||||
"default": 5000
|
||||
},
|
||||
"indexer.buffer_time": {
|
||||
"description": "For real-time indexers only: the time, in milliseconds, to buffer the results",
|
||||
"type": ["integer"],
|
||||
"default": 500
|
||||
},
|
||||
"indexer.follow_symlinks": {
|
||||
"description": "To allow indexer to follow symlinks",
|
||||
"type": ["boolean"],
|
||||
"default": false
|
||||
},
|
||||
"indexer.project_root": {
|
||||
"description": "The root path to use for scanning the index",
|
||||
"type": ["string"],
|
||||
"default": "%project_root%"
|
||||
},
|
||||
"indexer.reference_finder.deep": {
|
||||
"description": "Recurse over class implementations to resolve all references",
|
||||
"type": ["boolean"],
|
||||
"default": true
|
||||
},
|
||||
"indexer.implementation_finder.deep": {
|
||||
"description": "Recurse over class implementations to resolve all class implementations (not just the classes directly implementing the subject)",
|
||||
"type": ["boolean"],
|
||||
"default": true
|
||||
},
|
||||
"indexer.supported_extensions": {
|
||||
"description": "File extensions (e.g. `php`) for files that should be indexed",
|
||||
"type": ["object"],
|
||||
"default": ["php", "phar"]
|
||||
},
|
||||
"object_renderer.template_paths.markdown": {
|
||||
"description": "Paths in which to look for templates for hover information.",
|
||||
"default": ["%project_config%\/templates\/markdown", "%config%\/templates\/markdown"]
|
||||
},
|
||||
"language_server_phpstan.bin": {
|
||||
"description": "Path to the PHPStan executable",
|
||||
"default": "%project_root%\/vendor\/bin\/phpstan"
|
||||
},
|
||||
"language_server_phpstan.level": { "description": "Override the PHPStan level" },
|
||||
"language_server_phpstan.config": { "description": "Override the PHPStan configuration file" },
|
||||
"language_server_phpstan.mem_limit": { "description": "Override the PHPStan memory limit" },
|
||||
"language_server_psalm.bin": {
|
||||
"description": "Path to psalm if different from vendor\/bin\/psalm",
|
||||
"type": ["string"],
|
||||
"default": "%project_root%\/vendor\/bin\/psalm"
|
||||
},
|
||||
"language_server_psalm.show_info": {
|
||||
"description": "If infos from psalm should be displayed",
|
||||
"type": ["boolean"],
|
||||
"default": true
|
||||
},
|
||||
"language_server_psalm.use_cache": {
|
||||
"description": "If the Psalm cache should be used (see the `--no-cache` option)",
|
||||
"type": ["boolean"],
|
||||
"default": true
|
||||
},
|
||||
"language_server_psalm.error_level": {
|
||||
"description": "Override level at which Psalm should report errors (lower => more errors)"
|
||||
},
|
||||
"language_server_psalm.threads": {
|
||||
"description": "Set the number of threads Psalm should use. Warning: NULL will use as many as possible and may crash your computer",
|
||||
"type": ["integer"],
|
||||
"default": 1
|
||||
},
|
||||
"language_server_psalm.timeout": {
|
||||
"description": "Kill the psalm process after this number of seconds",
|
||||
"type": ["integer"],
|
||||
"default": 15
|
||||
},
|
||||
"language_server_php_cs_fixer.bin": {
|
||||
"description": "Path to the php-cs-fixer executable",
|
||||
"default": "%project_root%\/vendor\/bin\/php-cs-fixer"
|
||||
},
|
||||
"language_server_php_cs_fixer.env": {
|
||||
"description": "Environment for PHP CS Fixer (e.g. to set PHP_CS_FIXER_IGNORE_ENV)",
|
||||
"default": { "XDEBUG_MODE": "off", "PHP_CS_FIXER_IGNORE_ENV": true }
|
||||
},
|
||||
"language_server_php_cs_fixer.show_diagnostics": {
|
||||
"description": "Whether PHP CS Fixer diagnostics are shown",
|
||||
"default": true
|
||||
},
|
||||
"language_server_php_cs_fixer.config": {
|
||||
"description": "Set custom PHP CS config path. Ex., %project_root%\/.php-cs-fixer.php"
|
||||
},
|
||||
"php_code_sniffer.bin": {
|
||||
"description": "Path to the phpcs executable",
|
||||
"default": "%project_root%\/vendor\/bin\/phpcs"
|
||||
},
|
||||
"php_code_sniffer.env": {
|
||||
"description": "Environment for PHP_CodeSniffer (e.g. to set XDEBUG_MODE)",
|
||||
"default": { "XDEBUG_MODE": "off" }
|
||||
},
|
||||
"php_code_sniffer.show_diagnostics": {
|
||||
"description": "Whether PHP_CodeSniffer diagnostics are shown",
|
||||
"default": true
|
||||
},
|
||||
"php_code_sniffer.args": { "description": "Additional arguments to pass to the PHPCS process", "default": [] },
|
||||
"php_code_sniffer.cwd": { "description": "Working directory for PHPCS" },
|
||||
"behat.config_path": {
|
||||
"description": "Path to the main behat.yml (including the filename behat.yml)",
|
||||
"default": "%project_root%\/behat.yml"
|
||||
},
|
||||
"behat.symfony.di_xml_path": {
|
||||
"description": "If using Symfony, set this path to the XML container dump to find contexts which are defined as services"
|
||||
},
|
||||
"symfony.xml_path": {
|
||||
"description": "Path to the Symfony container XML dump file",
|
||||
"default": "%project_root%\/var\/cache\/dev\/App_KernelDevDebugContainer.xml"
|
||||
},
|
||||
"completion_worse.completor.symfony.enabled": {
|
||||
"description": "Enable\/disable the Symfony completor - depends on Symfony extension being enabled",
|
||||
"default": true
|
||||
},
|
||||
"public_services_only": {
|
||||
"description": "Only consider public services when providing analysis for the service locator",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
24
rector.php
Normal file
24
rector.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
|
||||
return RectorConfig::configure()
|
||||
->withPaths([__DIR__ . '/web/app/themes/haiku-atelier-2024'])
|
||||
->withSkip([__DIR__ . '/vendor', __DIR__ . '/node_modules'])
|
||||
->withPhpSets(php85: true)
|
||||
->withCodeQualityLevel(10)
|
||||
->withCodingStyleLevel(10)
|
||||
->withDeadCodeLevel(10)
|
||||
->withTypeCoverageDocblockLevel(10)
|
||||
->withTypeCoverageLevel(10)
|
||||
->withImportNames(
|
||||
importDocBlockNames: true,
|
||||
importNames: true,
|
||||
importShortClasses: true,
|
||||
removeUnusedImports: true,
|
||||
)
|
||||
->withPreparedSets(
|
||||
carbon: true,
|
||||
instanceOf: true,
|
||||
privatization: true,
|
||||
);
|
||||
|
|
@ -1 +0,0 @@
|
|||
/var/www/wordpress/web/app/plugins/query-monitor/wp-content/db.php
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
<?php
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Le modèle de la Page d'Accueil.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Timber\Timber;
|
||||
|
||||
// Contexte et modèles
|
||||
|
|
|
|||
|
|
@ -1,46 +1,43 @@
|
|||
<?php
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Le modèle de la Page d'un Produit.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
use function Crell\fp\pipe;
|
||||
use HaikuAtelier\Data\Product;
|
||||
|
||||
use Timber\Timber;
|
||||
|
||||
use function Crell\fp\pipe;
|
||||
|
||||
require_once __DIR__ . '/src/inc/HTML.php';
|
||||
|
||||
require_once __DIR__ . '/src/inc/TraitementInformations.php';
|
||||
|
||||
// Contexte et modèles
|
||||
$contexte = Timber::context();
|
||||
$modeles = ['produit.twig'];
|
||||
$context = Timber::context();
|
||||
$templates = ['produit.twig'];
|
||||
|
||||
/** @var WC_Product $produit */
|
||||
$produit = wc_get_product();
|
||||
$product = wc_get_product();
|
||||
|
||||
/** @var mixed $donnees_produit */
|
||||
$donnees_produit = recupere_informations_produit_page_produit(wc_get_product());
|
||||
if ($product === null || is_bool($product)) {
|
||||
throw new Exception("Le Produit n'existe pas.");
|
||||
}
|
||||
|
||||
/** @var bool $est_variation Le Produit est-il Variable (possède-t-il des variations ?) */
|
||||
$est_produit_variable = 'variable' === $produit->get_type();
|
||||
// $donnees_produit = recupere_informations_produit_page_produit($product);
|
||||
$donnees_produit = Product::new($product);
|
||||
|
||||
/** @var array $variations_produit Un tableau des informations d'affichage de chaque Variation du Produit */
|
||||
// Un tableau des informations d'affichage de chaque Variation du Produit
|
||||
$variations_produit = pipe(
|
||||
// Récupère les IDs des Enfants (Variations)
|
||||
wc_get_product()->get_children(),
|
||||
$product->get_children(),
|
||||
// Récupère les Variations
|
||||
fn($enfants) => array_map(
|
||||
static fn(/** @var list<int> */ $enfants): array => array_map(
|
||||
callback: wc_get_product(...),
|
||||
array: $enfants,
|
||||
),
|
||||
// Ne conserve que les Informations souhaitées
|
||||
fn($variations) => array_map(
|
||||
callback: fn($variation) => [
|
||||
// Ne conserve que les Informations souhaitées.
|
||||
static fn(/** @var list<WC_Product> */ $variations): array => array_map(
|
||||
callback: static fn(WC_Product $variation): array => [
|
||||
'id' => $variation->get_id(),
|
||||
// Ne récupère que le titre de l'Attribut unique de la Variation
|
||||
// Ne récupère que le titre de l'Attribut unique de la Variation.
|
||||
'titre' => match (true) {
|
||||
'' !== $variation->get_attribute('pa_side') => $variation->get_attribute('pa_side'),
|
||||
'' !== $variation->get_attribute('pa_stone') => $variation->get_attribute('pa_stone'),
|
||||
|
|
@ -60,14 +57,14 @@ $variations_produit = pipe(
|
|||
$prix_maximal = collect($variations_produit)->max('prix');
|
||||
|
||||
$produits_meme_collection = array_map(
|
||||
callback: 'recupere_informations_produit_page_produit',
|
||||
array: recupere_produits_meme_collection($donnees_produit['collection'])($donnees_produit['id']),
|
||||
callback: recupere_informations_produit_page_produit(...),
|
||||
array: recupere_produits_meme_collection($donnees_produit->collection)($donnees_produit->id),
|
||||
);
|
||||
|
||||
$contexte['produit'] = $donnees_produit;
|
||||
$contexte['prix_maximal'] = $prix_maximal;
|
||||
$contexte['variations_produit'] = $variations_produit;
|
||||
$contexte['produits_meme_collection'] = $produits_meme_collection;
|
||||
$context['produit'] = $donnees_produit;
|
||||
$context['prix_maximal'] = $prix_maximal;
|
||||
$context['variations_produit'] = $variations_produit;
|
||||
$context['produits_meme_collection'] = $produits_meme_collection;
|
||||
|
||||
/**
|
||||
* Charge les Scripts nécessaires pour la page Produit.
|
||||
|
|
@ -89,11 +86,15 @@ function charge_scripts_page_produit(): void {
|
|||
|
||||
add_action('wp_enqueue_scripts', 'charge_scripts_page_produit');
|
||||
|
||||
// $lal = wp_json_encode($contexte);
|
||||
// echo "<script>console.debug({$lal});</script>";
|
||||
$lal = wp_json_encode($context);
|
||||
echo "<script>console.debug({$lal});</script>";
|
||||
|
||||
$lol = wc_get_product()->get_children();
|
||||
$lol = wp_json_encode($lol);
|
||||
echo "<script>console.debug({$lol});</script>";
|
||||
|
||||
// Rendu
|
||||
Timber::render(
|
||||
filenames: $modeles,
|
||||
data: $contexte,
|
||||
filenames: $templates,
|
||||
data: $context,
|
||||
);
|
||||
|
|
|
|||
33
web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php
Normal file
33
web/app/themes/haiku-atelier-2024/src/inc/Data/Attribute.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace HaikuAtelier\Data;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use WC_Product_Attribute;
|
||||
use WP_Term;
|
||||
|
||||
final readonly class Attribute {
|
||||
/**
|
||||
* @param list<AttributeOption> $options
|
||||
*/
|
||||
public function __construct(
|
||||
public string $name,
|
||||
public string $slug,
|
||||
public array $options,
|
||||
) {}
|
||||
|
||||
public static function new(WC_Product_Attribute $attribute): self {
|
||||
$name = wc_attribute_label($attribute->get_name());
|
||||
$slug = $attribute->get_name();
|
||||
/** @var list<WP_Term> */
|
||||
$terms = $attribute->get_terms() ?? [];
|
||||
/** @var list<AttributeOption> */
|
||||
$options = Arr::map($terms, static fn(WP_Term $term): AttributeOption => AttributeOption::new($term));
|
||||
|
||||
return new self(
|
||||
name: $name,
|
||||
slug: $slug,
|
||||
options: $options,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace HaikuAtelier\Data;
|
||||
|
||||
use WP_Term;
|
||||
|
||||
final readonly class AttributeOption {
|
||||
public function __construct(
|
||||
public int $id,
|
||||
public string $name,
|
||||
public string $slug,
|
||||
) {}
|
||||
|
||||
public static function new(WP_Term $term): self {
|
||||
$id = $term->term_taxonomy_id;
|
||||
$name = $term->name;
|
||||
$slug = $term->slug;
|
||||
|
||||
return new self(
|
||||
id: $id,
|
||||
name: $name,
|
||||
slug: $slug,
|
||||
);
|
||||
}
|
||||
}
|
||||
103
web/app/themes/haiku-atelier-2024/src/inc/Data/Product.php
Normal file
103
web/app/themes/haiku-atelier-2024/src/inc/Data/Product.php
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace HaikuAtelier\Data;
|
||||
|
||||
use HaikuAtelier\WP\HaikuProduct;
|
||||
use HaikuAtelier\WP\Term;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psl\Option;
|
||||
use function Psl\Option\from_nullable;
|
||||
use WC_Product;
|
||||
use WC_Product_Attribute;
|
||||
|
||||
use WP_Term;
|
||||
|
||||
final readonly class Product {
|
||||
/**
|
||||
* @param list<Attribute> $attributes
|
||||
* @param list<string> $left_column_photos
|
||||
* @param list<string> $right_column_photos
|
||||
* @param list<int> $variation_ids
|
||||
*/
|
||||
private function __construct(
|
||||
public array $attributes,
|
||||
public string $category,
|
||||
public string $collection,
|
||||
public string $details,
|
||||
public int $id,
|
||||
public string $name,
|
||||
public string $price,
|
||||
public array $left_column_photos,
|
||||
public array $right_column_photos,
|
||||
public string $default_photo,
|
||||
public string $hover_photo,
|
||||
public string $slug,
|
||||
public int $stock,
|
||||
public array $variation_ids,
|
||||
public string $url,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @return list<Attribute>
|
||||
*/
|
||||
public static function get_attributes_for_product(WC_Product $product): array {
|
||||
/** @var list<Attribute> */
|
||||
return $product->get_attributes()
|
||||
|> (static fn($attributes) => Arr::map($attributes, static fn(WC_Product_Attribute $attribute): Attribute => Attribute::new(
|
||||
$attribute,
|
||||
)));
|
||||
}
|
||||
|
||||
public static function new(WC_Product $product): self {
|
||||
/** @var list<Attribute> */
|
||||
$attributes = self::get_attributes_for_product($product);
|
||||
/** @var lowercase-string */
|
||||
$category = $product->get_id() |> wc_get_product_category_list(...) |> strtolower(...);
|
||||
|
||||
/** @var Option\Option<list<WP_Term>> */
|
||||
$collection = Term::get_terms($product->get_id(), 'collection');
|
||||
/** @var Option\Option<WP_Term> */
|
||||
$collection = $collection->andThen(
|
||||
static fn(array $terms): Option\Option => head($terms) |> from_nullable(...),
|
||||
);
|
||||
/** @var Option\Option<string> */
|
||||
$collection = $collection->map(static fn(WP_Term $term) => $term->slug);
|
||||
/** @var string */
|
||||
$collection = $collection->unwrapOr('');
|
||||
|
||||
/** @var string */
|
||||
$details = $product->get_description() |> wpautop(...);
|
||||
$id = $product->get_id();
|
||||
$name = $product->get_name();
|
||||
$price = $product->get_price();
|
||||
/** @var list<string> */
|
||||
$left_column_photos = HaikuProduct::get_left_column_photos($id);
|
||||
/** @var list<string> */
|
||||
$right_column_photos = HaikuProduct::get_right_column_photos($id);
|
||||
$default_photo = $left_column_photos[0] ?? genere_balise_img_multiformats('-1');
|
||||
$hover_photo = $right_column_photos[0] ?? genere_balise_img_multiformats('-1', true);
|
||||
$slug = $product->get_slug();
|
||||
$stock = $product->get_stock_quantity() ?? 1;
|
||||
/** @var list<int> */
|
||||
$variation_ids = $product->get_children();
|
||||
$url = $product->get_permalink();
|
||||
|
||||
return new self(
|
||||
attributes: $attributes,
|
||||
category: $category,
|
||||
collection: $collection,
|
||||
details: $details,
|
||||
id: $id,
|
||||
name: $name,
|
||||
price: $price,
|
||||
left_column_photos: $left_column_photos,
|
||||
right_column_photos: $right_column_photos,
|
||||
default_photo: $default_photo,
|
||||
hover_photo: $hover_photo,
|
||||
slug: $slug,
|
||||
stock: $stock,
|
||||
variation_ids: $variation_ids,
|
||||
url: $url,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,25 +6,30 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
use function Crell\fp\pipe;
|
||||
use HaikuAtelier\Data\Attribute;
|
||||
|
||||
use HaikuAtelier\Data\Product;
|
||||
|
||||
// Page Shop
|
||||
|
||||
/**
|
||||
* TODO.
|
||||
*
|
||||
* @param int $id TODO
|
||||
* @param bool $lazy TODO
|
||||
* @param string $id TODO
|
||||
* @param bool $lazy TODO
|
||||
*
|
||||
* @return string TODO
|
||||
*/
|
||||
function genere_balise_img_multiformats($id, $lazy = false) {
|
||||
function genere_balise_img_multiformats(string $id, bool $lazy = false): string {
|
||||
$int_id = (int) $id;
|
||||
|
||||
if (-1 === $id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$url = wp_get_attachment_image_url($id, 'full');
|
||||
$chemin = realpath(get_attached_file($id)) ?: realpath(get_attached_file($id));
|
||||
$alt = get_post_meta($id, '_wp_attachment_image_alt', true);
|
||||
$url = wp_get_attachment_image_url($int_id, 'full');
|
||||
$chemin = realpath(get_attached_file($int_id)) ?: realpath(get_attached_file($int_id));
|
||||
$alt = get_post_meta($int_id, '_wp_attachment_image_alt', true);
|
||||
$dimensions = $chemin ? getimagesize($chemin) : ['', ''];
|
||||
|
||||
$avif = $chemin ? realpath(pathinfo($chemin)['dirname'] . '/' . pathinfo($chemin)['filename'] . '.avif') : false;
|
||||
|
|
@ -34,27 +39,26 @@ function genere_balise_img_multiformats($id, $lazy = false) {
|
|||
// Génère un tableau avec les différents formats valides
|
||||
$formats = pipe(
|
||||
[$avif, $jxl, $webp],
|
||||
fn($tableau) => array_filter(
|
||||
static fn($tableau): array => array_filter(
|
||||
array: $tableau,
|
||||
callback: fn($chemin_format) => false !== $chemin_format,
|
||||
callback: static fn($chemin_format): bool => false !== $chemin_format,
|
||||
),
|
||||
fn($tableau) => array_map(
|
||||
static fn($tableau): array => array_map(
|
||||
array: $tableau,
|
||||
callback: fn($chemin_format) => [
|
||||
'format' => pathinfo($chemin_format)['extension'],
|
||||
callback: static fn($chemin_format): array => [
|
||||
'format' => pathinfo((string) $chemin_format)['extension'],
|
||||
'taille' => filesize($chemin_format),
|
||||
'url' =>
|
||||
pathinfo($url)['dirname']
|
||||
'url' => pathinfo($url)['dirname']
|
||||
. '/'
|
||||
. pathinfo($url)['filename']
|
||||
. '.'
|
||||
. pathinfo($chemin_format)['extension'],
|
||||
. pathinfo((string) $chemin_format)['extension'],
|
||||
],
|
||||
),
|
||||
);
|
||||
usort(
|
||||
array: $formats,
|
||||
callback: fn($a, $b) => $a['taille'] <=> $b['taille'],
|
||||
callback: static fn($a, $b): int => $a['taille'] <=> $b['taille'],
|
||||
);
|
||||
|
||||
// Construis les balises <source> avec les formats valides
|
||||
|
|
@ -84,47 +88,36 @@ function genere_balise_img_multiformats($id, $lazy = false) {
|
|||
|
||||
/**
|
||||
* TODO.
|
||||
*
|
||||
* @param WC_Product $a
|
||||
* @param WC_Product $b
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function tri_variations_par_prix_descendant($a, $b) {
|
||||
if ($a->get_price() === $b->get_price()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $a->get_price() < $b->get_price() ? 1 : -1;
|
||||
function tri_variations_par_prix_descendant(WC_Product $a, WC_Product $b): int {
|
||||
return $b->get_price() <=> $a->get_price();
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les informations utilisées pour la grille des Produits et les retourne sous forme
|
||||
* de tableau associatif.
|
||||
*
|
||||
* @param WC_Product $produit
|
||||
*
|
||||
* @return mixed un tableau avec uniquement les informations pour la Grille de Produits
|
||||
*/
|
||||
function recupere_informations_produit_shop($produit) {
|
||||
function recupere_informations_produit_shop(WC_Product $produit): mixed {
|
||||
/** @var int $prix_maximal Le prix maximal du Produit. */
|
||||
$prix_maximal = pipe(
|
||||
// Récupère les Variations
|
||||
$produit->get_children(),
|
||||
// Récupère les informations de chaque Variation
|
||||
fn($enfants) => array_map(
|
||||
static fn($enfants): array => array_map(
|
||||
callback: wc_get_product(...),
|
||||
array: $enfants,
|
||||
),
|
||||
// Trie les Variations par prix descendant
|
||||
fn($variations) => array_map(
|
||||
callback: fn($variation) => $variation->get_price(),
|
||||
static fn($variations): array => array_map(
|
||||
callback: static fn($variation) => $variation->get_price(),
|
||||
array: $variations,
|
||||
),
|
||||
// Récupère le Prix de la Variation la plus chère
|
||||
fn($prix) => collect($prix)->max(),
|
||||
static fn($prix) => collect($prix)->max(),
|
||||
// Récupère le Prix pour la Variation la plus chère OU le prix du Produit simple
|
||||
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à.
|
||||
|
|
@ -158,49 +151,50 @@ function recupere_informations_produit_shop($produit) {
|
|||
|
||||
/**
|
||||
* Retourne un tableau associatif des informations affichées sur la page Produit depuis les données brutes d'un Produit.
|
||||
*
|
||||
* @param WC_Product $donnees_produit
|
||||
*/
|
||||
function recupere_informations_produit_page_produit($donnees_produit): mixed {
|
||||
function recupere_informations_produit_page_produit(WC_Product $product): mixed {
|
||||
/** @var list<Attribute> */
|
||||
$attributs = Product::get_attributes_for_product($product);
|
||||
|
||||
return [
|
||||
// Attributs du Produit
|
||||
'attributs' => wc_get_product()->get_attributes(),
|
||||
'attributs' => $attributs,
|
||||
// Catégorie du Produit
|
||||
'categorie' => pipe($donnees_produit->get_id(), wc_get_product_category_list(...), strtolower(...)),
|
||||
'categorie' => pipe($product->get_id(), wc_get_product_category_list(...), strtolower(...)),
|
||||
// Slug de la Collection - Peut ne pas avoir été défini
|
||||
'collection' => get_the_terms($donnees_produit->get_id(), 'collection')[0]->slug ?? '',
|
||||
'collection' => get_the_terms($product->get_id(), 'collection')[0]->slug ?? '',
|
||||
// Détails (Description) du Produit
|
||||
'details' => wpautop($donnees_produit->get_description()),
|
||||
'details' => wpautop($product->get_description()),
|
||||
// Identifiant du Produit
|
||||
'id' => $donnees_produit->get_id(),
|
||||
'id' => $product->get_id(),
|
||||
// Nom affiché du Produit
|
||||
'nom' => $donnees_produit->get_name(),
|
||||
'nom' => $product->get_name(),
|
||||
// Prix affiché du Produit
|
||||
'prix' => $donnees_produit->get_price(),
|
||||
'prix' => $product->get_price(),
|
||||
'photos_colonne_gauche' => array_map(
|
||||
callback: 'genere_balise_img_multiformats',
|
||||
array: get_post_meta($post_id = $donnees_produit->get_id(), $key = '_photos_colonne_gauche|||0|value'),
|
||||
callback: genere_balise_img_multiformats(...),
|
||||
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',
|
||||
callback: genere_balise_img_multiformats(...),
|
||||
array: carbon_get_the_post_meta('photos_colonne_droite'),
|
||||
),
|
||||
'photo_repos' => genere_balise_img_multiformats(
|
||||
get_post_meta($post_id = $donnees_produit->get_id(), $key = '_photos_colonne_gauche|||0|value')[0] ?? -1,
|
||||
get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_gauche|||0|value')[0] ?? -1,
|
||||
false,
|
||||
),
|
||||
'photo_survol' => genere_balise_img_multiformats(
|
||||
get_post_meta($post_id = $donnees_produit->get_id(), $key = '_photos_colonne_droite|||0|value')[0] ?? -1,
|
||||
get_post_meta($post_id = $product->get_id(), $key = '_photos_colonne_droite|||0|value')[0] ?? -1,
|
||||
true,
|
||||
),
|
||||
// Slug du Produit
|
||||
'slug' => $donnees_produit->get_slug(),
|
||||
'slug' => $product->get_slug(),
|
||||
// Quantité de Produit en stock
|
||||
'stock' => $donnees_produit->get_stock_quantity() ?? 1,
|
||||
'stock' => $product->get_stock_quantity() ?? 1,
|
||||
// Variations du Produit
|
||||
'variations_ids' => $donnees_produit->get_children(),
|
||||
'variations_ids' => $product->get_children(),
|
||||
// URL du Produit
|
||||
'url' => $donnees_produit->get_permalink(),
|
||||
'url' => $product->get_permalink(),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -209,14 +203,10 @@ function recupere_informations_produit_page_produit($donnees_produit): mixed {
|
|||
* collection) et les retourne sous forme de tableau associatif.
|
||||
*
|
||||
* Pour faciliter l'usage avec `array_map`, utilise une fonction avec curryfication.
|
||||
*
|
||||
* @param string $slug_collection
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function recupere_produits_meme_collection($slug_collection) {
|
||||
function recupere_produits_meme_collection(string $slug_collection): mixed {
|
||||
// @param int $id_produit
|
||||
return fn($id_produit) => wc_get_products([
|
||||
return static fn($id_produit) => wc_get_products([
|
||||
'exclude' => [$id_produit],
|
||||
'limit' => 4,
|
||||
'order' => 'DESC',
|
||||
|
|
@ -228,12 +218,7 @@ function recupere_produits_meme_collection($slug_collection) {
|
|||
|
||||
// Page Panier
|
||||
|
||||
/**
|
||||
* @param mixed $attributs_produit
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function recupere_et_formate_attributs_produit($attributs_produit) {
|
||||
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],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace HaikuAtelier\WP;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
|
||||
final readonly class HaikuProduct {
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public static function get_left_column_photos(int $post_id): array {
|
||||
/** @var list<string> */
|
||||
return Post::get_post_meta_array($post_id, '_photos_colonne_gauche|||0|value')->unwrapOr([])
|
||||
|> (static fn(array $meta) => Arr::where($meta, static fn($meta): bool => is_string($meta)))
|
||||
|> (static fn(array $array) => Arr::map($array, genere_balise_img_multiformats(...)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public static function get_right_column_photos(int $post_id): array {
|
||||
$meta = carbon_get_post_meta($post_id, 'photos_colonne_droite');
|
||||
|
||||
if (is_array($meta)) {
|
||||
/** @var list<string> */
|
||||
return Arr::where($meta, static fn($meta): bool => is_string($meta))
|
||||
|> (static fn(array $array) => Arr::map($array, genere_balise_img_multiformats(...)));
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
55
web/app/themes/haiku-atelier-2024/src/inc/WP/Post.php
Normal file
55
web/app/themes/haiku-atelier-2024/src/inc/WP/Post.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace HaikuAtelier\WP;
|
||||
|
||||
use Psl\Option;
|
||||
use function Psl\Option\none;
|
||||
use function Psl\Option\some;
|
||||
|
||||
use WP_Error;
|
||||
use WP_Term;
|
||||
use function is_array;
|
||||
|
||||
final readonly class Post {
|
||||
/**
|
||||
* @return Option\Option<mixed>
|
||||
*/
|
||||
public static function get_post_meta(int $post_id, string $key): Option\Option {
|
||||
/** @var false|mixed|string */
|
||||
$value = get_post_meta($post_id, $key, true);
|
||||
|
||||
if ($value === false) {
|
||||
return none();
|
||||
}
|
||||
|
||||
return some($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Option\Option<array<mixed>>
|
||||
*/
|
||||
public static function get_post_meta_array(int $post_id, string $key): Option\Option {
|
||||
/** @var array<mixed>|false */
|
||||
$value = get_post_meta($post_id, $key, false);
|
||||
|
||||
if (is_array($value)) {
|
||||
return some($value);
|
||||
}
|
||||
|
||||
return none();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Option\Option<array<mixed>>
|
||||
*/
|
||||
public static function get_terms(int $post_id, string $taxonomy_name): Option\Option {
|
||||
/** @var false|list<WP_Term>|WP_Error */
|
||||
$terms = get_the_terms($post_id, $taxonomy_name);
|
||||
|
||||
if (is_array($terms)) {
|
||||
return some($terms);
|
||||
}
|
||||
|
||||
return none();
|
||||
}
|
||||
}
|
||||
26
web/app/themes/haiku-atelier-2024/src/inc/WP/Term.php
Normal file
26
web/app/themes/haiku-atelier-2024/src/inc/WP/Term.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace HaikuAtelier\WP;
|
||||
|
||||
use Psl\Option;
|
||||
use function Psl\Option\none;
|
||||
|
||||
use function Psl\Option\some;
|
||||
use WP_Term;
|
||||
use function is_array;
|
||||
|
||||
final readonly class Term {
|
||||
/**
|
||||
* @return Option\Option<list<WP_Term>>
|
||||
*/
|
||||
public static function get_terms(int $post_id, string $taxonomy_name): Option\Option {
|
||||
$terms = get_the_terms($post_id, $taxonomy_name);
|
||||
|
||||
if (is_array($terms)) {
|
||||
/** @var Option\Option<list<WP_Term>> */
|
||||
return some($terms);
|
||||
}
|
||||
|
||||
return none();
|
||||
}
|
||||
}
|
||||
|
|
@ -59,7 +59,10 @@
|
|||
font-size: var(--resume-police-nom-taille);
|
||||
}
|
||||
|
||||
&__selection-variation {
|
||||
&__attribut-variation {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
gap: var(--espace-m) var(--espace-l);
|
||||
font-size: var(--resume-police-selecteur-taille);
|
||||
font-weight: var(--resume-police-selecteur-graisse);
|
||||
text-transform: lowercase;
|
||||
|
|
@ -98,7 +101,7 @@
|
|||
pointer-events: none;
|
||||
content: " ";
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
top: 7px;
|
||||
right: 0.4rem;
|
||||
display: inline-block;
|
||||
width: 0.9rem;
|
||||
|
|
@ -148,7 +151,7 @@
|
|||
}
|
||||
|
||||
@media (width <= 500px) {
|
||||
.selecteur-produit__selection-variation {
|
||||
.selecteur-produit__selection-variation-attribut {
|
||||
flex-flow: column nowrap;
|
||||
row-gap: var(--espace-inter-colonne);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@ import { pipe } from "@mobily/ts-belt";
|
|||
import { forEach as arrayForEach } from "@mobily/ts-belt/Array";
|
||||
import { get as dictGet } from "@mobily/ts-belt/Dict";
|
||||
import { tap as optionTap } from "@mobily/ts-belt/Option";
|
||||
import { pipe as epipe } from "effect";
|
||||
import { EitherAsync, Maybe } from "purify-ts";
|
||||
import { match, P } from "ts-pattern";
|
||||
import { type AnySchema, ValiError } from "valibot";
|
||||
|
||||
import type { WCStoreCart } from "./lib/types/api/cart";
|
||||
import type { WCStoreCartAddItemArgs } from "./lib/types/api/cart-add-item.ts";
|
||||
import type { WCStoreCartAddItemArgs, WCStoreCartAddItemArgsItems } from "./lib/types/api/cart-add-item.ts";
|
||||
import type { FetchErrors } from "./lib/types/reseau.ts";
|
||||
|
||||
import { ROUTE_API_AJOUTE_ARTICLE_PANIER } from "./constantes/api.ts";
|
||||
|
|
@ -23,8 +24,8 @@ import {
|
|||
DOM_BOUTON_AJOUT_PANIER,
|
||||
DOM_BOUTONS_ACCORDEON,
|
||||
DOM_CONTENUS_ACCORDEON,
|
||||
DOM_PRIX_PRODUIT,
|
||||
DOM_DOM_QUANTITE,
|
||||
DOM_PRIX_PRODUIT,
|
||||
} from "./constantes/dom.ts";
|
||||
import { lanceAnimationCycleLoading } from "./lib/animations.ts";
|
||||
import { mustGetEleInDocument, mustGetElesInDocument, recupereElementDocumentEither } from "./lib/dom.ts";
|
||||
|
|
@ -64,8 +65,9 @@ const E = {
|
|||
BOUTON_AJOUT_PANIER: mustGetEleInDocument<HTMLButtonElement>(DOM_BOUTON_AJOUT_PANIER),
|
||||
BOUTONS_ACCORDEON: mustGetElesInDocument<HTMLAnchorElement>(DOM_BOUTONS_ACCORDEON),
|
||||
CONTENUS_ACCORDEON: mustGetElesInDocument<HTMLDivElement>(DOM_CONTENUS_ACCORDEON),
|
||||
PRIX_PRODUIT: mustGetEleInDocument<HTMLParagraphElement>(DOM_PRIX_PRODUIT),
|
||||
DOM_VARIATION: recupereElementDocumentEither<HTMLSelectElement>(DOM_DOM_QUANTITE),
|
||||
PRIX_PRODUIT: mustGetEleInDocument<HTMLParagraphElement>(DOM_PRIX_PRODUIT),
|
||||
VARIATION_CHOICE_FORM: mustGetEleInDocument<HTMLFormElement>("#variation-choice"),
|
||||
};
|
||||
|
||||
const gereAccordeonDetailsProduit = (): void => {
|
||||
|
|
@ -119,17 +121,39 @@ const gereAccordeonDetailsProduit = (): void => {
|
|||
});
|
||||
})
|
||||
);
|
||||
E.BOUTON_AJOUT_PANIER.addEventListener("click", (): void => ajouteProduitAuPanier());
|
||||
E.BOUTON_AJOUT_PANIER.addEventListener("click", (event: MouseEvent): void => ajouteProduitAuPanier(event));
|
||||
};
|
||||
|
||||
const ajouteProduitAuPanier = (): void => {
|
||||
const getAttributeValuesFromDom = () => {
|
||||
const selectElements = epipe(
|
||||
document.querySelectorAll<HTMLSelectElement>(".selecteur-produit select"),
|
||||
Array.from<HTMLSelectElement>,
|
||||
);
|
||||
if (selectElements.length === 0) return [];
|
||||
|
||||
const attributeValues = selectElements.map(select => {
|
||||
return {
|
||||
attribute: select.id.replace("selecteur-attribut-", ""),
|
||||
value: select.value,
|
||||
} satisfies WCStoreCartAddItemArgsItems;
|
||||
});
|
||||
|
||||
return attributeValues;
|
||||
};
|
||||
|
||||
const ajouteProduitAuPanier = (event: MouseEvent): void => {
|
||||
event.preventDefault();
|
||||
console.debug("getAttributeValuesFromDom", getAttributeValuesFromDom());
|
||||
|
||||
// Construis les arguments de la requête au backend
|
||||
const argsRequete: WCStoreCartAddItemArgs = {
|
||||
id: E.DOM_VARIATION
|
||||
.map((selecteur: HTMLSelectElement): number => Number(selecteur.value))
|
||||
// Récupère l'ID du Produit de la Page pour les Produits simples
|
||||
.orDefault(ETATS_PAGE.idProduit),
|
||||
// id: E.DOM_VARIATION
|
||||
// .map((selecteur: HTMLSelectElement): number => Number(selecteur.value))
|
||||
// // Récupère l'ID du Produit de la Page pour les Produits simples
|
||||
// .orDefault(ETATS_PAGE.idProduit),
|
||||
id: ETATS_PAGE.idProduit,
|
||||
quantity: 1,
|
||||
variation: getAttributeValuesFromDom(),
|
||||
};
|
||||
|
||||
// Réalise la Requête et traite sa Réponse
|
||||
|
|
@ -209,6 +233,28 @@ const ajouteProduitAuPanier = (): void => {
|
|||
.run();
|
||||
};
|
||||
|
||||
const initAddToCartButtonActivationOnUserChoice = (): void => {
|
||||
const selectElements: ReadonlyArray<HTMLSelectElement> = epipe(
|
||||
document.querySelectorAll<HTMLSelectElement>(".selecteur-produit select"),
|
||||
Array.from<HTMLSelectElement>,
|
||||
);
|
||||
// S'il n'y a pas de sélecteur de variation, activer le bouton.
|
||||
if (selectElements.length === 0) {
|
||||
E.BOUTON_AJOUT_PANIER.removeAttribute(ATTRIBUT_DESACTIVE);
|
||||
}
|
||||
|
||||
E.VARIATION_CHOICE_FORM.addEventListener("change", (): void => {
|
||||
const formValidity = E.VARIATION_CHOICE_FORM.checkValidity();
|
||||
|
||||
if (formValidity) {
|
||||
E.BOUTON_AJOUT_PANIER.removeAttribute(ATTRIBUT_DESACTIVE);
|
||||
} else {
|
||||
E.BOUTON_AJOUT_PANIER.setAttribute(ATTRIBUT_DESACTIVE, "");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", (): void => {
|
||||
gereAccordeonDetailsProduit();
|
||||
initAddToCartButtonActivationOnUserChoice();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ $informations_produits = wc_get_products([
|
|||
|
||||
/** @var InformationsProduitShop $produits Les informations strictement nécessaires pour la grille des Produits. */
|
||||
$produits = array_map(
|
||||
callback: 'recupere_informations_produit_shop',
|
||||
callback: recupere_informations_produit_shop(...),
|
||||
array: $informations_produits,
|
||||
);
|
||||
$contexte['produits'] = $produits;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
loading="eager"
|
||||
src="{{ rel_url }}.jpg"
|
||||
width="{{ width }}"
|
||||
onload="this.style.opacity=1"
|
||||
onload="this.style.opacity = 1"
|
||||
>
|
||||
</picture>
|
||||
{% endmacro %}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,63 @@
|
|||
{# Barre flottante avec le nom du Produit, le sélectgeur de variation et de quantité pour le Panier. #}
|
||||
{# Barre flottante avec le nom du Produit, le sélecteur de variation et de quantité pour le Panier. #}
|
||||
|
||||
<aside
|
||||
aria-label="Product's name, price and variation selection"
|
||||
class="resume-produit"
|
||||
>
|
||||
<section class="selecteur-produit">
|
||||
<h3 class="selecteur-produit__nom">{{ produit.nom }}</h3>
|
||||
<form
|
||||
class="selecteur-produit"
|
||||
id="variation-choice"
|
||||
name="variation-choice"
|
||||
>
|
||||
<h3 class="selecteur-produit__nom">{{ produit.name }}</h3>
|
||||
|
||||
<div class="selecteur-produit__selection-variation">
|
||||
{% if variations_produit|length > 1 %}
|
||||
<label
|
||||
for="selecteur-variation"
|
||||
id="label-selecteur-variation"
|
||||
>
|
||||
Option:
|
||||
</label>
|
||||
|
||||
<div class="selecteur-produit__selection-variation__selecteurs">
|
||||
<select
|
||||
aria-labelledby="label-selecteur-variation"
|
||||
id="selecteur-variation"
|
||||
name="variations"
|
||||
>
|
||||
<option
|
||||
disabled
|
||||
selected
|
||||
value=""
|
||||
>
|
||||
--
|
||||
</option>
|
||||
{% for variation in variations_produit %}
|
||||
<option
|
||||
data-prix="{{ variation.prix }}"
|
||||
value="{{ variation.id }}"
|
||||
>
|
||||
{{ variation.titre }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="selecteur-produit__attribut-variation">
|
||||
{% if produit.attributes %}
|
||||
{% for attribut in produit.attributes %}
|
||||
<div class="test">
|
||||
{{ include('parts/pages/produit/selecteur-attributs-produit.twig') }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<!--
|
||||
{% if variations_produit|length > 1 %}
|
||||
<label
|
||||
for="selecteur-variation"
|
||||
id="label-selecteur-variation"
|
||||
>
|
||||
Option:
|
||||
</label>
|
||||
|
||||
<div class="selecteur-produit__attribut-variation__selecteurs">
|
||||
<select
|
||||
aria-labelledby="label-selecteur-variation"
|
||||
id="selecteur-variation"
|
||||
name="variations"
|
||||
>
|
||||
<option
|
||||
disabled
|
||||
selected
|
||||
value=""
|
||||
>
|
||||
--
|
||||
</option>
|
||||
{% for variation in variations_produit %}
|
||||
<option
|
||||
data-prix="{{ variation.prix }}"
|
||||
value="{{ variation.id }}"
|
||||
>
|
||||
{{ variation.titre }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
-->
|
||||
</div>
|
||||
|
||||
<p class="selecteur-produit__prix">{{ prix_maximal ?? produit.prix }}€</p>
|
||||
</section>
|
||||
<p class="selecteur-produit__prix">{{ prix_maximal ?? produit.price }}€</p>
|
||||
</form>
|
||||
</aside>
|
||||
|
||||
<aside
|
||||
|
|
@ -107,12 +121,14 @@
|
|||
</div>
|
||||
|
||||
<div class="details-produit__actions">
|
||||
{# Désactive le bouton d'ajout au panier en cas d'absence de stock. #}
|
||||
{% if produit.stock > 0 %}
|
||||
<button
|
||||
class="bouton-case-pleine"
|
||||
{{ variations_produit|length > 1 ? 'disabled' : '' }}
|
||||
disabled
|
||||
for="variation-choice"
|
||||
id="bouton-ajout-panier"
|
||||
type="button"
|
||||
type="submit"
|
||||
>
|
||||
Add to cart
|
||||
</button>
|
||||
|
|
@ -120,6 +136,7 @@
|
|||
<button
|
||||
class="bouton-case-pleine"
|
||||
disabled
|
||||
for="variation-choice"
|
||||
id="bouton-ajout-panier"
|
||||
type="button"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
aria-label="Photo of the Product alone"
|
||||
class="colonne colonne-gauche"
|
||||
>
|
||||
{% for photo in produit.photos_colonne_gauche %}
|
||||
{% for photo in produit.left_column_photos %}
|
||||
<figure
|
||||
data-index="0"
|
||||
role="figure"
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
aria-label="Photos of the Product worn"
|
||||
class="colonne colonne-droite"
|
||||
>
|
||||
{% for photo in produit.photos_colonne_droite %}
|
||||
{% for photo in produit.right_column_photos %}
|
||||
<figure
|
||||
data-index="{{ loop.index }}"
|
||||
role="figure"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<div class="selecteur-produit__attribut-variation__selecteurs">
|
||||
<label
|
||||
for="selecteur-attribut-{{ attribut.slug }}"
|
||||
id="label-selecteur-attribut-{{ attribut.slug }}"
|
||||
>
|
||||
{{ attribut.name }}:
|
||||
</label>
|
||||
|
||||
<select
|
||||
aria-labelledby="label-selecteur-attribut-{{ atribut.slug }}"
|
||||
id="selecteur-attribut-{{ attribut.slug }}"
|
||||
name="attribut-{{ attribut.slug }}"
|
||||
required
|
||||
>
|
||||
<option
|
||||
disabled
|
||||
selected
|
||||
value=""
|
||||
>
|
||||
--
|
||||
</option>
|
||||
{% for term in attribut.options %}
|
||||
<option value="{{ term.slug }}">
|
||||
{{ term.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue