HEX
Server: Apache
System: Linux webm013.cluster123.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64
User: lesanew (165608)
PHP: 8.3.31
Disabled: _dyuweyrj4,_dyuweyrj4r,dl
Upload Files
File: /home/l/e/s/lesanew/anestetues2/makefile
## —— Makefile ——————————————————————————————————

# Configuration du thème :
NAME = anes-tetues
THEME = web/app/themes/$(NAME)

docker: ## lance le docker-compose
	docker compose up -d

server: ### lance le serveur
	wp server --port=8000 --config=development.ini

start: ## lance Docker, serveur WordPress et Vite
	docker compose up -d
	wp server --port=8000 --config=development.ini &
	make vite

vite: ## lance Vite en mode développement (watch)
	cd $(THEME) && npm run dev

## -------- Pages (WP-CLI) --------

create-page: ## Crée une page WordPress et génère SCSS/TS (pages/<slug>.*)
	@set -e; \
	title="$${TITLE}"; if [ -z "$$title" ]; then printf "Titre: "; read title; fi; \
	slug="$${SLUG}";  if [ -z "$$slug" ];  then printf "Slug (optionnel, Entrée pour auto): "; read slug; fi; \
	status="$${STATUS}"; [ -n "$$status" ] || status=publish; \
	set -- --post_type=page --post_title="$$title" --post_status="$$status"; \
	if [ -n "$$slug" ]; then set -- "$$@" --post_name="$$slug"; fi; \
	echo "📝 Création: $$title (slug: $$slug, statut: $$status)"; \
	id=$$(wp post create "$$@" --porcelain --allow-root); \
	echo "✅ Page créée: ID=$$id"; \
	page_slug="$$slug"; if [ -z "$$page_slug" ]; then page_slug=$$(wp post get $$id --field=post_name --allow-root); fi; \
	scss_path="$(THEME)/resources/css/pages/$$page_slug.scss"; \
	ts_dir="$(THEME)/resources/js/pages"; ts_path="$$ts_dir/$$page_slug.ts"; \
	mkdir -p "$(THEME)/resources/css/pages" "$$ts_dir"; \
	if [ ! -f "$$scss_path" ]; then printf "/* Page: %s */\n.page-template-%s {\n}\n" "$$title" "$$page_slug" > "$$scss_path"; echo "🎨 SCSS créé: $$scss_path"; else echo "🎨 SCSS déjà présent: $$scss_path"; fi; \
	if [ ! -f "$$ts_path" ]; then \
		pascal=$$(printf "%s" "$$page_slug" | sed -E 's/(^|[-_])([a-zA-Z])/\U\2/g'); \
		printf "%s\n" \
		"// Page: $$title" \
		"export const init$${pascal}Page = () => {" \
		"  console.debug('[page:$$page_slug] init');" \
		"};" \
		"" \
		"if (document.readyState === 'loading') {" \
		"  document.addEventListener('DOMContentLoaded', () => init$${pascal}Page());" \
		"} else {" \
		"  init$${pascal}Page();" \
		"}" > "$$ts_path"; \
		echo "🧩 TS créé: $$ts_path"; \
	else \
		echo "🧩 TS déjà présent: $$ts_path"; \
	fi; \
	# Création du template Blade \
	blade_path="$(THEME)/resources/views/pages/$$page_slug.blade.php"; \
	mkdir -p "$(THEME)/resources/views/pages"; \
	if [ ! -f "$$blade_path" ]; then \
		printf "{{--\n  Template Name: $$title\n--}}\n\n@extends('layouts.app')\n\n@push('vite-head')\n  @vite(['resources/css/pages/$$page_slug.scss', 'resources/js/pages/$$page_slug.ts'])\n@endpush\n\n@section('content')\n\n@endsection\n" > "$$blade_path"; \
		echo "🧩 Blade créé: $$blade_path"; \
	else \
		echo "🧩 Blade déjà présent: $$blade_path"; \
	fi; \
	# (désactivé) Création auto d'un groupe ACF — aucun champ généré par défaut \
	# Affectation du template à la page \
	wp post meta update $$id _wp_page_template "pages/$$page_slug.blade.php" --allow-root >/dev/null 2>&1 || true; \
	wp post list --post_type=page --fields=ID,post_title,post_name,post_status --allow-root | grep "^$$id\\b" || true

add-component: ## Ajoute un composant à une page existante
	@set -e; \
	echo "📋 Pages disponibles:"; \
	wp post list --post_type=page --fields=ID,post_title,post_name --format=table --allow-root; \
	echo ""; \
	page_id="$${PAGE_ID}"; if [ -z "$$page_id" ]; then printf "ID de la page: "; read page_id; fi; \
	page_title=$$(wp post get $$page_id --field=post_title --allow-root); \
	page_slug=$$(wp post get $$page_id --field=post_name --allow-root); \
	echo "📄 Page sélectionnée: $$page_title ($$page_slug)"; \
	echo ""; \
	echo "🧩 Composants disponibles:"; \
	echo "1) titre-texte"; \
	echo "2) image-texte-bouton"; \
	echo ""; \
	component="$${COMPONENT}"; if [ -z "$$component" ]; then printf "Numéro du composant (1-2): "; read component; fi; \
	case "$$component" in \
		1) component_name="titre-texte"; component_fields="titre,texte"; ;; \
		2) component_name="image-texte-bouton"; component_fields="image,texte,texte_bouton,lien_bouton"; ;; \
		*) echo "❌ Composant invalide"; exit 1; ;; \
	esac; \
	echo "🔧 Ajout du composant: $$component_name"; \
	echo ""; \
	group_title="$${GROUP_TITLE}"; if [ -z "$$group_title" ]; then printf "Titre du groupe ACF (Entrée pour '$$component_name'): "; read group_title; fi; \
	if [ -z "$$group_title" ]; then group_title="$$component_name"; fi; \
	echo "📝 Titre du groupe ACF: $$group_title"; \
	# Nom (name) du champ group interne basé sur le titre (sans accents, _ ) \
	group_field_name=$$(printf "%s" "$$group_title" | iconv -f UTF-8 -t ASCII//TRANSLIT 2>/dev/null | tr '[:upper:]' '[:lower:]' | sed -E 's/[[:space:]]+/_/g' | sed -E 's/[^a-z0-9_]+/_/g' | sed -E 's/^_+|_+$$//g'); \
	[ -n "$$group_field_name" ] || group_field_name=$$(printf "%s" "$$group_title" | tr '[:upper:]' '[:lower:]' | sed -E 's/[[:space:]]+/_/g' | sed -E 's/[^a-z0-9_]+/_/g' | sed -E 's/^_+|_+$$//g'); \
	# Fichier Blade du composant (pour annotations facultatives) \
	spec_file="$(THEME)/resources/views/components/$$component_name.blade.php"; \
	# Ajouter les champs ACF au groupe de la page \
	acf_file="$(THEME)/app/acf/$$page_slug.php"; \
	# Créer un fichier ACF minimal s'il n'existe pas (groupe vide, prêt pour insertion) \
	if [ ! -f "$$acf_file" ]; then \
		echo "🆕 Création du fichier ACF: $$acf_file"; \
		mkdir -p "$(THEME)/app/acf"; \
		# Calcul d'une clé de groupe stable basée sur le titre (sans accents), espaces -> _ \
		group_slug="$$page_slug"; \
		# Si iconv indisponible, fallback simple \
		[ -n "$$group_slug" ] || group_slug=$$(printf "%s" "$$page_title" | iconv -f UTF-8 -t ASCII//TRANSLIT 2>/dev/null | tr '[:upper:]' '[:lower:]' | sed -E 's/[[:space:]]+/_/g' | sed -E 's/[^a-z0-9_]+/_/g' | sed -E 's/^_+|_+$$//g'); \
		base_group_key="$$group_slug"; \
		unique_group_key="$$base_group_key"; \
		idx=2; \
		while grep -R --include='*.php' -q "'key' => '$$unique_group_key'" "$(THEME)/app/acf" 2>/dev/null; do \
			unique_group_key="$$base_group_key-$$idx"; \
			idx=$$((idx + 1)); \
		done; \
		cat > "$$acf_file" <<-PHP
		<?php
		add_action( 'acf/include_fields', function() {
			if ( ! function_exists( 'acf_add_local_field_group' ) ) {
				return;
			}

			acf_add_local_field_group( array(
				'key' => '$$unique_group_key',
				'title' => '$$page_title',
				'fields' => array(
				),
				'location' => array(
					array(
						array(
							'param' => 'post_template',
							'operator' => '==',
							'value' => 'pages/$$page_slug.blade.php',
						),
					),
				),
				'menu_order' => 0,
				'position' => 'normal',
				'style' => 'default',
				'label_placement' => 'top',
				'instruction_placement' => 'label',
				'hide_on_screen' => '',
				'active' => true,
				'description' => '',
				'show_in_rest' => 0,
			) );
		} );
		PHP
	fi; \
	if [ -f "$$acf_file" ]; then \
		echo "📝 Ajout des champs ACF pour $$component_name..."; \
		# Assurer l'unicité du name du champ group dans ce fichier \
		unique_group_field_name="$$group_field_name"; \
		u_idx=2; \
		while grep -q "'name' => '$$unique_group_field_name'" "$$acf_file" 2>/dev/null; do \
			unique_group_field_name="$${group_field_name}_$${u_idx}"; \
			u_idx=$$((u_idx + 1)); \
		done; \
		# Créer un fichier temporaire avec les nouveaux champs \
		temp_file="/tmp/acf_$$component_name.$$(date +%s).php"; \
		case "$$component_name" in \
			"titre-texte") \
				base_key=$$(date +%s); \
				if [ -f "$$spec_file" ]; then \
					# Génération dynamique depuis annotations du Blade \
					printf "array(\n\t\t\t'key' => '$$unique_group_field_name',\n\t\t\t'label' => '$$group_title',\n\t\t\t'name' => '$$unique_group_field_name',\n\t\t\t'type' => 'group',\n\t\t\t'layout' => 'block',\n\t\t\t'sub_fields' => array(\n" > "$$temp_file"; \
					inc=1; \
					while IFS= read -r line; do \
						parsed=$$(printf "%s\n" "$$line" | sed -n -E "s/^[[:space:]]*\\/\\/\\s*([^:]+)\\s*:\\s*(.+)\\s*$$/\\1|\\2/p; s/^[[:space:]]*\\{\\{--\\s*([^:]+)\\s*:\\s*(.+)\\s*--\\}\\}$$/\\1|\\2/p"); \
						[ -z "$$parsed" ] && continue; \
						label=$$(printf "%s" "$$parsed" | cut -d'|' -f1 | sed -E 's/^\s+|\s+$$//g'); \
						name=$$(printf "%s" "$$label" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9_]+/_/g'); \
						rawtype=$$(printf "%s" "$$parsed" | cut -d'|' -f2 | tr '[:upper:]' '[:lower:]'); \
						case "$$rawtype" in \
							*wysi*|*editeur*) acf_type="wysiwyg" ;; \
							*texte-court*|*text*) acf_type="text" ;; \
							*textarea*|*texte-long*) acf_type="textarea" ;; \
							*image*) acf_type="image" ;; \
							*url*) acf_type="url" ;; \
							*) acf_type="text" ;; \
						esac; \
						printf "\t\t\t\tarray(\n\t\t\t\t\t'key' => 'field_$$(($$base_key + $$inc))',\n\t\t\t\t\t'label' => '%s',\n\t\t\t\t\t'name' => '%s',\n\t\t\t\t\t'aria-label' => '',\n\t\t\t\t\t'type' => '%s',\n\t\t\t\t\t'instructions' => '',\n\t\t\t\t\t'required' => 0,\n\t\t\t\t\t'conditional_logic' => 0,\n\t\t\t\t\t'wrapper' => array(\n\t\t\t\t\t\t'width' => '',\n\t\t\t\t\t\t'class' => '',\n\t\t\t\t\t\t'id' => '',\n\t\t\t\t\t),\n\t\t\t\t),\n" "$$label" "$$name" "$$acf_type" >> "$$temp_file"; \
						inc=$$((inc + 1)); \
					done < "$$spec_file"; \
					printf "\t\t\t),\n\t\t)," >> "$$temp_file"; \
				else \
					printf "array(\n\t\t\t'key' => 'field_$${base_key}',\n\t\t\t'label' => '$$group_title',\n\t\t\t'name' => '$$unique_group_field_name',\n\t\t\t'type' => 'group',\n\t\t\t'layout' => 'block',\n\t\t\t'sub_fields' => array(\n\t\t\t\tarray(\n\t\t\t\t\t'key' => 'field_$$((base_key + 1))',\n\t\t\t\t\t'label' => 'Titre',\n\t\t\t\t\t'name' => 'titre',\n\t\t\t\t\t'aria-label' => '',\n\t\t\t\t\t'type' => 'text',\n\t\t\t\t\t'instructions' => '',\n\t\t\t\t\t'required' => 0,\n\t\t\t\t\t'conditional_logic' => 0,\n\t\t\t\t\t'wrapper' => array(\n\t\t\t\t\t\t'width' => '',\n\t\t\t\t\t\t'class' => '',\n\t\t\t\t\t\t'id' => '',\n\t\t\t\t\t),\n\t\t\t\t\t'default_value' => 'Lorem ipsum dolor sit amet',\n\t\t\t\t\t'maxlength' => '',\n\t\t\t\t\t'placeholder' => '',\n\t\t\t\t\t'prepend' => '',\n\t\t\t\t\t'append' => '',\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'key' => 'field_$$((base_key + 2))',\n\t\t\t\t\t'label' => 'Texte',\n\t\t\t\t\t'name' => 'texte',\n\t\t\t\t\t'aria-label' => '',\n\t\t\t\t\t'type' => 'textarea',\n\t\t\t\t\t'instructions' => '',\n\t\t\t\t\t'required' => 0,\n\t\t\t\t\t'conditional_logic' => 0,\n\t\t\t\t\t'wrapper' => array(\n\t\t\t\t\t\t'width' => '',\n\t\t\t\t\t\t'class' => '',\n\t\t\t\t\t\t'id' => '',\n\t\t\t\t\t),\n\t\t\t\t\t'default_value' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',\n\t\t\t\t\t'maxlength' => '',\n\t\t\t\t\t'placeholder' => '',\n\t\t\t\t\t'rows' => '',\n\t\t\t\t\t'new_lines' => '',\n\t\t\t\t),\n\t\t\t),\n\t\t)," > "$$temp_file"; \
				fi; \
				;; \
			"image-texte-bouton") \
				base_key=$$(date +%s); \
				if [ -f "$$spec_file" ]; then \
					printf "array(\n\t\t\t'key' => '$$unique_group_field_name',\n\t\t\t'label' => '$$group_title',\n\t\t\t'name' => '$$unique_group_field_name',\n\t\t\t'type' => 'group',\n\t\t\t'layout' => 'block',\n\t\t\t'sub_fields' => array(\n" > "$$temp_file"; \
					inc=1; \
					while IFS= read -r line; do \
						parsed=$$(printf "%s\n" "$$line" | sed -n -E "s/^[[:space:]]*\\/\\/\\s*([^:]+)\\s*:\\s*(.+)\\s*$$/\\1|\\2/p; s/^[[:space:]]*\\{\\{--\\s*([^:]+)\\s*:\\s*(.+)\\s*--\\}\\}$$/\\1|\\2/p"); \
						[ -z "$$parsed" ] && continue; \
						label=$$(printf "%s" "$$parsed" | cut -d'|' -f1 | sed -E 's/^\s+|\s+$$//g'); \
						name=$$(printf "%s" "$$label" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9_]+/_/g'); \
						rawtype=$$(printf "%s" "$$parsed" | cut -d'|' -f2 | tr '[:upper:]' '[:lower:]'); \
						case "$$rawtype" in \
							*wysi*|*editeur*) acf_type="wysiwyg" ;; \
							*text*) acf_type="text" ;; \
							*textarea*|*texte-long*) acf_type="textarea" ;; \
							*image*) acf_type="image" ;; \
							*url*) acf_type="url" ;; \
							*) acf_type="text" ;; \
						esac; \
						printf "\t\t\t\tarray(\n\t\t\t\t\t'key' => 'field_$$(($$base_key + $$inc))',\n\t\t\t\t\t'label' => '%s',\n\t\t\t\t\t'name' => '%s',\n\t\t\t\t\t'aria-label' => '',\n\t\t\t\t\t'type' => '%s',\n\t\t\t\t\t'instructions' => '',\n\t\t\t\t\t'required' => 0,\n\t\t\t\t\t'conditional_logic' => 0,\n\t\t\t\t\t'wrapper' => array(\n\t\t\t\t\t\t'width' => '',\n\t\t\t\t\t\t'class' => '',\n\t\t\t\t\t\t'id' => '',\n\t\t\t\t\t),\n\t\t\t\t),\n" "$$label" "$$name" "$$acf_type" >> "$$temp_file"; \
						inc=$$((inc + 1)); \
					done < "$$spec_file"; \
					printf "\t\t\t),\n\t\t)," >> "$$temp_file"; \
				else \
					printf "array(\n\t\t\t'key' => 'field_$${base_key}',\n\t\t\t'label' => '$$group_title',\n\t\t\t'name' => '$$unique_group_field_name',\n\t\t\t'type' => 'group',\n\t\t\t'layout' => 'block',\n\t\t\t'sub_fields' => array(\n\t\t\t\tarray(\n\t\t\t\t\t'key' => 'field_$$((base_key + 1))',\n\t\t\t\t\t'label' => 'Image',\n\t\t\t\t\t'name' => 'image',\n\t\t\t\t\t'aria-label' => '',\n\t\t\t\t\t'type' => 'image',\n\t\t\t\t\t'instructions' => '',\n\t\t\t\t\t'required' => 0,\n\t\t\t\t\t'conditional_logic' => 0,\n\t\t\t\t\t'wrapper' => array(\n\t\t\t\t\t\t'width' => '',\n\t\t\t\t\t\t'class' => '',\n\t\t\t\t\t\t'id' => '',\n\t\t\t\t\t),\n\t\t\t\t\t'return_format' => 'array',\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'key' => 'field_$$((base_key + 2))',\n\t\t\t\t\t'label' => 'Texte',\n\t\t\t\t\t'name' => 'texte',\n\t\t\t\t\t'aria-label' => '',\n\t\t\t\t\t'type' => 'textarea',\n\t\t\t\t\t'instructions' => '',\n\t\t\t\t\t'required' => 0,\n\t\t\t\t\t'conditional_logic' => 0,\n\t\t\t\t\t'wrapper' => array(\n\t\t\t\t\t\t'width' => '',\n\t\t\t\t\t\t'class' => '',\n\t\t\t\t\t\t'id' => '',\n\t\t\t\t\t),\n\t\t\t\t\t'default_value' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',\n\t\t\t\t\t'maxlength' => '',\n\t\t\t\t\t'placeholder' => '',\n\t\t\t\t\t'rows' => '',\n\t\t\t\t\t'new_lines' => '',\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'key' => 'field_$$((base_key + 3))',\n\t\t\t\t\t'label' => 'Texte du bouton',\n\t\t\t\t\t'name' => 'texte_bouton',\n\t\t\t\t\t'aria-label' => '',\n\t\t\t\t\t'type' => 'text',\n\t\t\t\t\t'instructions' => '',\n\t\t\t\t\t'required' => 0,\n\t\t\t\t\t'conditional_logic' => 0,\n\t\t\t\t\t'wrapper' => array(\n\t\t\t\t\t\t'width' => '',\n\t\t\t\t\t\t'class' => '',\n\t\t\t\t\t\t'id' => '',\n\t\t\t\t\t),\n\t\t\t\t\t'default_value' => 'En savoir plus',\n\t\t\t\t\t'maxlength' => '',\n\t\t\t\t\t'placeholder' => '',\n\t\t\t\t\t'prepend' => '',\n\t\t\t\t\t'append' => '',\n\t\t\t\t),\n\t\t\t\tarray(\n\t\t\t\t\t'key' => 'field_$$((base_key + 4))',\n\t\t\t\t\t'label' => 'Lien du bouton',\n\t\t\t\t\t'name' => 'lien_bouton',\n\t\t\t\t\t'aria-label' => '',\n\t\t\t\t\t'type' => 'url',\n\t\t\t\t\t'instructions' => '',\n\t\t\t\t\t'required' => 0,\n\t\t\t\t\t'conditional_logic' => 0,\n\t\t\t\t\t'wrapper' => array(\n\t\t\t\t\t\t'width' => '',\n\t\t\t\t\t\t'class' => '',\n\t\t\t\t\t\t'id' => '',\n\t\t\t\t\t),\n\t\t\t\t\t'default_value' => '#',\n\t\t\t\t\t'placeholder' => '',\n\t\t\t\t),\n\t\t\t),\n\t\t)," > "$$temp_file"; \
				fi; \
				;; \
		esac; \
		# Conserver la syntaxe array(...) comme dans l'exemple souhaité \
		# Insérer le groupe dans $(THEME)/app/acf/$$page_slug.php via PHP (entre 'fields' et 'location') \
		php_script="/tmp/insert_acf_$$RANDOM.php"; \
		cat > "$$php_script" <<-'PHP'
		<?php
		$$file = $$argv[1];
		$$addFile = $$argv[2];
		$$code = file_get_contents($$file);
		$$addition = rtrim(file_get_contents($$addFile));
		// Gérer 'fields' => array(...) ou 'fields' => [...] et insérer avant 'location'
		$$pattern = "/('fields'\\s*=>\\s*(?:array\\(|\\[))(.*?)(?:\)\\s*,\\s*\\n\\s*'location'|\\]\\s*,\\s*\\n\\s*'location')/s";
		$$replaced = preg_replace_callback($$pattern, function ($$m) use ($$addition) {
			$$inside = rtrim($$m[2]);
			if ($$inside !== '' && substr(rtrim($$inside), -1) !== ',') {
				$$inside .= ",\n";
			}
			// Reconstruire proprement: $$m[0] commence après l'ouverture et s'arrête juste avant location; on doit réintroduire la fermeture correspondante
			$$opening = $$m[1];
			$$closing = (strpos($$opening, 'array(') !== false) ? ")\n" : "]\n";
			// Ajouter la virgule avant 'location' pour une syntaxe valide
			return $$opening . $$inside . $$addition . "\n" . $$closing . ",\n\t\t\t\t" . "'location'";
		}, $$code, 1);
		if ($$replaced === null) {
			fwrite(STDERR, "preg_replace failed\n");
			exit(2);
		}
		if ($$replaced === $$code) {
			fwrite(STDERR, "no match for fields/location block\n");
			exit(3);
		}
		file_put_contents($$file, $$replaced);
		PHP
		php "$$php_script" "$$acf_file" "$$temp_file"; status=$$?; \
		rm -f "$$php_script" "$$temp_file"; \
		if [ $$status -ne 0 ]; then echo "❌ Insertion ACF échouée"; exit $$status; fi; \
		echo "✅ Champs ACF insérés dans $$acf_file"; \
	else \
		echo "⚠️  Fichier ACF non trouvé: $$acf_file"; \
	fi; \
	# (supprimé) Gestion SCSS — plus nécessaire, import automatique \
	# Ajouter le composant dans le template Blade (doublons autorisés) \
	blade_file="$(THEME)/resources/views/pages/$$page_slug.blade.php"; \
	if [ -f "$$blade_file" ]; then \
		echo "🧩 Ajout du composant dans le template Blade..."; \
		case "$$component_name" in \
			"titre-texte") \
				sed -i "/^@endsection/i\\  @include('components.titre-texte', ['composant_data' => get_field('$$unique_group_field_name')])\n" "$$blade_file"; \
				echo "✅ Composant ajouté au template Blade"; \
				;; \
			"image-texte-bouton") \
				sed -i "/^@endsection/i\\  @include('components.image-texte-bouton', ['composant_data' => get_field('$$unique_group_field_name')])\n" "$$blade_file"; \
				echo "✅ Composant ajouté au template Blade"; \
				;; \
		esac; \
	else \
		echo "⚠️  Fichier Blade non trouvé: $$blade_file"; \
	fi; \
		echo "🎉 Composant $$component_name ajouté à la page $$page_title !"

branch: ### créer branch
	$(eval name ?= branch)
	git branch $(name)
	git checkout $(name)
	git add .
	git commit -m "new branch $(name)"
	git push -u origin $(name)

pull: ### pull main
	git checkout main
	git pull

asset-dev: ## lance Vite en mode développement
	cd $(THEME) && npm run dev

asset-build: ## build de production avec Vite
	cd $(THEME) && npm run build

install-theme:
	composer require roots/acorn
	cd web/app/themes && composer create-project roots/sage $(NAME) --no-interaction
	cd $(THEME) && npm install
	cd $(THEME) && npm uninstall -D @tailwindcss/vite tailwindcss || true
	cd $(THEME) && npm install -D sass typescript @types/node
	cd $(THEME) && npm install -D eslint @eslint/js typescript-eslint stylelint stylelint-config-standard-scss prettier prettier-plugin-blade

	mv $(THEME)/resources/css/app.css $(THEME)/resources/css/app.scss
	mv $(THEME)/resources/css/editor.css $(THEME)/resources/css/editor.scss
	echo "" > $(THEME)/resources/css/editor.scss
	rm -f $(THEME)/tailwind.config.js
	sed -i "/import .*tailwindcss/d" $(THEME)/vite.config.js
	sed -i "s/tailwindcss(),//" $(THEME)/vite.config.js
	sed -i "s/app\.css/app.scss/g" $(THEME)/vite.config.js
	sed -i "s/editor\.css/editor.scss/g" $(THEME)/vite.config.js
	sed -i "s/disableTailwindColors: false/disableTailwindColors: true/" $(THEME)/vite.config.js
	sed -i "s/disableTailwindFonts: false/disableTailwindFonts: true/" $(THEME)/vite.config.js
	sed -i "s/disableTailwindFontSizes: false/disableTailwindFontSizes: true/" $(THEME)/vite.config.js
	sed -i "s/app\.css/app.scss/" $(THEME)/resources/views/layouts/app.blade.php
	sed -i "s/editor\.css/editor.scss/" $(THEME)/app/setup.php
	# Ajouter @stack('vite-head') après @vite dans le layout pour permettre aux pages d'ajouter leurs assets
	sed -i "/@vite.*app\.scss/a\    @stack('vite-head')" $(THEME)/resources/views/layouts/app.blade.php
	# Ajouter la configuration ACF pour l'export JSON
	@echo '' >> $(THEME)/app/setup.php
	@echo '/**' >> $(THEME)/app/setup.php
	@echo ' * Configure ACF to save JSON files in the theme directory.' >> $(THEME)/app/setup.php
	@echo ' * This allows versioning ACF field groups in Git.' >> $(THEME)/app/setup.php
	@echo ' *' >> $(THEME)/app/setup.php
	@echo ' * @return void' >> $(THEME)/app/setup.php
	@echo ' */' >> $(THEME)/app/setup.php
	@echo 'add_filter('\''acf/settings/save_json'\'', function ($$path) {' >> $(THEME)/app/setup.php
	@echo '    // Save JSON files in the theme'\''s acf-json directory' >> $(THEME)/app/setup.php
	@echo '    $$path = get_stylesheet_directory() . '\''/acf-json'\'';' >> $(THEME)/app/setup.php
	@echo '    ' >> $(THEME)/app/setup.php
	@echo '    // Create directory if it doesn'\''t exist' >> $(THEME)/app/setup.php
	@echo '    if (!file_exists($$path)) {' >> $(THEME)/app/setup.php
	@echo '        wp_mkdir_p($$path);' >> $(THEME)/app/setup.php
	@echo '    }' >> $(THEME)/app/setup.php
	@echo '    ' >> $(THEME)/app/setup.php
	@echo '    return $$path;' >> $(THEME)/app/setup.php
	@echo '});' >> $(THEME)/app/setup.php
	@echo '' >> $(THEME)/app/setup.php
	@echo 'add_filter('\''acf/settings/load_json'\'', function ($$paths) {' >> $(THEME)/app/setup.php
	@echo '    // Load JSON files from the theme'\''s acf-json directory' >> $(THEME)/app/setup.php
	@echo '    $$paths[] = get_stylesheet_directory() . '\''/acf-json'\'';' >> $(THEME)/app/setup.php
	@echo '    ' >> $(THEME)/app/setup.php
	@echo '    return $$paths;' >> $(THEME)/app/setup.php
	@echo '});' >> $(THEME)/app/setup.php
	# Créer le répertoire acf-json
	@mkdir -p $(THEME)/acf-json
	@touch $(THEME)/acf-json/.gitkeep
	@echo "🎨 Thème Sage installé avec Vite et SCSS prêt à compiler"
	mkdir -p $(THEME)/resources/css/pages
	mkdir -p $(THEME)/resources/css/utilities
	mkdir -p $(THEME)/resources/css/components
	# Copier les bases CSS (compat css_base ou répertoires dédiés)
	@mkdir -p $(THEME)/resources/css
	@if [ -d ./css_base ]; then \
		echo "➡️  Copie de css_base/* vers $(THEME)/resources/css/"; \
		cp -r ./css_base/* $(THEME)/resources/css/; \
	else \
		if [ -d ./utilities ]; then \
			echo "➡️  Copie de utilities/* vers $(THEME)/resources/css/utilities/"; \
			mkdir -p $(THEME)/resources/css/utilities; \
			cp -r ./utilities/* $(THEME)/resources/css/utilities/; \
		fi; \
		if [ -d ./variables ]; then \
			echo "➡️  Copie de variables/* vers $(THEME)/resources/css/variables/"; \
			mkdir -p $(THEME)/resources/css/variables; \
			cp -r ./variables/* $(THEME)/resources/css/variables/; \
		fi; \
		if [ -d ./functions ]; then \
			echo "➡️  Copie de functions/* vers $(THEME)/resources/css/functions/"; \
			mkdir -p $(THEME)/resources/css/functions; \
			cp -r ./functions/* $(THEME)/resources/css/functions/; \
		fi; \
	fi; \
	if [ -d ./components ]; then \
		echo "➡️  Copie de components/* vers $(THEME)/resources/css/components/"; \
		mkdir -p $(THEME)/resources/css/components; \
		cp -r ./components/* $(THEME)/resources/css/components/; \
	fi
	# Générer le fichier d'entrée app.scss avec les imports utilitaires
	@printf '%s\n' \
	"@use 'utilities/index' as *;" \
	"@use 'utilities/reset';" \
	"@use 'utilities/base';" \
	"@use 'utilities/sanitize';" \
	"@use 'utilities/sanitize_assets';" \
	"@use 'utilities/sanitize_forms';" \
	"@use 'components/button';" \
	"@use 'components/title';" \
	"@use 'components/container';" \
	"@use 'components/text';" \
	> $(THEME)/resources/css/app.scss
	mkdir -p $(THEME)/resources/views/components
	mkdir -p $(THEME)/resources/views/pages
	@echo "📁 Architecture SCSS créée : pages, utilities, components"
	@echo "📁 Architecture Blade créée : components, pages"
	@echo "📜 Configuration TypeScript..."
	mv $(THEME)/resources/js/app.js $(THEME)/resources/js/app.ts
	mv $(THEME)/resources/js/editor.js $(THEME)/resources/js/editor.ts
	sed -i "s/app\.js/app.ts/" $(THEME)/resources/views/layouts/app.blade.php
	sed -i "s/editor\.js/editor.ts/" $(THEME)/app/setup.php
	@echo "✅ TypeScript configuré"
	# Créer le fichier tsconfig.json
	@printf '%s\n' \
	'{' \
	'  "compilerOptions": {' \
	'    "target": "ES2022",' \
	'    "module": "ESNext",' \
	'    "lib": ["ES2022", "DOM", "DOM.Iterable"],' \
	'    "moduleResolution": "bundler",' \
	'    "resolveJsonModule": true,' \
	'    "allowJs": true,' \
	'    "checkJs": false,' \
	'    "strict": true,' \
	'    "noEmit": true,' \
	'    "esModuleInterop": true,' \
	'    "skipLibCheck": true,' \
	'    "forceConsistentCasingInFileNames": true,' \
	'    "isolatedModules": true,' \
	'    "types": ["node"]' \
	'  },' \
	'  "include": ["resources/js/**/*"],' \
	'  "exclude": ["node_modules", "vendor", "public"]' \
	'}' \
	> $(THEME)/tsconfig.json
	@echo "🔧 Configuration des linters..."
	# Créer le fichier .stylelintrc.json
	@printf '%s\n' \
	'{' \
	'  "extends": [' \
	'    "stylelint-config-standard-scss"' \
	'  ],' \
	'  "rules": {' \
	'    "color-hex-length": "short",' \
	'    "color-named": "never",' \
	'    "declaration-no-important": true,' \
	'    "font-weight-notation": "numeric",' \
	'    "property-no-vendor-prefix": true,' \
	'    "value-no-vendor-prefix": true,' \
	'    "no-empty-source": null,' \
	'    "scss/dollar-variable-colon-space-after": "always",' \
	'    "scss/dollar-variable-colon-space-before": "never"' \
	'  },' \
	'  "ignoreFiles": [' \
	'    "node_modules/**",' \
	'    "vendor/**",' \
	'    "public/**"' \
	'  ]' \
	'}' \
	> $(THEME)/.stylelintrc.json
	# Créer le fichier eslint.config.js
	@printf '%s\n' \
	'import js from '\''@eslint/js'\'';' \
	'import tseslint from '\''typescript-eslint'\'';' \
	'' \
	'export default tseslint.config(' \
	'  {' \
	'    ignores: ['\''node_modules/**'\'', '\''vendor/**'\'', '\''public/**'\'', '\''*.config.js'\''],' \
	'  },' \
	'  js.configs.recommended,' \
	'  ...tseslint.configs.recommended,' \
	'  {' \
	'    languageOptions: {' \
	'      parser: tseslint.parser,' \
	'      parserOptions: {' \
	'        ecmaVersion: 2022,' \
	'        sourceType: '\''module'\'',' \
	'        project: '\''./tsconfig.json'\'',' \
	'      },' \
	'      globals: {' \
	'        window: '\''readonly'\'',' \
	'        document: '\''readonly'\'',' \
	'        console: '\''readonly'\'',' \
	'      },' \
	'    },' \
	'    rules: {' \
	'      '\''@typescript-eslint/no-unused-vars'\'': [' \
	'        '\''error'\'',' \
	'        {' \
	'          argsIgnorePattern: '\''^_'\'',' \
	'          varsIgnorePattern: '\''^_'\'',' \
	'        },' \
	'      ],' \
	'      '\''@typescript-eslint/explicit-module-boundary-types'\'': '\''off'\'',' \
	'      '\''@typescript-eslint/no-explicit-any'\'': '\''warn'\'',' \
	'    },' \
	'  }' \
	');' \
	> $(THEME)/eslint.config.js
	# Créer le fichier .prettierrc.json
	@printf '%s\n' \
	'{' \
	'  "plugins": ["prettier-plugin-blade"],' \
	'  "printWidth": 100,' \
	'  "tabWidth": 2,' \
	'  "useTabs": false,' \
	'  "semi": true,' \
	'  "singleQuote": true,' \
	'  "trailingComma": "es5"' \
	'}' \
	> $(THEME)/.prettierrc.json
	@echo "✅ Linters configurés"


	
recup-theme: ## récupère et met à jour les dépendances du thème
	composer install
	cd $(THEME) && composer install
	cd $(THEME) && npm install
	@echo "✅ Dépendances du thème mises à jour"

stop:
	docker compose stop
	fuser -k 8000/tcp || true

## —— Déploiement ——————————————————————————————————

setup-ssh: ## Configure les clés SSH pour l'authentification sans mot de passe
	@set -e; \
	echo "🔐 Configuration des clés SSH..."; \
	echo ""; \
	ssh_host="$${SSH_HOST}"; if [ -z "$$ssh_host" ]; then printf "Host SSH (ex: user@example.com): "; read ssh_host; fi; \
	ssh_port="$${SSH_PORT}"; if [ -z "$$ssh_port" ]; then printf "Port SSH (Entrée pour 22): "; read ssh_port; fi; \
	if [ -z "$$ssh_port" ]; then ssh_port=22; fi; \
	echo ""; \
	# Vérifier si une clé SSH existe déjà \
	ssh_key="$$HOME/.ssh/id_rsa"; \
	ssh_key_pub="$$HOME/.ssh/id_rsa.pub"; \
	if [ ! -f "$$ssh_key" ] || [ ! -f "$$ssh_key_pub" ]; then \
		echo "🔑 Génération d'une nouvelle clé SSH..."; \
		ssh-keygen -t rsa -b 4096 -f "$$ssh_key" -N "" -C "$$(whoami)@$$(hostname)" || (echo "❌ Erreur génération clé SSH"; exit 1); \
		echo "✅ Clé SSH générée"; \
	else \
		echo "✅ Clé SSH existante trouvée: $$ssh_key"; \
	fi; \
	echo ""; \
	# Copier la clé publique sur le serveur \
	echo "📤 Copie de la clé publique sur le serveur..."; \
	ssh-copy-id -p $$ssh_port $$ssh_host 2>/dev/null || \
	( \
		echo "⚠️  ssh-copy-id non disponible, tentative manuelle..."; \
		cat $$ssh_key_pub | ssh -p $$ssh_port $$ssh_host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" || \
		(echo "❌ Erreur copie clé SSH. Vérifiez votre accès SSH."; exit 1) \
	); \
	echo "✅ Clé SSH copiée sur le serveur"; \
	echo ""; \
	# Tester la connexion \
	echo "🧪 Test de la connexion SSH..."; \
	ssh -p $$ssh_port -o BatchMode=yes -o ConnectTimeout=5 $$ssh_host "echo 'Connexion SSH réussie'" 2>/dev/null && \
	echo "✅ Connexion SSH sans mot de passe configurée avec succès !" || \
	(echo "⚠️  La connexion SSH nécessite encore un mot de passe. Vérifiez les permissions sur le serveur."; exit 1); \
	echo ""; \
	echo "🎉 Configuration SSH terminée !"

deploy-first: ## Déploiement initial automatique (première mise en ligne)
	@set -e; \
	echo "🚀 Déploiement initial du projet"; \
	echo ""; \
	\
	# Lire les informations de la base de données locale depuis .env et docker-compose.yaml \
	echo "📊 Lecture de la configuration locale..."; \
	if [ -f .env ]; then \
		local_db_name=$$(grep -E "^DB_NAME=" .env 2>/dev/null | cut -d'=' -f2 | tr -d '"' | tr -d "'" | tr -d ' ' | head -1); \
		local_db_user=$$(grep -E "^DB_USER=" .env 2>/dev/null | cut -d'=' -f2 | tr -d '"' | tr -d "'" | tr -d ' ' | head -1); \
		local_db_password=$$(grep -E "^DB_PASSWORD=" .env 2>/dev/null | cut -d'=' -f2 | tr -d '"' | tr -d "'" | tr -d ' ' | head -1); \
	fi; \
	# Compléter depuis docker-compose.yaml si nécessaire \
	if [ -f docker-compose.yaml ]; then \
		if [ -z "$$local_db_name" ]; then \
			local_db_name=$$(grep -E "MYSQL_DATABASE:" docker-compose.yaml 2>/dev/null | cut -d':' -f2 | tr -d '"' | tr -d "'" | tr -d ' ' | head -1); \
		fi; \
		if [ -z "$$local_db_password" ]; then \
			local_db_password=$$(grep -E "MYSQL_ROOT_PASSWORD:" docker-compose.yaml 2>/dev/null | cut -d':' -f2 | tr -d '"' | tr -d "'" | tr -d ' ' | head -1); \
		fi; \
	fi; \
	# Valeurs par défaut si non trouvées \
	local_db_name="$${local_db_name:-wp}"; \
	local_db_user="$${local_db_user:-root}"; \
	local_db_password="$${local_db_password:-password}"; \
	echo "  ✅ Base locale détectée: $$local_db_user@docker/$$local_db_name"; \
	echo ""; \
	# Demander les informations de base de données DISTANTE (production) \
	echo "📊 Informations de base de données DISTANTE (production) :"; \
	db_host="$${DB_HOST}"; if [ -z "$$db_host" ]; then printf "  Host de la BDD (ex: localhost): "; read db_host; fi; \
	db_user="$${DB_USER}"; if [ -z "$$db_user" ]; then printf "  Utilisateur de la BDD: "; read db_user; fi; \
	db_password="$${DB_PASSWORD}"; if [ -z "$$db_password" ]; then printf "  Mot de passe de la BDD: "; stty -echo; read db_password; stty echo; echo ""; fi; \
	db_name="$${DB_NAME}"; if [ -z "$$db_name" ]; then printf "  Nom de la base de données: "; read db_name; fi; \
	echo ""; \
	\
	# Demander les informations SSH \
	echo "🔐 Informations SSH :"; \
	ssh_host="$${SSH_HOST}"; if [ -z "$$ssh_host" ]; then printf "  Host SSH (ex: user@example.com): "; read ssh_host; fi; \
	ssh_port="$${SSH_PORT}"; if [ -z "$$ssh_port" ]; then printf "  Port SSH (Entrée pour 22): "; read ssh_port; fi; \
	if [ -z "$$ssh_port" ]; then ssh_port=22; fi; \
	echo ""; \
	# Vérifier et configurer SSH si nécessaire \
	echo "🔐 Vérification de la configuration SSH..."; \
	if ! ssh -p $$ssh_port -o BatchMode=yes -o ConnectTimeout=5 $$ssh_host "echo 'test'" >/dev/null 2>&1; then \
		echo "⚠️  Connexion SSH nécessite un mot de passe. Configuration des clés SSH..."; \
		SSH_HOST=$$ssh_host SSH_PORT=$$ssh_port make setup-ssh || (echo "❌ Échec configuration SSH"; exit 1); \
		echo ""; \
	fi; \
	\
	# Demander l'URL \
	echo "🌐 Informations du site :"; \
	site_url="$${SITE_URL}"; if [ -z "$$site_url" ]; then printf "  URL du site (ex: example.com): "; read site_url; fi; \
	# Enlever https:// et http:// si présent \
	site_url=$$(echo "$$site_url" | sed 's|^https\?://||'); \
	echo ""; \
	\
	# Demander le dossier racine \
	echo "📁 Dossier racine du projet :"; \
	remote_dir="$${REMOTE_DIR}"; if [ -z "$$remote_dir" ]; then printf "  Dossier racine (Entrée pour ~/www): "; read remote_dir; fi; \
	if [ -z "$$remote_dir" ]; then remote_dir="~/www"; fi; \
	# Détecter le home de l'utilisateur SSH \
	ssh_home=$$(ssh -p $$ssh_port $$ssh_host "echo \$$HOME" 2>/dev/null || echo ""); \
	if [ -z "$$ssh_home" ]; then \
		# Extraire le nom d'utilisateur depuis ssh_host \
		ssh_user=$$(echo "$$ssh_host" | cut -d'@' -f1); \
		ssh_home="/home/$$ssh_user"; \
	fi; \
	# Gérer les chemins relatifs et ~ \
	if echo "$$remote_dir" | grep -q "^~/"; then \
		remote_dir=$$(echo "$$remote_dir" | sed "s|^~|$$ssh_home|"); \
	elif [ "$${remote_dir#/}" = "$$remote_dir" ]; then \
		# Chemin relatif, ajouter au home \
		remote_dir="$$ssh_home/$$remote_dir"; \
	fi; \
	echo "  Chemin complet: $$remote_dir"; \
	echo ""; \
	\
	echo "✅ Configuration :"; \
	echo "  BDD: $$db_user@$$db_host/$$db_name"; \
	echo "  SSH: $$ssh_host:$$ssh_port"; \
	echo "  URL: https://$$site_url"; \
	echo "  Dossier: $$remote_dir"; \
	echo ""; \
	read -p "Continuer ? (o/N): " confirm; \
	if [ "$$confirm" != "o" ] && [ "$$confirm" != "O" ]; then \
		echo "❌ Déploiement annulé"; \
		exit 1; \
	fi; \
	echo ""; \
	\
	# Préparer le projet pour la production \
	echo "📦 Préparation du projet pour la production..."; \
	composer install --no-dev --optimize-autoloader || (echo "⚠️  Erreur composer install"; exit 1); \
	theme_path="$(THEME)"; \
	if [ -d "$$theme_path" ]; then \
		echo "📦 Compilation des assets du thème..."; \
		(cd $$theme_path && npm ci && npm run build) || (echo "⚠️  Erreur compilation du thème"; exit 1); \
		echo "✅ Assets du thème compilés"; \
	else \
		echo "⚠️  Thème $$theme_path non trouvé, compilation des assets ignorée"; \
	fi; \
	echo "✅ Projet préparé pour la production"; \
	echo ""; \
	\
	# Exporter la base de données locale depuis Docker \
	echo "💾 Export de la base de données locale depuis Docker..."; \
	sql_file="/tmp/deploy_$$(date +%s).sql"; \
	if ! command -v docker >/dev/null 2>&1; then \
		echo "❌ Docker n'est pas installé. Impossible d'exporter la base de données."; \
		exit 1; \
	fi; \
	if ! docker compose ps database 2>/dev/null | grep -q "Up"; then \
		echo "⚠️  Le conteneur Docker 'database' n'est pas démarré."; \
		echo "   Démarrage du conteneur..."; \
		docker compose up -d database || (echo "❌ Impossible de démarrer le conteneur Docker."; exit 1); \
		echo "   Attente que la base soit prête..."; \
		sleep 5; \
	fi; \
	echo "  Export depuis Docker ($$local_db_user@database/$$local_db_name)..."; \
	docker compose exec -T database mysqldump -u$$local_db_user -p$$local_db_password $$local_db_name > "$$sql_file" 2>/dev/null || \
	(echo "❌ Erreur export BDD depuis Docker."; \
	echo "   Vérifiez que le conteneur est démarré: docker compose ps"; \
	echo "   Identifiants utilisés: $$local_db_user@database/$$local_db_name"; \
	exit 1); \
	echo "✅ Base de données exportée: $$sql_file"; \
	echo ""; \
	\
	# Modifier les URLs dans le fichier SQL \
	echo "🔧 Modification des URLs dans le fichier SQL..."; \
	sed -i "s|http://localhost:8000|https://$$site_url|g" "$$sql_file"; \
	sed -i "s|localhost:8000|$$site_url|g" "$$sql_file"; \
	echo "✅ URLs modifiées (http://localhost:8000 → https://$$site_url)"; \
	echo ""; \
	\
	# Récupérer automatiquement l'URL Git depuis les remotes configurés \
	echo "🔍 Récupération de l'URL Git..."; \
	git_url="$${GIT_URL}"; \
	if [ -z "$$git_url" ]; then \
		# Essayer de récupérer depuis les remotes dans l'ordre : ovh, origin, puis le premier disponible \
		git_url=$$(git remote get-url ovh 2>/dev/null || git remote get-url origin 2>/dev/null || git remote | head -1 | xargs -I {} git remote get-url {} 2>/dev/null || echo ""); \
	fi; \
	if [ -z "$$git_url" ]; then \
		echo "⚠️  Aucun remote Git trouvé localement"; \
		printf "  URL du dépôt Git: "; read git_url; \
	fi; \
	# Convertir les alias SSH locaux (github-pro, github-perso) en URL GitHub réelle \
	if echo "$$git_url" | grep -q "^git@github-pro:"; then \
		echo "⚠️  Alias SSH local détecté (github-pro), conversion en github.com..."; \
		git_url=$$(echo "$$git_url" | sed 's|^git@github-pro:|git@github.com:|'); \
	elif echo "$$git_url" | grep -q "^git@github-perso:"; then \
		echo "⚠️  Alias SSH local détecté (github-perso), conversion en github.com..."; \
		git_url=$$(echo "$$git_url" | sed 's|^git@github-perso:|git@github.com:|'); \
	fi; \
	# Convertir l'URL HTTPS en SSH si nécessaire (pour GitHub, GitLab, etc.) \
	if echo "$$git_url" | grep -q "^https://"; then \
		echo "⚠️  URL HTTPS détectée, conversion en SSH recommandée pour l'authentification"; \
		git_url=$$(echo "$$git_url" | sed 's|^https://\([^/]*\)/\(.*\)|git@\1:\2|'); \
	fi; \
	echo "📦 URL Git détectée: $$git_url"; \
	echo ""; \
	\
	# Configurer GitHub SSH sur le serveur si nécessaire \
	if echo "$$git_url" | grep -q "github.com"; then \
		echo "🔐 Configuration de GitHub SSH sur le serveur..."; \
		# Ajouter la clé GitHub au known_hosts \
		ssh -p $$ssh_port $$ssh_host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && \
			if ! grep -q 'github.com' ~/.ssh/known_hosts 2>/dev/null; then \
				ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2>/dev/null || \
				echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOXUCHiWpEvvwdwdTZ6Y0sZgnZJ39WnNkK5atdlQq2gxkzFhq2T3WSJmrVQYTMwgmIDX9/0d2acBjosZNgFcxiPY968lcFUV6LzIXONrE9E3fB2n9Hfhsm4QU8dGCvggzPpffOnguDBra5G85IrEjD+ZMoK1fOQtm3MFoKZsEnvZ3MzyXPX1z0hvhMlzHNaHyXGpzFoDZX6PBgoL32oqQVv8uzjvdjdTeP4Li2d4fht/a7lg4z+4C+42IAHlFmvi9B42LokNCw==' >> ~/.ssh/known_hosts 2>/dev/null; \
				chmod 600 ~/.ssh/known_hosts 2>/dev/null || true; \
			fi" || true; \
		# Vérifier si une clé SSH existe déjà pour GitHub \
		server_has_github_key=$$(ssh -p $$ssh_port $$ssh_host "test -f ~/.ssh/id_rsa.pub -o -f ~/.ssh/id_ed25519.pub" 2>/dev/null && echo "yes" || echo "no"); \
		if [ "$$server_has_github_key" = "no" ]; then \
			echo "🔑 Génération d'une clé SSH sur le serveur pour GitHub..."; \
			ssh -p $$ssh_port $$ssh_host "ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N '' -C 'server@github' 2>/dev/null || ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N '' -C 'server@github' 2>/dev/null || true"; \
		fi; \
		# Récupérer la clé publique \
		server_ssh_key=$$(ssh -p $$ssh_port $$ssh_host "cat ~/.ssh/id_ed25519.pub 2>/dev/null || cat ~/.ssh/id_rsa.pub 2>/dev/null || echo ''" 2>/dev/null); \
		if [ -n "$$server_ssh_key" ]; then \
			echo ""; \
			echo "📋 IMPORTANT : Pour que le clonage GitHub fonctionne, vous devez ajouter cette clé SSH à votre compte GitHub :"; \
			echo ""; \
			echo "$$server_ssh_key"; \
			echo ""; \
			echo "  1. Copiez la clé ci-dessus"; \
			echo "  2. Allez sur https://github.com/settings/keys"; \
			echo "  3. Cliquez sur 'New SSH key'"; \
			echo "  4. Collez la clé et sauvegardez"; \
			echo ""; \
			printf "Appuyez sur Entrée une fois la clé ajoutée à GitHub..."; \
			read dummy; \
		fi; \
		echo ""; \
	fi; \
	# Vérifier si le projet existe déjà sur le serveur \
	echo "🔍 Vérification du projet sur le serveur..."; \
	if ssh -p $$ssh_port $$ssh_host "[ -d $$remote_dir ]" 2>/dev/null; then \
		echo "📁 Le dossier $$remote_dir existe déjà"; \
		if ssh -p $$ssh_port $$ssh_host "[ -d $$remote_dir/.git ]" 2>/dev/null; then \
			echo "✅ Dépôt Git déjà présent, mise à jour..."; \
			ssh -p $$ssh_port $$ssh_host "cd $$remote_dir && git fetch --all && git reset --hard origin/main || git reset --hard ovh/main || git reset --hard HEAD" || true; \
		else \
			echo "📥 Clonage du projet dans le dossier existant ($$remote_dir)..."; \
			ssh -p $$ssh_port $$ssh_host "cd $$remote_dir && git clone $$git_url ." || (echo "⚠️  Erreur clonage, dossier non vide ?"; exit 1); \
			echo "✅ Projet cloné"; \
		fi; \
	else \
		echo "📁 Création du dossier $$remote_dir..."; \
		ssh -p $$ssh_port $$ssh_host "mkdir -p $$remote_dir"; \
		echo "📥 Clonage du projet dans $$remote_dir..."; \
		ssh -p $$ssh_port $$ssh_host "cd $$remote_dir && git clone $$git_url ." || (echo "❌ Erreur lors du clonage"; exit 1); \
		echo "✅ Projet cloné"; \
	fi; \
	# Configurer le remote pour utiliser SSH si nécessaire \
	echo "🔧 Configuration des remotes Git sur le serveur..."; \
	ssh -p $$ssh_port $$ssh_host "cd $$remote_dir && \
		(git remote remove origin 2>/dev/null || true) && \
		git remote add origin $$git_url && \
		(git remote remove ovh 2>/dev/null || true) && \
		git remote add ovh $$git_url 2>/dev/null || true && \
		git remote -v" || echo "⚠️  Erreur configuration remotes"; \
	echo "✅ Remotes Git configurés"; \
	echo ""; \
	\
	# Envoyer les fichiers du projet (assets compilés, sans vendor) \
	echo "📤 Envoi des fichiers du projet..."; \
	theme_path="$(THEME)"; \
	build_dir="$$theme_path/public/build"; \
	if [ -d "$$build_dir" ]; then \
		echo "  📦 Dossier d'assets compilés trouvé: $$build_dir"; \
	else \
		echo "  ⚠️  Dossier d'assets compilés non trouvé: $$build_dir"; \
		echo "  ⚠️  Les assets devront être compilés sur le serveur"; \
	fi; \
	rsync -avz --exclude='.git' --exclude='node_modules' --exclude='database' \
		--exclude='vendor' --exclude='.env' --exclude='*.log' -e "ssh -p $$ssh_port" \
		./ $$ssh_host:$$remote_dir/ || (echo "⚠️  Erreur rsync, tentative avec scp..."; \
		tar -czf /tmp/deploy_files.tar.gz --exclude='.git' --exclude='node_modules' \
		--exclude='database' --exclude='vendor' --exclude='.env' --exclude='*.log' . && \
		scp -P $$ssh_port /tmp/deploy_files.tar.gz $$ssh_host:$$remote_dir/ && \
		ssh -p $$ssh_port $$ssh_host "cd $$remote_dir && tar -xzf deploy_files.tar.gz && rm deploy_files.tar.gz"); \
	# Vérifier que les assets compilés sont bien présents sur le serveur \
	if [ -d "$$build_dir" ]; then \
		if ssh -p $$ssh_port $$ssh_host "[ -d $$remote_dir/$$build_dir ]" 2>/dev/null; then \
			echo "  ✅ Assets compilés vérifiés sur le serveur"; \
		else \
			echo "  ⚠️  Assets compilés non trouvés sur le serveur, ils seront compilés si npm est disponible"; \
		fi; \
	fi; \
	echo "✅ Fichiers envoyés"; \
	echo ""; \
	\
	# Envoyer le fichier SQL \
	echo "📤 Envoi du fichier SQL..."; \
	scp -P $$ssh_port "$$sql_file" $$ssh_host:$$remote_dir/database.sql || (echo "⚠️  Erreur envoi SQL"; exit 1); \
	echo "✅ Fichier SQL envoyé"; \
	echo ""; \
	\
	# Télécharger WP-CLI et Composer localement sur le serveur \
	echo "📥 Téléchargement de WP-CLI et Composer sur le serveur..."; \
	ssh -p $$ssh_port $$ssh_host "cd $$remote_dir && \
		(if [ ! -f wp-cli.phar ]; then \
			echo '📥 Téléchargement de WP-CLI...'; \
			curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar 2>/dev/null || \
			wget -q https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar 2>/dev/null || \
			echo '⚠️  Impossible de télécharger WP-CLI'; \
		fi) && \
		chmod +x wp-cli.phar 2>/dev/null || true && \
		(if [ ! -f composer.phar ]; then \
			echo '📥 Téléchargement de Composer...'; \
			php -r \"copy('https://getcomposer.org/installer', 'composer-setup.php');\" && \
			php composer-setup.php --quiet && \
			php -r \"unlink('composer-setup.php');\" 2>/dev/null || \
			(echo '⚠️  Téléchargement Composer via curl...' && \
			curl -sS https://getcomposer.org/installer | php 2>/dev/null || \
			echo '⚠️  Impossible de télécharger Composer'); \
		fi) && \
		chmod +x composer.phar 2>/dev/null || true" || echo "⚠️  Erreur téléchargement outils"; \
	echo "✅ WP-CLI et Composer téléchargés"; \
	echo ""; \
	\
	# Configuration sur le serveur \
	echo "⚙️  Configuration sur le serveur..."; \
	theme_path="$(THEME)"; \
	ssh -p $$ssh_port $$ssh_host "cd $$remote_dir && \
		if [ ! -f composer.phar ]; then \
			echo '❌ composer.phar non trouvé, téléchargement...'; \
			php -r \"copy('https://getcomposer.org/installer', 'composer-setup.php');\" && \
			php composer-setup.php --quiet && \
			php -r \"unlink('composer-setup.php');\" 2>/dev/null || \
			(echo '⚠️  Téléchargement Composer via curl...' && \
			curl -sS https://getcomposer.org/installer | php 2>/dev/null); \
			chmod +x composer.phar 2>/dev/null || true; \
		fi && \
		if [ ! -f composer.phar ]; then \
			echo '❌ Impossible de télécharger Composer'; \
			exit 1; \
		fi && \
		(if [ -d \"$$theme_path\" ]; then \
			npm_cmd=\$$(command -v npm 2>/dev/null || printf ''); \
			if [ -z \"\$$npm_cmd\" ]; then \
				echo '🔍 Récupération de la dernière version LTS de Node.js...'; \
				node_version=\"v20.18.0\"; \
				node_json=\"/tmp/nodejs_index_\$$(date +%s).json\"; \
				if curl -fsSL https://nodejs.org/dist/index.json -o \"\$$node_json\" 2>/dev/null || wget -q https://nodejs.org/dist/index.json -O \"\$$node_json\" 2>/dev/null; then \
					if [ -f \"\$$node_json\" ] && [ -s \"\$$node_json\" ]; then \
						node_version_extracted=\$$(grep -m 1 '\"lts\":' \"\$$node_json\" | head -1 | sed -n 's/.*\"version\":\"\\(v[0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][0-9]*\\)\".*/\\1/p'); \
						if [ -n \"\$$node_version_extracted\" ] && echo \"\$$node_version_extracted\" | grep -qE '^v[0-9]+\\.[0-9]+\\.[0-9]+$$'; then \
							node_version=\"\$$node_version_extracted\"; \
							echo \"📦 Version LTS détectée: \$$node_version\"; \
						fi; \
					fi; \
					rm -f \"\$$node_json\"; \
				fi; \
				if [ -z \"\$$node_version\" ]; then \
					node_version=\"v20.18.0\"; \
					echo '⚠️ Impossible de récupérer la version LTS, utilisation de v20.18.0'; \
				fi; \
				arch_name=\$$(uname -m); \
				if [ \"\$$arch_name\" = \"x86_64\" ] || [ \"\$$arch_name\" = \"amd64\" ]; then \
					node_arch=\"linux-x64\"; \
				elif [ \"\$$arch_name\" = \"aarch64\" ] || [ \"\$$arch_name\" = \"arm64\" ]; then \
					node_arch=\"linux-arm64\"; \
				else \
					node_arch=\"linux-x64\"; \
					echo '⚠️ Architecture non reconnue, utilisation de linux-x64'; \
				fi; \
				node_base=\"$$remote_dir/.nodejs\"; \
				node_dir=\"\$$node_base/node-\$$node_version-\$$node_arch\"; \
				if [ ! -x \"\$$node_dir/bin/npm\" ]; then \
					echo \"⚙️ Installation de Node.js \$$node_version...\"; \
					mkdir -p \"\$$node_base\" || (echo '❌ Erreur création répertoire'; exit 1); \
					tmp_node=\"/tmp/node-\$$node_version-\$$node_arch.tar.xz\"; \
					node_url=\"https://nodejs.org/dist/\$$node_version/node-\$$node_version-\$$node_arch.tar.xz\"; \
					if ! curl -fsSL \"\$$node_url\" -o \"\$$tmp_node\"; then \
						if ! wget -q \"\$$node_url\" -O \"\$$tmp_node\"; then \
							echo \"❌ Téléchargement Node.js échoué (\$$node_url)\"; \
							exit 1; \
						fi; \
					fi; \
					if [ ! -f \"\$$tmp_node\" ]; then \
						echo '❌ Fichier Node.js non téléchargé'; \
						exit 1; \
					fi; \
					tar -xJf \"\$$tmp_node\" -C \"\$$node_base\" || (echo '❌ Extraction Node.js échouée'; exit 1); \
					rm -f \"\$$tmp_node\"; \
				fi; \
				if [ ! -x \"\$$node_dir/bin/npm\" ]; then \
					echo '❌ npm non trouvé après installation'; \
					exit 1; \
				fi; \
				npm_cmd=\"\$$node_dir/bin/npm\"; \
				export PATH=\"\$$node_dir/bin:\$$PATH\"; \
			fi; \
			if [ -z \"\$$npm_cmd\" ] || [ ! -x \"\$$npm_cmd\" ]; then \
				echo '❌ npm indisponible, compilation ignorée'; \
			else \
				echo '📦 Compilation des assets du thème...'; \
				cd \"$$theme_path\" && \"\$$npm_cmd\" ci && \"\$$npm_cmd\" run build; \
			fi; \
		else \
			echo \"⚠️ Thème $$theme_path non trouvé, compilation ignorée\"; \
		fi) && \
		echo '📦 Installation des dépendances Composer à la racine...' && \
		php composer.phar install --no-dev --optimize-autoloader || (echo '❌ Erreur installation Composer racine'; exit 1) && \
		(if [ -d \"$$theme_path\" ] && [ -f \"$$theme_path/composer.json\" ]; then \
			echo '📦 Installation des dépendances Composer dans le thème...' && \
			cd \"$$theme_path\" && \
			php \"$$remote_dir/composer.phar\" install --no-dev --optimize-autoloader || (echo '❌ Erreur installation Composer thème'; exit 1); \
		fi)" || (echo "❌ Erreur lors de la configuration sur le serveur"; exit 1); \
	echo "✅ Configuration sur le serveur terminée"; \
	echo ""; \
	\
	# Créer le fichier .env sur le serveur en copiant le .env local et en remplaçant les valeurs \
	echo "📝 Création du fichier .env sur le serveur..."; \
	if [ ! -f .env ]; then \
		echo "⚠️  Fichier .env local non trouvé, création d'un .env minimal"; \
		env_temp="/tmp/env_temp_$$(date +%s).txt"; \
		touch "$$env_temp"; \
	else \
		env_temp="/tmp/env_temp_$$(date +%s).txt"; \
		cp .env "$$env_temp"; \
	fi; \
	# Transférer le .env local sur le serveur \
	scp -P $$ssh_port "$$env_temp" $$ssh_host:$$remote_dir/.env >/dev/null 2>&1 || (echo "⚠️  Erreur transfert .env"; rm -f "$$env_temp"; exit 1); \
	rm -f "$$env_temp"; \
	# Remplacer uniquement les valeurs spécifiques par celles de la production \
	# Créer un script de remplacement avec les valeurs déjà substituées \
	replace_script="/tmp/replace_env_$$(date +%s).sh"; \
	{ \
		echo "#!/bin/sh"; \
		echo "cd \"$$remote_dir\" || exit 1"; \
		echo "sed -i \"s|^DB_NAME=.*|DB_NAME='$$db_name'|\" .env"; \
		echo "sed -i \"s|^DB_USER=.*|DB_USER='$$db_user'|\" .env"; \
		echo "sed -i \"s|^DB_PASSWORD=.*|DB_PASSWORD='$$db_password'|\" .env"; \
		echo "sed -i \"s|^DB_HOST=.*|DB_HOST='$$db_host'|\" .env"; \
		echo "sed -i \"s|^WP_ENV=.*|WP_ENV='production'|\" .env"; \
		echo "sed -i \"s|^WP_HOME=.*|WP_HOME='https://$$site_url'|\" .env"; \
		echo "sed -i \"s|^WP_SITEURL=.*|WP_SITEURL=\\\\\\\"\${WP_HOME}/wp\\\\\\\"|\" .env"; \
		echo "grep -q '^DB_NAME=' .env || echo \"DB_NAME='$$db_name'\" >> .env"; \
		echo "grep -q '^DB_USER=' .env || echo \"DB_USER='$$db_user'\" >> .env"; \
		echo "grep -q '^DB_PASSWORD=' .env || echo \"DB_PASSWORD='$$db_password'\" >> .env"; \
		echo "grep -q '^DB_HOST=' .env || echo \"DB_HOST='$$db_host'\" >> .env"; \
		echo "grep -q '^WP_ENV=' .env || echo \"WP_ENV='production'\" >> .env"; \
		echo "grep -q '^WP_HOME=' .env || echo \"WP_HOME='https://$$site_url'\" >> .env"; \
		echo "grep -q '^WP_SITEURL=' .env || echo 'WP_SITEURL=\"\${WP_HOME}/wp\"' >> .env"; \
	} > "$$replace_script"; \
	chmod +x "$$replace_script"; \
	# Transférer et exécuter le script sur le serveur \
	scp -P $$ssh_port "$$replace_script" $$ssh_host:/tmp/replace_env.sh >/dev/null 2>&1 && \
	ssh -p $$ssh_port $$ssh_host "bash /tmp/replace_env.sh && rm -f /tmp/replace_env.sh" || echo "⚠️  Erreur configuration .env"; \
	rm -f "$$replace_script"; \
	echo "✅ Fichier .env configuré (copie du local avec valeurs de production)"; \
	echo ""; \
	\
	# Importer la base de données \
	echo "💾 Import de la base de données..."; \
	ssh -p $$ssh_port $$ssh_host "cd $$remote_dir && \
		(php wp-cli.phar db import database.sql --allow-root 2>/dev/null || \
		mysql -h'$$db_host' -u'$$db_user' -p'$$db_password' '$$db_name' < database.sql 2>/dev/null || \
		php wp-cli.phar db import database.sql --allow-root || \
		mysql -h'$$db_host' -u'$$db_user' -p'$$db_password' '$$db_name' < database.sql)" || echo "⚠️  Erreur import BDD - vérifiez manuellement"; \
	echo "✅ Base de données importée"; \
	echo ""; \
	\
	# Mettre à jour les URLs dans WordPress \
	echo "🔧 Mise à jour des URLs dans WordPress..."; \
	ssh -p $$ssh_port $$ssh_host "cd $$remote_dir && \
		php wp-cli.phar search-replace 'http://localhost:8000' 'https://$$site_url' --allow-root --all-tables && \
		php wp-cli.phar search-replace 'localhost:8000' '$$site_url' --allow-root --all-tables && \
		php wp-cli.phar option update home 'https://$$site_url' --allow-root && \
		php wp-cli.phar option update siteurl 'https://$$site_url/wp' --allow-root" || echo "⚠️  Erreur mise à jour URLs"; \
	echo "✅ URLs mises à jour"; \
	echo ""; \
	\
	# Nettoyer \
	echo "🧹 Nettoyage..."; \
	rm -f "$$sql_file"; \
	ssh -p $$ssh_port $$ssh_host "cd $$remote_dir && rm -f database.sql" || true; \
	echo "✅ Nettoyage terminé"; \
	echo ""; \
	\
	echo "🎉 Déploiement terminé avec succès !"; \
	echo "🌐 Site disponible sur : https://$$site_url"

## —— Linters et Code Quality ——————————————————————————————————

lint-php: ## Lint PHP avec PHP_CodeSniffer et WordPress Coding Standards
	@echo "🔍 Linting PHP avec WordPress Coding Standards..."
	./vendor/bin/phpcs --standard=$(THEME)/phpcs.xml $(THEME)

lint-php-fix: ## Auto-correction PHP avec PHP_CodeSniffer
	@echo "🔧 Auto-correction PHP..."
	./vendor/bin/phpcbf --standard=$(THEME)/phpcs.xml $(THEME)

lint-scss: ## Lint SCSS avec stylelint
	@echo "🎨 Linting SCSS..."
	cd $(THEME) && npx stylelint "resources/css/**/*.scss" --ignore-path .gitignore

lint-scss-fix: ## Auto-correction SCSS
	@echo "🔧 Auto-correction SCSS..."
	cd $(THEME) && npx stylelint "resources/css/**/*.scss" --fix --ignore-path .gitignore

lint-js: ## Lint JavaScript avec ESLint
	@echo "📜 Linting JavaScript..."
	cd $(THEME) && if find resources/js -type f -name "*.js" -print -quit | grep -q .; then npx eslint "resources/js/**/*.js"; else echo "(skip) aucun .js"; fi

lint-js-fix: ## Auto-correction JavaScript
	@echo "🔧 Auto-correction JavaScript..."
	cd $(THEME) && if find resources/js -type f -name "*.js" -print -quit | grep -q .; then npx eslint "resources/js/**/*.js" --fix; else echo "(skip) aucun .js"; fi

lint-ts: ## Lint TypeScript avec ESLint (principal)
	@echo "📜 Linting TypeScript..."
	cd $(THEME) && npx eslint "resources/js/**/*.{ts,tsx}"

lint-ts-fix: ## Auto-correction TypeScript (principal)
	@echo "🔧 Auto-correction TypeScript..."
	cd $(THEME) && npx eslint "resources/js/**/*.{ts,tsx}" --fix

lint-blade: ## Lint Blade avec Prettier (check)
	@echo "🧩 Linting Blade..."
	@cd $(THEME) && npx prettier --check "resources/views/**/*.blade.php" --ignore-path .gitignore || true
	@cd $(THEME) && npx prettier --write "resources/views/**/*.blade.php" --ignore-path .gitignore || true

format-js: ## Formatage JavaScript avec Prettier
	@echo "🎨 Formatage JavaScript..."
	cd $(THEME) && npx prettier --write "resources/js/**/*.js" --ignore-path .gitignore

format-ts: ## Formatage TypeScript avec Prettier
	@echo "🎨 Formatage TypeScript..."
	cd $(THEME) && npx prettier --write "resources/js/**/*.ts" "resources/js/**/*.tsx" --ignore-path .gitignore

format-all-js: ## Formatage de tous les fichiers JS/TS
	@echo "🎨 Formatage de tous les fichiers JS/TS..."
	cd $(THEME) && npx prettier --write "resources/js/**/*.{js,ts,tsx}" --ignore-path .gitignore

format-scss: ## Formatage SCSS avec Prettier
	@echo "🎨 Formatage SCSS..."
	cd $(THEME) && npx prettier --write "resources/css/**/*.scss" --ignore-path .gitignore

format-blade: ## Formatage Blade avec blade-formatter
	@echo "🎨 Formatage Blade..."
	cd $(THEME) && npx prettier --write "resources/views/**/*.blade.php" --ignore-path .gitignore

lint-theme: ## Lint uniquement le thème (SCSS, TS, JS, Blade)
	@echo "🎯 Linting du thème uniquement..."
	make lint-scss
	make lint-ts
	make lint-js
	make lint-blade

lint-all: ## Lance tous les linters
	@echo "🚀 Lancement de tous les linters..."
	make lint-scss
	make lint-ts
	make lint-js
	make lint-blade

lint: ## Lint + format + sécurité + performance (thème uniquement)
	@echo "🚀 Lint global (thème) — lint, format, sécurité, performance"
	make format-all
	make lint-all
	make security-check
	make wp-security
	make wp-cache
	make wp-optimize

lint-ci: ## Lint pour CI/CD (sans WordPress)
	@echo "🚀 Lint CI/CD — lint, format, sécurité (sans WordPress)"
	make format-all
	make lint-all
	make security-check

lint-all-fix: ## Auto-correction de tous les linters
	@echo "🔧 Auto-correction de tous les linters..."
	make lint-scss-fix
	make lint-ts-fix
	make lint-js-fix
	make format-blade

lint-fix: ## Corrige automatiquement (linters + formatage)
	@echo "🛠️  Auto-fix — linters + format (thème)"
	make lint-all-fix
	make format-all

format-all: ## Formatage de tous les fichiers
	@echo "🎨 Formatage de tous les fichiers..."
	make format-all-js
	make format-scss
	make format-blade

format: ## Alias — formatage JS/TS/SCSS du thème
	make format-all

## —— Sécurité et Audit ——————————————————————————————————

security-check: ## Vérification de sécurité avec Composer
	@echo "🔒 Vérification de sécurité Composer..."
	composer audit

wp-security: ## Vérification de sécurité WordPress
	@echo "🔒 Vérification de sécurité WordPress..."
	wp plugin list --status=active --format=table
	wp theme list --status=active --format=table
	@echo "⚠️  Vérifiez manuellement les plugins et thèmes actifs"

## —— Performance ——————————————————————————————————

wp-cache: ## Optimisation du cache WordPress
	@echo "⚡ Optimisation du cache..."
	wp cache flush
	wp rewrite flush
	wp transient delete --all

wp-optimize: ## Optimisation générale WordPress
	@echo "⚡ Optimisation générale..."
	@if command -v mysqlcheck >/dev/null 2>&1; then \
		wp db optimize; \
		wp db repair; \
	else \
		echo "⚠️  mysqlcheck non disponible (MySQL dans Docker) - optimisation DB ignorée"; \
	fi
	wp cache flush
	wp rewrite flush

# ==== Linters désactivés temporairement ====
.PHONY: lint lint-all lint-all-fix lint-php lint-php-fix lint-scss lint-scss-fix lint-js lint-js-fix lint-ts lint-ts-fix lint-blade \
        format format-all format-all-js format-scss format-js format-ts format-blade