<?php

/***********************************************************************************************************
*  	AJOUT AUX PARAMÉTRES DU BLOC PARAGRAPHE DE STYLES PERSONNALISÉS
*   	Add Style Box Shadow(bloc paragraphe & bloc grouper & bloc colonne)
*		Add Style Card
*		Add Style Notice: Question
*		Add Style Notice: Info
*		Add Style Notice: Advice
*		Add Style Notice: Warning
*		Add Style Notice: Alert
*   	Add Style Click to Tweet
*   	Add Style Evidence
*
*  	AJOUT AUX PARAMÉTRES DU BLOC LISTE DE STYLES PERSONNALISÉS
*   	Add Style Square
*   	Add Style Check
*   	Add Style Check circle fill
*   	Add Style Add 
*   	Add Style Add circle fill
*   	Add Style Push Spin 
*   	Add Style Circle Duotone
*   	Add Style Clear
*   	Add Style Site
*   	Add Style E-Mail
*   	Add Style Phone
*   	Add Style Facebook
*   	Add Style YouTube
*   	Add Style Twitter
*		Add Style Pinterest
*		Add Style Instagram
*		Add Style Linkedin
*   	Add Style Calendar
*   	Add Style Clock
* 		Add Style Location
*		Add Style Diagram
*		Add ordonned disk-style
*		Add Style Accordion
*  		Add Style Table Of Contents
*
*  	AJOUT AUX PARAMÉTRES DU BLOC GROUPE DE STYLES PERSONNALISÉS
*		Add Style Table Of Contents bloc groupe
*		Add Style Layout One Column Mobile bloc Groupe
*		Add Style Tab Content bloc Groupe
*
* 	AJOUT AUX PARAMÉTRES DU BLOC IMAGE DE STYLES PERSONNALISÉS
*   	Add Style Circle 
*   	Add Style Filter Grayscale
*		Add Style Image Card
*		Add Style Bordure Animée
*
*  	AJOUT AUX PARAMÉTRES DU BLOC BOUTON DE STYLES PERSONNALISÉS
*   	Add style Outline hover arrow
*   	Add style Download
*   	Add style Tab Item
* 
*  	AJOUT AUX PARAMÉTRES DU BLOC PARENT COLONNES DE STYLES PERSONNALISÉS
*   	Add Style Column reverse 
*   	Add Style Responsive three columns
*
*  	AJOUT AUX PARAMÉTRES DU BLOC MÉDIA & TEXTE DE STYLES PERSONNALISÉS
*   	Add Style Half Background
*
*  	AJOUT AUX PARAMÉTRES DU BLOC CITATION DE STYLES PERSONNALISÉS
*   	Add Style Quote
*		Add Style Fancy Quote
*		Add Style Patenthesis
*   	Add Style First Letter
*   	Add Style Arrow
*
*  	AJOUT AUX PARAMÉTRES DU BLOC READ MORE DE STYLES PERSONNALISÉS
*
*  	AJOUT AUX PARAMÉTRES DU BLOC TABLE DE STYLES PERSONNALISÉS
*
*  	AJOUT AUX PARAMÉTRES DU BLOC SOCIAL LINKS DE STYLES PERSONNALISÉS
*
*	Créer une catégorie de bloc personnalisée dans WordPress Block Inserter
*
*	PERSONNALISER BLOCS GUTENBERG
*   	Ajouter une nouvelle taille aux paramètres du bloc image 
*		Modifier les paramètres d'ajout de média par défaut
*		Ajout en Front End d'attribut URL Pour les bloc Groupe & Colonne 
*   	AJOUT EN FRONT END DE LA VARIATION DU BLOCK GROUPE COMPTE A REBOURS 
*   	Bloc Groupe: AJOUT EN FRONT END DU STYLE TABLE OF CONTENTS
*   	Transformer le bloc Galerie de WordPress en un slider utilisant la bibliothèque Swiper
*   	Transformer le bloc Galerie de WordPress en un album d'images
*		Transformer le bloc Groupe de WordPress contenant des blocs bannières en un slider avec la bibliothèque Swiper
*		Transformer le bloc Groupe de WordPress en une Fenêtre Modale
*		Transformer le bloc Groupe de WordPress pour afficher une carte Google Maps
*       Bloc Galerie de WordPress style justifié
*   	Bloc Icônes Sociales: transformer Liens Profil en Liens de Partage
*   	Visibilité des blocs Gutenberg
*		Visibilité des blocs pour les utilisateurs connectés ou déconnectés
*		Visibilité des blocs selon le role de l'utilisateur connecté
*		Visibilité des blocs selon le nom affiché publiquement pour l'utilisateur connecté
*		AJOUT EN FRONT END DU BOUTON CLICK TO TWEET POUR LE STYLE TWEET DU BLOC PARAGRAPHE
*       ANIMATION DES BLOCS GUTENBERG AVEC LA LIBRAIRIE AOS
*
*************************************************************************************************************/



/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC PARAGRAPHE DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/


add_action( 'after_setup_theme', 'eccp_register_block_paragraph_styles' );

function eccp_register_block_paragraph_styles(){
	
	// on récupère les paramètres pour la personnalisation des blocs Gutenberg
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
	
	
	/* ----------------------------- Add Style Box Shadow(bloc paragraphe & bloc grouper & bloc colonne) ---------------------------------------*/
	
	// modif version 2.8 , le style box shadows est directement appliqué 
	// dans les paramètres du bloc
	
	/*
	Ajout d'un style Box Shadow(Ombre de boite)au bloc paragraphe & bloc grouper & bloc colonne
	La register_block_style fonction reçoit le nom du bloc comme premier argument 
	et un tableau décrivant les propriétés du style comme deuxième argument.
	name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
	label: etiquette pour identifier le nouveau style dans les paramètres du bloc
	Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
	is-style-name avec name: identifiant ou slug du style déclaré
	le nom de la classe pour appliquer le nouveau style au bloc paragraphe est donc is-style-eccp-box-shadow 
	Il est également possible de définir la propriété 'is_default' => true, pour définir 
	ce style comme  le style par défaut pour le bloc
	*/
	
	/* si on a activé l'effet Box Shadow pour le bloc paragraphe
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_box_shadow_paragraph_block_radio_field'] == 'yes' ) {
	
		register_block_style(
			'core/paragraph',
			array(
				'name'  => 'eccp-box-shadow',
				'label' => __( 'Box Shadow', 'editor-custom-color-palette' ),
			)
		);
		
		register_block_style(
			'core/group',
			array(
				'name'  => 'eccp-box-shadow',
				'label' => __( 'Box Shadow', 'editor-custom-color-palette' ),
			)
		);
		
		register_block_style(
			'core/column',
			array(
				'name'  => 'eccp-box-shadow',
				'label' => __( 'Box Shadow', 'editor-custom-color-palette' ),
			)
		);
	
	}
   
	*/
   
	/* ----------------------------- Add Style Card ---------------------------------------*/
	
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_card_paragraph_radio_field'] == 'yes' ) {
		
		register_block_style(
			'core/paragraph',
			array(
				'name'  => 'eccp-card',
				'label' => __( 'Card', 'editor-custom-color-palette' ),
			)
		);
		
	}
   
   /* ----------------------------- Add Style Notice: Question ---------------------------------------*/
	
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_notice_question_radio_field'] == 'yes' ) {
		
		register_block_style(
			'core/paragraph',
			array(
				'name'  => 'eccp-notice-question',
				'label' => __( 'Notice: Question', 'editor-custom-color-palette' ),
			)
		);
		
		register_block_style(
			'core/group',
			array(
				'name'  => 'eccp-notice-question',
				'label' => __( 'Notice: Question', 'editor-custom-color-palette' ),
			)
		);
		
		
	}
	
	/* ----------------------------- Add Style Notice: Info ---------------------------------------*/
	
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_notice_info_radio_field'] == 'yes' ) {
		
		register_block_style(
			'core/paragraph',
			array(
				'name'  => 'eccp-notice-info',
				'label' => __( 'Notice: Info', 'editor-custom-color-palette' ),
			)
		);
		
		register_block_style(
			'core/group',
			array(
				'name'  => 'eccp-notice-info',
				'label' => __( 'Notice: Info', 'editor-custom-color-palette' ),
			)
		);
		
	}
	
	/* ----------------------------- Add Style Notice: Advice ---------------------------------------*/
	
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_notice_advice_radio_field'] == 'yes' ) {
		
		register_block_style(
			'core/paragraph',
			array(
				'name'  => 'eccp-notice-advice',
				'label' => __( 'Notice: Advice', 'editor-custom-color-palette' ),
			)
		);
		
		register_block_style(
			'core/group',
			array(
				'name'  => 'eccp-notice-advice',
				'label' => __( 'Notice: Advice', 'editor-custom-color-palette' ),
			)
		);
		
	}
	
	/* ----------------------------- Add Style Notice: Warning ---------------------------------------*/
	
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_notice_warning_radio_field'] == 'yes' ) {
		
		register_block_style(
			'core/paragraph',
			array(
				'name'  => 'eccp-notice-warning',
				'label' => __( 'Notice: Warning', 'editor-custom-color-palette' ),
			)
		);
		
		register_block_style(
			'core/group',
			array(
				'name'  => 'eccp-notice-warning',
				'label' => __( 'Notice: Warning', 'editor-custom-color-palette' ),
			)
		);
		
	}
	
	/* ----------------------------- Add Style Notice: Alert ---------------------------------------*/
	
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_notice_alert_radio_field'] == 'yes' ) {
		
		register_block_style(
			'core/paragraph',
			array(
				'name'  => 'eccp-notice-alert',
				'label' => __( 'Notice: Alert', 'editor-custom-color-palette' ),
			)
		);
		
		register_block_style(
			'core/group',
			array(
				'name'  => 'eccp-notice-alert',
				'label' => __( 'Notice: Alert', 'editor-custom-color-palette' ),
			)
		);
		
	}
   
   
	/* ----------------------------- Add Style Click to Tweet ---------------------------------------*/
	
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_click_to_tweet_radio_field'] == 'yes' ) {
		
		register_block_style(
			'core/paragraph',
			array(
				'name'  => 'eccp-tweet',
				'label' => __( 'Click to Tweet', 'editor-custom-color-palette' ),
			)
		);
		
	}
	
	
	/* ----------------------------- Add Style Evidence ---------------------------------------*/

		
		register_block_style(
			'core/paragraph',
			array(
				'name'  => 'eccp-evidence',
				'label' => __( 'Evidence', 'editor-custom-color-palette' ),
			)
		);
		
}

/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC LISTE DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/


if( $custom_gutenberg_blocks_settings['eccp_settings_activate_styles_bullet_list_radio_field'] == 'yes' ) {
	add_action( 'after_setup_theme', 'eccp_register_block_liste_styles' );
}

function eccp_register_block_liste_styles(){
	
	// on récupère les paramètres pour la personnalisation des blocs Gutenberg
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
	
	
	/* ----------------------------- Add Style Square  ---------------------------------------*/
	
	/*
	Ajout d'un style Square au bloc Liste 
	La register_block_style fonction reçoit le nom du bloc comme premier argument 
	et un tableau décrivant les propriétés du style comme deuxième argument.
	name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
	label: etiquette pour identifier le nouveau style dans les paramètres du bloc
	Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
	is-style-name avec name: identifiant ou slug du style déclaré
	le nom de la classe pour appliquer le nouveau style au bloc Liste est donc is-style-eccp-square-bullet-list 
	Il est également possible de définir la propriété 'is_default' => true, pour définir 
	ce style comme  le style par défaut pour le bloc
	
		
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-square-bullet-list',
			'label' => __( 'Square', 'editor-custom-color-palette' ),
		)
	);
	*/
	
	/* ----------------------------- Add Style Check  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-check-bullet-list',
			'label' => __( 'Check', 'editor-custom-color-palette' ),
		)
	);*/
	
	/* ----------------------------- Add Style Check circle fill  ---------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-check-circle-fill-bullet-list',
			'label' => __( 'Check circle fill', 'editor-custom-color-palette' ),
		)
	);*/
	
	
	/* ----------------------------- Add Style Add  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-add-bullet-list',
			'label' => __( 'Add', 'editor-custom-color-palette' ),
		)
	);*/
	
	
	/* ----------------------------- Add Style Add circle fill  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-add-circle-fill-bullet-list',
			'label' => __( 'Add circle fill', 'editor-custom-color-palette' ),
		)
	);*/
	
	
	/* ----------------------------- Add Style Push spin  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-push-spin-bullet-list',
			'label' => __( 'Push spin', 'editor-custom-color-palette' ),
		)
	);*/
	
	
	/* ----------------------------- Add Style Circle Duotone  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-circle-duotone-bullet-list',
			'label' => __( 'Circle duotone', 'editor-custom-color-palette' ),
		)
	);*/
	
	
	/* ----------------------------- Add Style Clear  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-clear-bullet-list',
			'label' => __( 'No', 'editor-custom-color-palette' ),
		)
	);*/
	
	/* ----------------------------- Add Style Clear  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-clear-bullet-list',
			'label' => __( 'No', 'editor-custom-color-palette' ),
		)
	);*/
	
	
	/* ----------------------------- Add Style Site  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-site-bullet-list',
			'label' => __( 'Site', 'editor-custom-color-palette' ),
		)
	);*/
	
	
	/* ----------------------------- Add Style E-Mail  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-mail-bullet-list',
			'label' => __( 'E-Mail', 'editor-custom-color-palette' ),
		)
	);*/
	
	
	/* ----------------------------- Add Style Phone  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-phone-bullet-list',
			'label' => __( 'Phone', 'editor-custom-color-palette' ),
		)
	);*/
	
	
	/* ----------------------------- Add Style Facebook  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-facebook-bullet-list',
			'label' => __( 'Facebook', 'editor-custom-color-palette' ),
		)
	);*/
	
	/* ----------------------------- Add Style YouTube  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-youtube-bullet-list',
			'label' => __( 'YouTube', 'editor-custom-color-palette' ),
		)
	);*/
		
	/* ----------------------------- Add Style Twitter  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-twitter-bullet-list',
			'label' => __( 'Twiter', 'editor-custom-color-palette' ),
		)
	);*/
	
	/* ----------------------------- Add Style Pinterest  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-pinterest-bullet-list',
			'label' => __( 'Pinterest', 'editor-custom-color-palette' ),
		)
	);*/

	/* ----------------------------- Add Style Instagram  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-instagram-bullet-list',
			'label' => __( 'Instagram', 'editor-custom-color-palette' ),
		)
	);*/

	/* ----------------------------- Add Style LinkedIn  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-linkedin-bullet-list',
			'label' => __( 'LinkedIn', 'editor-custom-color-palette' ),
		)
	);*/
	
	/* ----------------------------- Add Style Whatsapp  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-whatsapp-bullet-list',
			'label' => __( 'Whatsapp', 'editor-custom-color-palette' ),
		)
	);*/
	
	/* ----------------------------- Add Style Calendar  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-calendar-bullet-list',
			'label' => __( 'Calendar', 'editor-custom-color-palette' ),
		)
	);*/
	
	/* ----------------------------- Add Style Clock  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-clock-bullet-list',
			'label' => __( 'Clock', 'editor-custom-color-palette' ),
		)
	);*/
	
	/* ----------------------------- Add Style Location  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-location-bullet-list',
			'label' => __( 'Location', 'editor-custom-color-palette' ),
		)
	);*/
	
	/* ----------------------------- Add ordonned disk-style(Liste ordonnée de style Disque)  ---------------------------------------
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-ordonned-disk-bullet-list',
			'label' => __( 'Ordonned disk', 'editor-custom-color-palette' ),
		)
	);*/
	
	/* ----------------------------- Add Style Diagram  ---------------------------------------*/
	
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-tree-bullet-list',
			'label' => __( 'Diagram', 'editor-custom-color-palette' ),
		)
	);
	
	/* ----------------------------- Add Style Accordion  ---------------------------------------*/
	register_block_style(
		'core/list',
		array(
			'name'  => 'eccp-accordion-bullet-list',
			'label' => __( 'Accordion', 'editor-custom-color-palette' ),
		)
	);
	
}

/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC GROUPE DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/

add_action( 'after_setup_theme', 'eccp_register_block_group_styles' );

function eccp_register_block_group_styles(){
	
	// on récupère les paramètres pour la personnalisation des blocs Gutenberg
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
	
	
	/* ----------------------------- Add Style Table Of Contents bloc Groupe  ---------------------------------------*/
	
	/*
	Ajout d'un style Table Of Contents au bloc Groupe 
	La register_block_style fonction reçoit le nom du bloc comme premier argument 
	et un tableau décrivant les propriétés du style comme deuxième argument.
	name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
	label: etiquette pour identifier le nouveau style dans les paramètres du bloc
	Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
	is-style-name avec name: identifiant ou slug du style déclaré
	le nom de la classe pour appliquer le nouveau style au bloc groupe est donc is-style-eccp-toc 
	Il est également possible de définir la propriété 'is_default' => true, pour définir 
	ce style comme le style par défaut pour le bloc
	*/
	
	register_block_style(
		'core/group',
		array(
			'name'  => 'eccp-toc',
			'label' => __( 'Table Of Contents', 'editor-custom-color-palette' ),
		)
	);
	
	/* ----------------------------- Add Style Layout One Column Mobile bloc Groupe  ---------------------------------------*/
	
	/*
	Ajout d'un style Layout One Column Mobile au bloc Groupe
	qui sera affiché seulement pour la disposition en grille
	La register_block_style fonction reçoit le nom du bloc comme premier argument 
	et un tableau décrivant les propriétés du style comme deuxième argument.
	name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
	label: etiquette pour identifier le nouveau style dans les paramètres du bloc
	Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
	is-style-name avec name: identifiant ou slug du style déclaré
	le nom de la classe pour appliquer le nouveau style au bloc groupe est donc is-style-eccp-layout-one-column-mobile 
	Il est également possible de définir la propriété 'is_default' => true, pour définir 
	ce style comme le style par défaut pour le bloc
	*/
	
	register_block_style(
		'core/group',
		array(
			'name'  => 'eccp-layout-one-column-mobile',
			'label' => __( 'Layout One Column Mobile', 'editor-custom-color-palette' ),
		)
	);
	
	/* ----------------------------- Add Style Tab Content bloc Groupe  ---------------------------------------*/
	
	register_block_style(
		'core/group',
		array(
			'name'  => 'tab-content',
			'label' => __( 'Tab Content', 'editor-custom-color-palette' ),
		)
	);
	
}

/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC IMAGE DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/


add_action( 'after_setup_theme', 'eccp_register_block_image_styles' );

function eccp_register_block_image_styles(){
	
	// on récupère les paramètres pour la personnalisation des blocs Gutenberg
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
	
	
	/* ----------------------------- Add Style Circle  ---------------------------------------*/
	
	/*
	Ajout d'un style Circle au bloc paragraphe 
	La register_block_style fonction reçoit le nom du bloc comme premier argument 
	et un tableau décrivant les propriétés du style comme deuxième argument.
	name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
	label: etiquette pour identifier le nouveau style dans les paramètres du bloc
	Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
	is-style-name avec name: identifiant ou slug du style déclaré
	le nom de la classe pour appliquer le nouveau style au bloc image est donc is-style-eccp-image-circle-4-3 
	Il est également possible de définir la propriété 'is_default' => true, pour définir 
	ce style comme  le style par défaut pour le bloc
	Remarque: WordPress a déja une classe prédéfini pour appliquer un masque circulaire: is-style-circle-mask
	*/
	
	// si on a activé le style Circle pour le bloc Image
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_image_circle_radio_field'] == 'yes' ) {
	
		register_block_style(
			'core/image',
			array(
				'name'  => 'eccp-image-circle-4-3',
				'label' => __( 'Circle img 4/3', 'editor-custom-color-palette' ),
			)
		);
		
		
		register_block_style(
			'core/image',
			array(
				'name'  => 'eccp-image-circle-16-9',
				'label' => __( 'Circle img 16/9', 'editor-custom-color-palette' ),
			)
			
		);
		
	}
	
	
	/* ----------------------------- Add Style Filter Grayscale ---------------------------------------*/
	
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_image_filter_grayscale_radio_field'] == 'yes' ) {
		
		register_block_style(
			'core/image',
			array(
				'name'  => 'eccp-filter-grayscale',
				'label' => __( 'Filter: Grayscale', 'editor-custom-color-palette' ),
			)
		);
		
	}
	
	/* ----------------------------- Add Style Image Card ---------------------------------------*/
	
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_image_card_radio_field'] == 'yes' ) {
		
		register_block_style(
			'core/image',
			array(
				'name'  => 'eccp-card-image',
				'label' => __( 'Card', 'editor-custom-color-palette' ),
			)
		);
		
	}
	
	/* ----------------------------- Add Style Bordure Animée ---------------------------------------*/
	
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_style_image_animated_border_radio_field'] == 'yes' ) {
		
		register_block_style(
			'core/image',
			array(
				'name'  => 'eccp-animated-border',
				'label' => __( 'Bordure Animée', 'editor-custom-color-palette' ),
			)
		);
		
	}

}


/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC BOUTON DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/

add_action( 'after_setup_theme', 'eccp_register_block_buttons_styles' );

function eccp_register_block_buttons_styles(){
	
	// on récupère les paramètres pour la personnalisation des blocs Gutenberg
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
	
	
	// si on a activé les styles pour le bloc boutons
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_button_styles_hover_radio_field'] == 'yes' ) {
	
		/* ----------------------------- Add style Outline hover arrow  ---------------------------------------*/
		
		/*
		Ajout d'un style Outline hover arrow au bloc bouton 
		La register_block_style fonction reçoit le nom du bloc comme premier argument 
		et un tableau décrivant les propriétés du style comme deuxième argument.
		name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
		label: etiquette pour identifier le nouveau style dans les paramètres du bloc
		Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
		is-style-name avec name: identifiant ou slug du style déclaré
		le nom de la classe pour appliquer le nouveau style au bloc bouton est donc is-style-eccp-outlinehover-arrow 
		Il est également possible de définir la propriété 'is_default' => true, pour définir 
		ce style comme  le style par défaut pour le bloc
		*/
	
		register_block_style(
			'core/button',
			array(
				'name'  => 'eccp-outline-hover-arrow',
				'label' => __( 'Outline hover arrow', 'editor-custom-color-palette' ),
			)
		);
	
		/* ----------------------------- Add style Download  ---------------------------------------*/
	
		register_block_style(
			'core/button',
			array(
				'name'  => 'eccp-download',
				'label' => __( 'Download', 'editor-custom-color-palette' ),
			)
		);
		
		/* ----------------------------- Add style Tab Item  ---------------------------------------*/
	
		register_block_style(
			'core/button',
			array(
				'name'  => 'tab-item',
				'label' => __( 'Tab Item', 'editor-custom-color-palette' ),
			)
		);
	
	}
	
}




/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC PARENT COLONNES DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/


add_action( 'after_setup_theme', 'eccp_register_block_columns_styles' );

function eccp_register_block_columns_styles(){
	
	// on récupère les paramètres pour la personnalisation des blocs Gutenberg
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
	
	
	// si on a activé les styles pour le bloc parent colonnes
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_columns_block_styles_radio_field'] == 'yes' ) {
	
		/* ----------------------------- Add Style Column reverse  ---------------------------------------*/
		
		/*
		Ajout d'un style Column reverse au bloc parent colonnes 
		La register_block_style fonction reçoit le nom du bloc comme premier argument 
		et un tableau décrivant les propriétés du style comme deuxième argument.
		name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
		label: etiquette pour identifier le nouveau style dans les paramètres du bloc
		Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
		is-style-name avec name: identifiant ou slug du style déclaré
		le nom de la classe pour appliquer le nouveau style au bloc image est donc is-style-eccp-column-reverse 
		Il est également possible de définir la propriété 'is_default' => true, pour définir 
		ce style comme  le style par défaut pour le bloc
		*/
	
		register_block_style(
			'core/columns',
			array(
				'name'  => 'eccp-column-reverse',
				'label' => __( 'Columns reverse mobile', 'editor-custom-color-palette' ),
			)
		);
		
		/* ----------------------------- Add Style Responsive three columns  ---------------------------------------*/
		
		register_block_style(
			'core/columns',
			array(
				'name'  => 'eccp-responsive-three-columns',
				'label' => __( 'Responsive three columns', 'editor-custom-color-palette' ),
			)
		);
		
		
	}
	
}

/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC MÉDIA & TEXTE DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/

add_action( 'after_setup_theme', 'eccp_register_block_media_texte_styles' );

function eccp_register_block_media_texte_styles(){
	
	// on récupère les paramètres pour la personnalisation des blocs Gutenberg
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
	
	
	// si on a activé les styles pour le bloc Média & Texte
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_media_text_block_styles_radio_field'] == 'yes' ) {
	
		/* ----------------------------- Add Style Half Background  ---------------------------------------*/
		
		/*
		Ajout de styles au bloc média & texte 
		La register_block_style fonction reçoit le nom du bloc comme premier argument 
		et un tableau décrivant les propriétés du style comme deuxième argument.
		name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
		label: etiquette pour identifier le nouveau style dans les paramètres du bloc
		Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
		is-style-name avec name: identifiant ou slug du style déclaré
		donc pour le styles Half Background
		le nom de la classe pour appliquer le nouveau style au bloc image est donc is-style-eccp-half-background 
		Il est également possible de définir la propriété 'is_default' => true, pour définir 
		ce style comme  le style par défaut pour le bloc
		*/
	
		register_block_style(
			'core/media-text',
			array(
				'name'  => 'eccp-media-texte-reverse-mobile',
				'label' => __( 'Default reverse mobile', 'editor-custom-color-palette' ),
			)
		);
	
		register_block_style(
			'core/media-text',
			array(
				'name'  => 'eccp-half-background',
				'label' => __( 'Half background', 'editor-custom-color-palette' ),
			)
		);
		
		register_block_style(
			'core/media-text',
			array(
				'name'  => 'eccp-half-background-reverse-mobile',
				'label' => __( 'Half background reverse mobile', 'editor-custom-color-palette' ),
			)
		);
		
		
	}
	
}

/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC CITATION DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/

add_action( 'after_setup_theme', 'eccp_register_block_quote_texte_styles' );

function eccp_register_block_quote_texte_styles(){
	
	// on récupère les paramètres pour la personnalisation des blocs Gutenberg
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
	

	// si on a activé les styles pour le bloc Citation
	if( $custom_gutenberg_blocks_settings['eccp_settings_enable_custom_block_quote_styles_radio_field'] == 'yes' ) {
	
		/* ----------------------------- Add Style Quote  ---------------------------------------*/
		
		/*
		La register_block_style fonction reçoit le nom du bloc comme premier argument 
		et un tableau décrivant les propriétés du style comme deuxième argument.
		name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
		label: etiquette pour identifier le nouveau style dans les paramètres du bloc
		Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
		is-style-name avec name: identifiant ou slug du style déclaré
		le nom de la classe pour appliquer le nouveau style au bloc citation est donc is-style-eccp-quote 
		Il est également possible de définir la propriété 'is_default' => true, pour définir 
		ce style comme  le style par défaut pour le bloc
		*/
	
		register_block_style(
			'core/quote',
			array(
				'name'  => 'eccp-quote',
				'label' => __( 'Quote', 'editor-custom-color-palette' ),
			)
		);
		
		/* ----------------------------- Add Style Fancy Quote  ---------------------------------------*/
		
		register_block_style(
			'core/quote',
			array(
				'name'  => 'eccp-fancy-quote',
				'label' => __( 'Fancy Quote', 'editor-custom-color-palette' ),
			)
		);
		
		
		/* ----------------------------- Add Style Patenthesis  ---------------------------------------*/
		
		register_block_style(
			'core/quote',
			array(
				'name'  => 'eccp-patenthesis',
				'label' => __( 'Parenthèse', 'editor-custom-color-palette' ),
			)
		);
		
		
		/* ----------------------------- Add Style First Letter  ---------------------------------------*/
		
		register_block_style(
			'core/quote',
			array(
				'name'  => 'eccp-quote-first-letter',
				'label' => __( 'First Letter', 'editor-custom-color-palette' ),
			)
		);
		
		/* ----------------------------- Add Style Arrow  ---------------------------------------*/
		
		register_block_style(
			'core/quote',
			array(
				'name'  => 'eccp-quote-arrow',
				'label' => __( 'Arrow', 'editor-custom-color-palette' ),
			)
		);
		
		
	}
	
}

/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC READ MORE DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/


/**************************************************************************************************
    remplacer l'intitulé de la balise Read More: continuer la lecture de par: Lire la suite.
   customiser la balise read more avec une classe CSS.
   On supprime la référence à l’ancre #more-000 par l’URL de l’article et
   on insére un attribut title reprenant le titre de l’article.
   On customise le lien sous forme de bouton avec la classe eccp-read-more 
   on encadre le bouton dans un div avec la classe display:block pour imposer 
   un retour a la ligne du bouton.
   On utilise la classe dashicons dashicons-arrow-right-alt2  pour un icône en forme de fléche vers la droite
   le hook: the_content_more_link permet de filtrer le lien de la balise Read More pour empêcher lorsqu'on clique
   sur cette balise de faire défiler vers la section juste en dessous la balise Read More contenant l'ancre nommée: #more-000
   href="' . get_permalink() . '" donne le lien de l'article en cours donc un clic sur la balise read more amène en début d'article
/*************************************************************************************************/

// si on a activé les styles pour le bloc READ MORE
if( $custom_gutenberg_blocks_settings['eccp_settings_activate_block_styles_read_more_radio_field'] == 'yes' ) {
	add_filter( 'the_content_more_link', 'eccp_custom_read_more_block',999 );
}

function eccp_custom_read_more_block() {
	
 // on récupère les paramètres de réglage de la section Personnaliser blocs Gutenberg
 $custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
 
 $link_text = __($custom_gutenberg_blocks_settings['eccp_settings_link_text_read_more_text_field'], 'editor-custom-color-palette' );
	
 return '<div style="display:block;">
			<a class="eccp-read-more" href="' . get_permalink() . '" title="Lire la suite - ' 
			. get_the_title() . '">'.esc_html($link_text).'<span class="dashicons dashicons-arrow-right-alt2"></span> </a>
			
		 </div>';
		 
}


/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC TABLE DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/

add_action( 'after_setup_theme', 'eccp_register_block_table_styles' );

function eccp_register_block_table_styles(){
	
	// on récupère les paramètres pour la personnalisation des blocs Gutenberg
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
	
	
	// si on a activé les styles pour le bloc Table
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_block_styles_table_radio_field'] == 'yes' ) {
	
		/* ----------------------------- Add Style Stripes  ---------------------------------------*/
		
		/*
		Ajout d'un style Stripes(rayures)au bloc média & texte 
		La register_block_style fonction reçoit le nom du bloc comme premier argument 
		et un tableau décrivant les propriétés du style comme deuxième argument.
		name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
		label: etiquette pour identifier le nouveau style dans les paramètres du bloc
		Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
		is-style-name avec name: identifiant ou slug du style déclaré
		le nom de la classe pour appliquer le nouveau style au bloc image est donc is-style-eccp-stripes 
		Il est également possible de définir la propriété 'is_default' => true, pour définir 
		ce style comme  le style par défaut pour le bloc
		*/
	
		register_block_style(
			'core/table',
			array(
				'name'  => 'eccp-stripes',
				'label' => __( 'ECCP Stripes', 'editor-custom-color-palette' ),
			)
		);
		
		
	}
	
}


/*----------------------------------------------------------------------------------------
		  AJOUT AUX PARAMÉTRES DU BLOC SOCIAL LINKS DE STYLES PERSONNALISÉS
/*---------------------------------------------------------------------------------------*/

add_action( 'after_setup_theme', 'eccp_register_block_social_links_styles' );

function eccp_register_block_social_links_styles(){
	
	// on récupère les paramètres pour la personnalisation des blocs Gutenberg
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
	
	
	// si on a activé les styles pour le bloc social links
	if( $custom_gutenberg_blocks_settings['eccp_settings_activate_rectangle_shape_style_radio_field'] == 'yes' ) {
	
		/* ----------------------------- Add Style rectangular shape(forme rectangle)  ---------------------------------------*/
		
		/*
		Ajout d'un style rectangular shape au bloc social links
		La register_block_style fonction reçoit le nom du bloc comme premier argument 
		et un tableau décrivant les propriétés du style comme deuxième argument.
		name: L'identifiant ou slug du style utilisé pour la classe CSS du bloc
		label: etiquette pour identifier le nouveau style dans les paramètres du bloc
		Le nom de classe de style  pour le bloc est automatiquement créé en utilisant le format suivant :
		is-style-name avec name: identifiant ou slug du style déclaré
		le nom de la classe pour appliquer le nouveau style au bloc image est donc is-style-eccp-rectangular-shape 
		Il est également possible de définir la propriété 'is_default' => true, pour définir 
		ce style comme  le style par défaut pour le bloc
		*/
	
		register_block_style(
			'core/social-links',
			array(
				'name'  => 'eccp-rectangular-shape',
				'label' => __( 'Rectangular Shape', 'editor-custom-color-palette' ),
			)
		);
		
		
		/* ----------------------------- Add Style Float Right(forme rectangle flottant a droite )  ---------------------------------------*/
		
		register_block_style(
			'core/social-links',
			array(
				'name'  => 'eccp-social-icons-floating-right',
				'label' => __( 'Float Right', 'editor-custom-color-palette' ),
			)
		);
		
		
		/* ----------------------------- Add Style Float Left(forme rectangle flottant a gauche )  ---------------------------------------*/
		
		register_block_style(
			'core/social-links',
			array(
				'name'  => 'eccp-social-icons-floating-left',
				'label' => __( 'Float Left', 'editor-custom-color-palette' ),
			)
		);
		
		
	}
	
}

/*----------------------------------------------------------------------------------------
		  Créer une catégorie de bloc personnalisée dans WordPress Block Inserter
/*---------------------------------------------------------------------------------------*/

/* ANCIEN CODE OU ON VIENT SIMPLMENT ENTRER LA NOUVELLE CATÉGORIES
   EN FIN DES CATÉGORIES
function eccp_plugin_block_categories( $block_categories,$block_editor_context ) {
	
	// Vérifie le contexte de ce filtre, renvoie la valeur par défaut 
	// s'il n'est pas dans l'éditeur de bloc.
	if ( ! ( $block_editor_context instanceof WP_Block_Editor_Context ) ) {
        return $block_categories;
    }
		
    return array_merge(
        $block_categories,
        [
            [
                'slug'  => 'eccp-blocks',
                'title' => __( 'ECCP Custom Blocks', 'editor-custom-color-palette' ),
            ],
        ]
    );
	
}
*/

function eccp_plugin_block_categories( $block_categories,$block_editor_context ) {
	
	// Vérifie le contexte de ce filtre, renvoie la valeur par défaut 
	// s'il n'est pas dans l'éditeur de bloc.
	if ( ! ( $block_editor_context instanceof WP_Block_Editor_Context ) ) {
        return $block_categories;
    }

	// créer un nouvel élément de tableau avec n'importe quoi comme index
	$new_categorie = array(
		'eccpindex' => array(
			'slug'  => 'eccp-blocks',
			'title' => __( 'ECCP Custom Blocks', 'editor-custom-color-palette' ),
		)
	);

	// On rensigne ici à quelle position notre catégorie personnalisée doit apparaître
	// sachant que l'index du tableau des catégories de bloc commence a 0
	$position = 2; // 2: Après Text et Media, donc techniquement c'est une 3ème position

	
	// array_slice(array , position, longueur, ne pas réordonner les indices)
	// si longueur est null ou omis alors on retourne tout les éléments depuis 
	// la position offset jusqu'à la fin du tableau.
	$block_categories= array_slice( $block_categories, 0, $position, true ) + $new_categorie + array_slice( $block_categories, $position, null, true );

	// array_values permet de réindexer numériquement le tableau
	$block_categories = array_values( $block_categories );

	return $block_categories;

}


// ce hook nécessite wordpress > 5.8 
// il filtre le tableau de catégories par défaut pour les types de bloc
// et vient inésérer la nouvelle catégorie en troisième position
// $block_editor_context permet aussi de filtrer en fonction du contenu de l'editeur Page, Article etc..
add_action( 'block_categories_all', 'eccp_plugin_block_categories', 10, 2 );


/***********************************************************************************************
                                       PERSONNALISER BLOCS GUTENBERG            
***********************************************************************************************/

/*------------ Ajouter une nouvelle taille aux paramètres du bloc image  ---------*/

// si on a activé une nouvelle taille d'image aux paramètres du bloc
// et si on a donné un nom acette nouvelle taille d'image
if( ($custom_gutenberg_blocks_settings['eccp_settings_enable_image_size_setting_radio_field'] == 'yes') &&
  (!empty($custom_gutenberg_blocks_settings['eccp_settings_name_new_image_size_text_field'])) ) {


	// Création de la taille au format 16/9 ème utilisée dans le site
	// add_image_size( libellé, hauteur , largeur, image recadré)
	function eccp_setup_init_images() {
		// récupération des paramètres
		$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
		
		add_image_size( $custom_gutenberg_blocks_settings['eccp_settings_slug_new_image_size_text_field'], 720, 405, false );
	}

	add_action( 'after_setup_theme', 'eccp_setup_init_images' );


	// Ajout de la taille: custom aux paramètres du bloc image,
	// pour cela on utilise le hook: image_size_names_choose. 
	// la fontion php array_merge permet de fusionner en fin de tableau
	// la taille custom avec celles existantes:
	// thumbnail (miniature: 150*150) medium (moyenne: 300px de large max ) large (1024px) 
	// post-thumbnail (taille originale).
	// il existe une taille medium_large (moyenne-large: max 768px de large) utilisée pour le responsive
	// affichée uniquement dans le HTML de l'image avec l'attribut srcset.
	// pour que la taille custom apparaisse dans le menu déroulant Taille de l'image des paramètres du bloc,
	// il faut au préalable régénérer les miniatures avec l'extension Regenerate Thumbnails.
	function eccp_custom_sizes_images( $sizes ) {
		
		// récupèration des paramètres
		$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
		
		// par défaut
		// $new_sizes = array('custom' => __('Custom', 'editor-custom-color-palette')
		$new_sizes = array($custom_gutenberg_blocks_settings['eccp_settings_slug_new_image_size_text_field'] => __($custom_gutenberg_blocks_settings['eccp_settings_name_new_image_size_text_field'], 'editor-custom-color-palette')) ;
		return array_merge( $sizes,$new_sizes); 					
	}

	add_filter( 'image_size_names_choose', 'eccp_custom_sizes_images' );

}

/*------------ Modifier les paramètres d'ajout de média par défaut  ---------*/

function eccp_image_display_settings() {
	
	// récupèration des paramètres
	$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );

	// l'alignement ne fonctionne pas
	//update_option( 'image_default_align', 'center' ); // left, center, right, none
	update_option( 'image_default_link_type', $custom_gutenberg_blocks_settings['eccp_settings_image_default_link_type_select_field'] );//  none , file 
	update_option( 'image_default_size', $custom_gutenberg_blocks_settings['eccp_settings_image_default_size_select_field'] ); // thumbnail, medium, large, full

}
add_action( 'after_setup_theme', 'eccp_image_display_settings',10 );


/*------------ Ajout en Front End d'attribut URL Pour les bloc Groupe & Colonne  ---------*/

/**
  * Ajout d'un lien aux données du bloc.
  * 
  * @param	string	$block_content ==> le contenu du bloc
  * @param	array	$block ==> les données du bloc complet, y compris le nom et les attributs
  * @return	string ==> Le contenu du bloc mis à jour
  * @throws	\DOMexception
  */
 function eccp_add_linkable_block_data( string $block_content, array $block ): string {
	
	// les attributs link,withLinkBlock, target
	// ont été définit en React JS pour les blocs Groupe & Colonne
	// wp_parse_args permet de fusionner un tableau d'arguments $block['attrs'] 
	// et un tableau de valeurs par défaut
 	$args = wp_parse_args(
	
 		$block['attrs'],
 		[
 			'link' => '',
 			'withLinkBlock' => false,
 			'target' => '',
 		]
 	);
	
	// si on n'a pas activé de lien pour le bloc
	// on retourne le contenu du bloc sans modification
	if (!$args['withLinkBlock']){
		return $block_content;
	}

 	// signifie que les erreurs dans la bibliothèque libxml ne sont pas générées 
	// et que l'on doit s'en occuper via libxml_get_errors()
	libxml_use_internal_errors( true );

 	// on initialise la classe DOMDocument
	// avec DOMDocument() on a la possibilité d'effectuer des opérations similaires 
	// a javascript sur le Document Object Model (DOM) de n'importe quel code HTML
	// de nombreuses méthodes ont été DOMDocumentnommées de manière identique 
	// à leur équivalent JavaScript, par ex getElementById()
	$dom = new DOMDocument();
	
	// ancien code déprécié avec PHP 8.3
	// on charge le contenu HTML($block_content) et on l'encadre de balise html
	// car nécessaire pour pouvoir le traiter avec la classe DOMDocument
	// loadHTML fonctionne avec ISO-8859-1 par défaut,donc on utilise la fonction
	// mb_convert_encoding pour encoder en UTF8
	// LIBXML_HTML_NOIMPLIED:désactive l'ajout automatique d'éléments html/body... implicites.
	// LIBXML_HTML_NODEFDTD: empêche l'ajout d'un doctype par défaut lorsqu'il n'en trouve pas.
	/*$dom->loadHTML(
 		mb_convert_encoding(
 			'<html>' . $block_content . '</html>',
 			'HTML-ENTITIES',
 			'UTF-8'
 		),
 		LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
 	);*/
	
	// Convertir les caractères non-ASCII en HTML UTF8
    $block_content = mb_encode_numericentity(
        $block_content,
		//conversion ISO-8859-1 en référence de caractère numérique HTML
        [0x80, 0xffff, 0, 0xffff],
        'UTF-8'
    );

    // Préparation du contenu HTML en encadrant avec des balises html
	// car nécessaire pour pouvoir le traiter avec la classe DOMDocument
    $htmlContent = '<html>' . $block_content . '</html>';

    // LIBXML_HTML_NOIMPLIED : désactive l'ajout automatique d'éléments html/body... implicites.
    // LIBXML_HTML_NODEFDTD : empêche l'ajout d'un doctype par défaut lorsqu'il n'en trouve pas.
    $dom->loadHTML($htmlContent, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
	

 	// pour tous les éléments qui sont des divs 
 	foreach ( $dom->getElementsByTagName( 'div' ) as $element ) {
		
 		// Si on activé le lien pour les blocs
		if ( $args['withLinkBlock'] ) {
			
			// si le lien renseigné en backoffice dans les paramètres 
			// du bloc Groupe ou colonne est bien une URL
			// on attribue la classe is-linkable-block en la concaténant avec les classes
			// existante du bloc Groupe ou Colonne
			// attention! l'espace est important devant la classe is-linkable-block
			// on ajoute dans le html du bloc l'attribut data-link
			// avec la valeur de l'attribut link pour renseigner l'URL
			// on ajoute dans le html du bloc l'attribut data-target
			// avec la valeur de l'attribut target pour renseigner
			// si on ouvre le lien dans l'onglet courant ou un nouvel onglet
			if (!filter_var( $args['link'], FILTER_VALIDATE_URL) === false) {
				
				$element->setAttribute( 'class', $element->getAttribute( 'class' ) . ' is-linkable-block' );
				$element->setAttribute( 'data-link', $block['attrs']['link'] );
				$element->setAttribute( 'data-target', $args['target'] );
				
			}
			
		}


 	}

 	// on affecte le contenu HTML du bloc modifié
	$block_content = $dom->saveHTML( $dom->documentElement );

	// on active la gestion d'erreur libxml
 	libxml_use_internal_errors( false );

 	// on nettoie le code HTML et on remplace 
	// toutes les balise <html> & </html>
	// par une chaine vide dans $block_content
	// valeur de retour de la fonction
	return str_replace(
 		[
 			'<html>',
 			'</html>',
 		],
 		[
 			'',
 			'',
 		],
 		$block_content
 	);
	
 }

 // On utilise le hook render_block_name block  qui permet de filtrer le contenu
 // du bloc avant son rendu HTML sur le Front END
 add_action( 'render_block_core/column', 'eccp_add_linkable_block_data', 10, 2 );
 add_action( 'render_block_core/group', 'eccp_add_linkable_block_data', 10, 2 );




// on marque les blocs comme des liens
// en spécifiant le curseur de la souris comme pointer
function ecpp_style_link_block() {
	
	
	echo '<style type="text/css" id="eccp-link-block">';
		
		
		echo'.is-linkable-block{';
			echo'cursor: pointer;';
		echo'}';
		
	echo '</style>';
	
}

add_action( 'wp_head','ecpp_style_link_block',1 );




/* AJOUT EN FRONT END DE LA VARIATION DU BLOCK GROUPE COMPTE A REBOURS */

/*
Une post meta:countdown_timer_date_events a été déclaré par la fonction
PHP eccp_register_post_meta().
Dans les paramètres du bloc pour le style sélectionné Compte à rebours

un composant DatePicker permet de sélectionner la date de fin du compte à rebours.
La date sélectionnée est affectée a un attribut date_events qui met a jour
la post meta:countdown_timer_date_events pour la publication en cours
réciproquement la post meta:countdown_timer_date_events est récupéré
en ReactJS pour initialiser le DatePicker.  

Le hook render_block est utilisé par la fonction eccp_countdown() pour modifier 
en Front End le balisage de fin du block groupe de classe is-style-eccp-countdown 
pour incorporer le code HTML de notre compte a rebours pour deux styles:
• style carré
• Style circulaire 

Remarque:
- La classe is-style-eccp-countdown est ajoutée par la variation de bloc Countdown Timer
la date de l'évènement pour le compte à rebours a été affiché dans une div caché 
par la fonction php: eccp_get_countdown_timer_date_events().

- le script JS: eccp-countdown-timer.js va récupérer la date d'èvènement dans cette
balise <div> caché et actualiser l'affichage du compte a rebours toutes les secondes.
il va aussi récupérer la valeur de l'attribut circular-countdown pour savoir si on a un 
compte a rebours de forme circulaire, afin d'appliquer du code JS
spécifiquement pour ce style.

- dans le balisage HTML on applique du style CSS en ligne pour les 
4 compteurs du compte à rebours de forme circulaire afin d'appliquer
la valeur correspondante des attributs aux paramètres du bloc groupe pour:
• diamètre du cercle que l'on va faire varier en appliquant un zoom.
le diamètre du cercle est par défaut de 100 et peut aller jusqu'a 300,
soit un zoom de 1 à 3
• couleur de bordure du cercle
• couleur d'arrière plan du cercle
• couleur du texte
*/


function eccp_countdown( $block_content, $block ) {

		// les attributs dateEvents,styleAttribute, 
		// ont été définit en React JS pour le bloc Groupe 
		// wp_parse_args permet de fusionner un tableau d'arguments $block['attrs'] 
		// et un tableau de valeurs par défaut
		$args = wp_parse_args(
		
			$block['attrs'],
			[
				'styleAttribute' => 'none',
				'dateEvents' => '',
				'withCircularCountdown' => false,
				'circleDiameter' => 100,
				'daysCircleBorderColor' => '#333333',
				'hoursCircleBorderColor' => '#333333',
				'minutesCircleBorderColor' => '#333333',
				'secondsCircleBorderColor' => '#333333',
				'daysCircleBackgroundColor' => 'transparent',
				'hoursCircleBackgroundColor' => 'transparent',
				'minutesCircleBackgroundColor' => 'transparent',
				'secondsCircleBackgroundColor' => 'transparent',
				'daysCircleTextColor'  => '#333333',
				'hoursCircleTextColor'  => '#333333',
				'minutesCircleTextColor'  => '#333333',
				'secondsCircleTextColor'  => '#333333',
			]
		);
		
	// si c'est le bloc groupe avec une classe is-style-eccp-countdown & si on a sélectionné
	// le style compte a rebours
	if( 'core/group' === $block['blockName'] && $args['styleAttribute'] === 'countdown-timer' &&
	    !empty( $block['attrs']['className'] ) && 'is-style-eccp-countdown' === $block['attrs']['className'] ) {
		
		/* Pour debug 
			print_r ($args['styleAttribute']);
				echo'<br>';
			print_r ($args['dateEvents']);
				echo'<br>';
		*/
		
		// balise HTML de fermeture du bloc groupe
		$original_closing_tag = '</div>';
		
		// si on a activé un compte à rebours 
		// avec des compteurs de forme circulaire
		if ( $args['withCircularCountdown'] ){
			
			$zoom = $args['circleDiameter']/100;
			
			// nouveau balisage en fermeture du bloc groupe
			// pour notre style compte à rebours 
			// avec des compteurs de forme circulaire
			  $new_closing_tag = '<div class="countdown-wrapper"'. 'circular-countdown="' . esc_attr( $args['withCircularCountdown'] ) .'" circle-diameter="' . esc_attr( $args['circleDiameter'] ) . '">';
		
				// compteur jours     
				$new_closing_tag .= '<div class="countdown-item" style="transform:scale('.$zoom.');margin:calc(('.$zoom.' - 1)* 50 * 1px + 10px);background:'.$args['daysCircleBackgroundColor'].';">';
					$new_closing_tag .= '<svg xmlns="http://www.w3.org/2000/svg" class="countdown-svg" >'; 
						$new_closing_tag .= '<path d="" id="arc-days" fill="none" stroke="'.$args['daysCircleBorderColor'].'" stroke-width="4" />'; 
					$new_closing_tag .= '</svg>'; 
						$new_closing_tag .= '<span style="color:'.$args['daysCircleTextColor'].';" class="days"> </span>';
						$new_closing_tag .= '<span style="color:'.$args['daysCircleTextColor'].';">'.__( 'Days','editor-custom-color-palette'). '</span>';				
				$new_closing_tag .= '</div>';
			
				// compteur heures
				$new_closing_tag .= '<div class="countdown-item" style="transform:scale('.$zoom.');margin:calc(('.$zoom.' - 1)* 50 * 1px + 10px);background:'.$args['hoursCircleBackgroundColor'].';">';
					$new_closing_tag .= '<svg xmlns="http://www.w3.org/2000/svg" class="countdown-svg" >'; 
						$new_closing_tag .= '<path d="" id="arc-hours" fill="none" stroke="'.$args['hoursCircleBorderColor'].'" stroke-width="4" />'; 
					$new_closing_tag .= '</svg>'; 
						$new_closing_tag .= '<span style="color:'.$args['hoursCircleTextColor'].';" class="hours"> </span>';
						$new_closing_tag .= '<span style="color:'.$args['hoursCircleTextColor'].';">'.__( 'Hours','editor-custom-color-palette'). '</span>';				
				$new_closing_tag .= '</div>'; 
			
				// compteur minutes
				$new_closing_tag .= '<div class="countdown-item" style="transform:scale('.$zoom.');margin:calc(('.$zoom.' - 1)* 50 * 1px + 10px);background:'.$args['minutesCircleBackgroundColor'].';">';
					$new_closing_tag .= '<svg xmlns="http://www.w3.org/2000/svg" class="countdown-svg" >'; 
						$new_closing_tag .= '<path d="" id="arc-minutes" fill="none" stroke="'.$args['minutesCircleBorderColor'].'" stroke-width="4" />'; 
					$new_closing_tag .= '</svg>'; 
						$new_closing_tag .= '<span style="color:'.$args['minutesCircleTextColor'].';" class="minutes"> </span>';
						$new_closing_tag .= '<span style="color:'.$args['minutesCircleTextColor'].';">'.__( 'Minutes','editor-custom-color-palette'). '</span>';				
				$new_closing_tag .= '</div>';
			
				//compteur secondes
				$new_closing_tag .= '<div class="countdown-item" style="transform:scale('.$zoom.');margin:calc(('.$zoom.' - 1)* 50 * 1px + 10px);background:'.$args['secondsCircleBackgroundColor'].';">';
					$new_closing_tag .= '<svg xmlns="http://www.w3.org/2000/svg" class="countdown-svg" >'; 
						$new_closing_tag .= '<path d="" id="arc-seconds" fill="none" stroke="'.$args['secondsCircleBorderColor'].'" stroke-width="4" />'; 
					$new_closing_tag .= '</svg>'; 
						$new_closing_tag .= '<span style="color:'.$args['secondsCircleTextColor'].';" class="seconds"> </span>';
						$new_closing_tag .= '<span style="color:'.$args['secondsCircleTextColor'].';" >'.__( 'Seconds','editor-custom-color-palette'). '</span>';				
				$new_closing_tag .= '</div>'; 
		
			$new_closing_tag .= '</div>';

		} else {
			
			// nouveau balisage en fermeture du bloc groupe
			// pour notre style compte à rebours 
			// avec des compteurs de forme carré
			$new_closing_tag = '<ul id="countdown">';
			
				// compteur jours
				$new_closing_tag .= '<li>'; 
					$new_closing_tag .= '<p class="timeRefDays">'.__( 'Days','editor-custom-color-palette').'</p>'; 
					$new_closing_tag .= "<span class='days'> </span>"; 
				$new_closing_tag .= '</li>';
				
				// compteur heures
				$new_closing_tag .= '<li>';
					$new_closing_tag .= '<p class="timeRefHours">'.__( 'Hours','editor-custom-color-palette').'</p>';
					$new_closing_tag .= "<span class='hours'> </span>";
				$new_closing_tag .= '</li>'; 
				
				// compteur minutes
				$new_closing_tag .= '<li>';
					$new_closing_tag .= '<p class="timeRefMinutes">'.__( 'Minutes','editor-custom-color-palette').'</p>';
					$new_closing_tag .= "<span class='minutes'> </span>";
				$new_closing_tag .= '</li>';
				
				//compteur secondes
				$new_closing_tag .= '<li>';
					$new_closing_tag .= '<p class="timeRefSeconds">'.__( 'Seconds','editor-custom-color-palette').'</p>';
					$new_closing_tag .= "<span class='seconds'> </span>";
				$new_closing_tag .= '</li>';
				
			$new_closing_tag .= '</ul>'; 
			
		}
		
		$new_closing_tag .= $original_closing_tag;
		
		// on remplace dans le contenu du bloc la balise de fermeture originale 
		// par la nouvelle qui contient le Compte A Rebours
		$block_content = str_replace( $original_closing_tag, $new_closing_tag, $block_content );
		
	}
	
	return $block_content;
}

add_filter( 'render_block', 'eccp_countdown', 10, 2 );


// Passage de la date d'évènement du compte à rebours au script JS
// qui actualise le compte à rebours
// on va utiliser DOM pour passer la variable PHP à JavaScript
// en concret on utilise un div caché pour afficher notre variable sur la page HTML
// pour la récupérer ensuite par javascript avec le script: eccp-countdown-timer.js */  
 function eccp_get_countdown_timer_date_events(){ 

	$date = get_post_meta( get_the_ID(), 'countdown_timer_date_events', true );
	
	// pour la date du 31/01/2023 la date retourné par le DatePicker
	// a l'attribut date_events est: 2023-01-31T13:34:51
	// la date doit être au format anglais pour la conversion au format timestamp
	// on  va éliminer l'heure et ne conserver que la date
	// pour une bonne conversion au format timestamp
	$date_events = substr($date, 0, stripos($date, 'T') );
	
	/* ancien code pour conserver l'heure mais supprimer le caractère 'T'
		$date_events = substr($date, 0, stripos($date, 'T') );
		$date_events .=' ';
		$date_events .= substr($date, stripos($date, 'T') + 1 );
	*/
	
	?>
	<div id="data-date-events" style="display:none;" >
		<?php
			echo esc_html($date_events); 
		?>
	</div>
	<?php
	
 }
 
add_action( 'wp_head','eccp_get_countdown_timer_date_events',100 );


/* Bloc Groupe: AJOUT EN FRONT END DU STYLE TABLE OF CONTENTS */

/*

********* structure balisage liste ordonnée WordPress *********

<ol class="is-style-eccp-table-of-contents-bullet-list">

	<li class="heading-level-2">
    		<a href="#introduction">Titre H2</a>
				<ol>
						<li class="heading-level-3">
							<a href="#a-propos">Titre H3</a>
						</li>
						
						<li class="heading-level-3">
							<a href="#deuxième-titre-h3">deuxième titre H3</a>
						
								<ol>
									<li class="heading-level-4">
										<a href="#le-concours">Titre H4</a>

											<ol>
												<li class="heading-level-5">
													<a href="#le-concours">Titre H5</a>
												</li>
											
											</ol>
									</li>
								</ol>
						</li>
				</ol>
	</li>

	<li class="heading-level-2">
		<a href="#suivez-rock-4-you">Titre H2</a>
	</li>
	
</ol>

• Lorsque deux titres de même niveau hièrarchique se suivent on ferme la balise </li>
du 1er titre. 

• On laisse la balise <li> ouverte et on ajoute une balise <ol> pour une liste
ordonnée imbriqué lorsque le titre qui suit baisse dans la hièrarchie, 
afin d'identer la liste.

• lorsque le titre qui suit augmente dans la hièrarchie, on ferme les balises </ol>
ce qui ferme automatiquement les balises </li> et permet de supprimer l'identation.


******* Structure HTML de la table des matières ********

A partir du panneau avancé du bloc groupe on change la balise
<div> par défaut du bloc groupe en <article> sinon la table
des matières est répétée pour chaque bloc groupe!!
Un bloc code est ajouté en back office au block groupe pour
mettre en évidence que c'est le bloc Table des matières.
Ce bloc code est masqué en Front End.
On utilise un bloc code pour éviter que l'intitulé Table des matières soit repris
dans le résumé apparaissant dans le bloc boucle de requête
ou Derniers Articles.
On utilise la balise <détails> qui permet de révéler ou non
son contenu suivant repectivement la valeur d'un attribut
open afin de créer un effet accordéon.
par défaut la balise <détails> est fermé et il n' y a pas d'attribut
l'attribut open ou rien varie automatiquement suivant le clic sur la balise <détails>.
Pour avoir le contenu de la balise <détails> affiché par défaut on ajoute l'attribut open
le contenu de la balise <détails> sera une liste ordonnée imbriquée selon le niveau des titres.
la 1ère balise enfant de <détails> est summary pour fournir
un intitulé au contenu, cette balise bien que contenu
dans la balise <détails> est toujours visible.
il n'existe aucun moyen intégré d'animer la transition 
entre l'ouverture et la fermeture.

<article class="wp-block-group is-style-eccp-toc">
	<pre class="wp-block-code">
		<code>TABLE DES MATIÈRES</code>
	</pre>
	<div class="eccp-toc">
		<details open>
			<summary>
			Table des matières
			</summary>
			<nav aria-label="table of contents">
				<ol class=is-style-eccp-table-of-contents-bullet-list>
					<!--items ici de la table des matières-->
				</ol>
			</nav>
		</details>
	</div>
</article>


*/
function eccp_table_of_contents_group_block( $block_content, $block ) {

	
	global $post;

	$headings = [];
	
	// correction pour Bug avec la page qui liste les évènements 
	// de l'extension The Events Calendar 
	if(empty($post->post_content)){
		return '';
	}
	
	// s'il y a des blocs on récupère un tableau de tous
	// les blocs du contenu de la publication
	if ( has_blocks( $post->post_content ) ) {
		$blocks = parse_blocks($post->post_content);
	}else{
		return $block_content;
	}
	
	/* Pour Debug
	echo'<pre'>
		print_r($blocks);
	echo'</pre>';
	*/
	
	// on parcours les blocs
	// on récupère les titres et leur niveau 
	foreach ($blocks as $block) {
		
		
		if ($block['blockName'] === 'core/heading') {
			
			// s'il n'y a pas de niveau alors c'est un titre H2, on lui attribue le niveau 2
			// En effet par défaut la fonction parse_blocks() de WordPress 
			// ne retourne pas de niveau pour le titre H2
			$level = (isset($block['attrs']['level'])) ? $block['attrs']['level'] : 2;  
			
			// wp_strip_all_tags permet de supprimer toutes les balises HTML du contenu
			$title = wp_strip_all_tags($block['innerHTML']);
			
			$headings[] = ['title' => $title , 'level' => $level];
			
			//$search  = array('(',')',"'",'"','&amp;','€',);
			//$replace = array(' ',' '," ",' ',' ');' '

			// On supprime des caractères spéciaux comme la parenthèse du titre 
			// pour l'item de liste du sommaire par un espacement blanc. 
			// En effet l'assinissement du titre par la fonction WordPress sanitize_tittle 
			// remplace la parenthèse par rien contrairement a un espace blanc
			// qui est remplacé par un tiret,ceci afin de correspondre a une autre manière d'assainir
			// le titre de la publication  par la fonction eccp_add_anchor_title_tag($matches)
			//$title = str_replace($search, $replace, $title );	
			//echo  $title.'<br>';
			
			// on ajoute l'ancre id=slug-titre a la balise d'ouverture <h> du titre
			//$block_content = str_replace('>'.$title, ' id="'.eccp_sanitize_heading($title).'"'.'>'.$title, $block_content);
		
		}
	
	}
	
	
	/* Pour debug 
	echo'<pre>';
		echo 'nombre de titre: '.count($headings).'<br>';
		print_r($headings);
	echo'</pre>';
	*/
	
	
	// S'il n'y a pas de titre on sort
	if (empty($headings)) {  
		return $block_content;
	}
	
	
	/*
	 Ajouter les ancres sur les différentes titres, 
	 on ajoute un filtre sur le contenu des publications qui va rechercher 
	 les balises h2,h3,h4,h5 et h6 et placer des id sur ces balises.
	 pour cela on utilise la fonction preg_replace_callback()de PHP 
	 qui permet de faire des modifications sur des éléments 
	 que notre regex($pattern) va isoler dans la chaîne
	 Notre regex /<h([2-6])(.*?)>(.*?)</h([2-6])>/ recherche tout ce qui correspond 
	 à des balise <h2>,<h3> <h4> etc.., peut importe leur attribut ou leur contenu.
	*/
	 $pattern = "/<h([2-6])(.*?)>(.*?)<\/h([2-6])>/i";
	 $block_content = preg_replace_callback($pattern, 'eccp_add_anchor_title_tag', $block_content);
	

	// on retourne la balise de fermeture </div> modifié	
	// du bloc groupe
	foreach ($blocks as $block) {

		// si c'est le bloc groupe avec une classe is-style-eccp-toc
		if( 'core/group' === $block['blockName'] && !empty( $block['attrs']['className'] ) 
			&& 'is-style-eccp-toc' === $block['attrs']['className'] ) {
		
			// On récupère les paramètres de l'extension pour la personnalisation des blocs Gutenberg
			$custom_gutenberg_blocks_settings = get_option( 'eccp_settings_custom_gutenberg_block' );
			
			// titre de la table des matières
			$title_toc = $custom_gutenberg_blocks_settings['eccp_settings_name_table_of_contents_text_field'];
		
			// balise HTML originale de fermeture du bloc Groupe
			$original_closing_tag = '</article>';
			
			// on initialise la nouvelle balise de fermeture
			$new_closing_tag = '<div class="eccp-toc">
									<details open>
										<summary>'.
										$title_toc.
										'</summary>
										<nav aria-label="table of contents">
											<ol class="is-style-eccp-table-of-contents-bullet-list">';
			$i = 0;
			$balise_ol_ouverte = 0;
			
			// Nouveau balisage en fermeture du bloc groupe
			// pour notre style Table Of Contents en incorporant les ancres
			foreach ($headings as $heading) {
				
				// pour le caratère & on prend son code HTML: &amp;
				$search  = array('(',')',"'",'"','&amp;');
				$replace = array(' ',' '," ",' ',' ');

				// On supprime des caractères spéciaux comme la parenthèse du titre 
				// pour l'item de liste du sommaire par un espacement blanc. 
				// En effet l'assainissement du titre par la fonction WordPress sanitize_tittle 
				// remplace la parenthèse par rien contrairement a un espace blanc
				// qui est remplacé par un tiret,ceci afin de correspondre a l'assainissement
				// du titre de la publication  par la fonction eccp_add_anchor_title_tag($matches)
				$title = str_replace($search, $replace, $heading['title']);	 
				 
				// on initialise le 1er élément de la table des matières qui doit être de niveau H2 
				// ou H3(si le titre de l'article est en H2)
				if ($i == 0) {
					
					// c'est le seul & unique titre de la publication on ferme la balise '</li>' 
					if ($i == count($headings)-1){
						$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li>';	
				
					// sinon si le titre suivant est de même niveau on ferme la balise '</li>'
					}else if ( isset($headings[$i+1]['level']) && ( $headings[$i+1]['level'] == $headings[$i]['level'] ) ){
						$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li>';
					
					// sinon le titre suivant est de niveau inférieur 
					// on laisse la balise '<li>' ouverte pour pouvoir ensuite identer
					}else {
						$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a>';
					}
					
				}
				
				if ($i > 0) {
					
					
					
					/*----------------------------------------------------------*/
					// si le titre précédent est supérieur hiérarchiquement alors on idente la liste 
					if ( $headings[$i]['level'] > $headings[$i-1]['level'] ){
						
						$balise_ol_ouverte++;
					
						// si le titre suivant est de même niveau 
						// on laisse la balise '<ol>' de l'identation ouverte & on ferme la balise '</li>'
						if (isset($headings[$i+1]['level']) && ( $headings[$i+1]['level'] == $headings[$i]['level'] ) ){
							$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li>';
						
						// sinon le titre suivant est de niveau inférieur 
						// on laisse la balise '<ol>' de l'identation & la balise '<li>' ouverte
						// pour pouvoir identer a nouveau
						}else if ( isset($headings[$i+1]['level']) && ( $headings[$i+1]['level'] > $headings[$i]['level'] )  ){
							$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a>';
						
						// sinon le titre suivant est de niveau hiérachique supérieur 
						}else {
							
							// si le niveau du titre suivant est le plus élevé de l'article
							// on ouvre la balise <ol> pour pouvoir identer
							// on ferme toutes les balises '</ol>' ce qui va fermer automatiquement les balises '</li>'
							// fermetures maximun de balises '</ol>':
							// si le 1er titre de l'article est un H2 alors
							// 1 fermeture balise ol pour le titre H3, 2 pour H4,3 pour H5,4 pour H6
							// si le 1er titre de l'article est un H3 alors
							// 1 fermeture balise ol pour le titre H4, 2 pour H5,3 pour H6
							if ( isset($headings[$i+1]['level']) &&  ( $headings[$i+1]['level'] == $headings[0]['level'] )  ){
							
								// selon le nombre de balise ol ouverte
								// on ferme le nombre de balise ol requise
								switch ($balise_ol_ouverte) {
								
									case 1:
										$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol>';
										  break;
										  
									case 2:
										$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol>';
										  break;
										  
									case 3:
										$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol></ol>';
										  break;
										  
									case 4:
										$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol></ol></ol>';
										  break;
										  
								}
								
								$balise_ol_ouverte = 0;
							
							// Sinon le titre suivant est supérieur mais de niveau H5 , H4 ou H3						
							}else{
								
								if ( isset($headings[$i+1]['level']) ) {
								
									// selon (le niveau du titre en cours - le niveau du titre suivant)
									// on ouvre la balise <ol> pour pouvoir identer
									// on ferme le nombre de balise </ol> requise pour les identations précédentes
									switch ($headings[$i]['level'] - $headings[$i+1]['level']) {
									
										case 1:
											$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol>';
											$balise_ol_ouverte = $balise_ol_ouverte - 1; 
											  break;
											  
										case 2:
											$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol>';
											$balise_ol_ouverte = $balise_ol_ouverte - 2;  
											  break;
											  
										case 3:
											$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol></ol>';
											$balise_ol_ouverte = $balise_ol_ouverte - 3;  
											  break;
											  
											  
									}
								
								}
								
							}
						
						}
			
			
					/*----------------------------------------------------------*/
					// sinon si le titre précédent est de même niveau hiérachique
					}else if ( $headings[$i]['level'] == $headings[$i-1]['level'] ){
						
						// si c'est le dernier titre de la publication on ferme la balise '</li>' 
						if ($i == count($headings)-1){
							$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li>';	
						}
						
						// si le titre suivant est de même niveau 
						// on ferme la balise '</li>'
						if ( isset($headings[$i+1]['level']) && ( $headings[$i+1]['level'] == $headings[$i]['level'] ) ){
						
							$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li>';
						
						// sinon le titre suivant est de niveau inférieur 
						// on laisse la balise '<li>' ouverte pour pouvoir identer
						}else if ( isset($headings[$i+1]['level']) && ( $headings[$i+1]['level'] > $headings[$i]['level'] )  ){
							$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a>';
						
						// sinon le titre suivant est de niveau hiérachique supérieur
						}else{
							
							// si le niveau du titre suivant est le plus élevé de l'article
							// on ferme toutes les balises '</ol>' ce qui va fermer automatiquement les balises '</li>'
							// fermetures maximun de balises '</ol>':
							// si le 1er titre de l'article est un H2 alors
							// 1 fermeture balise ol pour le titre H3, 2 pour H4,3 pour H5,4 pour H6
							// si le 1er titre de l'article est un H3 alors
							// 1 fermeture balise ol pour le titre H4, 2 pour H5,3 pour H6
							if ( isset($headings[$i+1]['level']) &&  ( $headings[$i+1]['level'] == $headings[0]['level'] )  ){
							
								// selon le nombre de balise ol ouverte
								// on ferme le nombre de balise ol requise
								switch ($balise_ol_ouverte) {
								
									case 1:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol>';
										  break;
										  
									case 2:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol>';
										  break;
										  
									case 3:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol></ol>';
										  break;
										  
									case 4:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol></ol></ol>';
										  break;
										  
								}
								
								$balise_ol_ouverte = 0;
							
							// Sinon le titre suivant est supérieur mais de niveau H5 , H4 ou H3						
							}else{
								
								if( isset($headings[$i+1]['level']) ){
								
									// selon le niveau du titre en cours - le niveau du titre suivant
									// on ferme le nombre de balise ol requise
									switch ($headings[$i]['level'] - $headings[$i+1]['level']) {
									
										case 1:
											$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol>';
											$balise_ol_ouverte = $balise_ol_ouverte - 1;
											  break;
											  
										case 2:
											$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol>';
											$balise_ol_ouverte = $balise_ol_ouverte - 2;  
											  break;
											  
										case 3:
											$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol></ol>';
											$balise_ol_ouverte = $balise_ol_ouverte - 3;  
											  break;
											  
											  
									}
								
								}
								
							}
							
						}
					
					/*----------------------------------------------------------*/					
					// sinon si le titre précédent est d'un niveau hiérarchique inférieur
					}else{
						
						
						// si c'est le dernier titre de la publication 
						if ($i == (count($headings)-1) ){
							
							// si le niveau de titre en cours est le plus élevé de la publication
							if ( $headings[$i]['level'] == $headings[0]['level'] ){
							
								// On ferme seulement la balise </li> car les balises
								// </ol> ont été fermées précédement par le titre de niveau inférieur
								$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li>';
							
							// Sinon le titre en cours est supérieur mais de niveau H5 , H4 ou H3						
							}else{
								
								// selon (le niveau du titre précédent - le niveau du titre en cours)
								// on ferme le nombre de balise ol requise pour les identations précédentes
								switch ($headings[$i-1]['level'] - $headings[$i]['level']) {
								
									case 1:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol>';
										$balise_ol_ouverte = $balise_ol_ouverte - 1 ;
										  break;
										  
									case 2:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol>';
										$balise_ol_ouverte = $balise_ol_ouverte - 2;  
										  break;
										  
									case 3:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol></ol>';
										$balise_ol_ouverte = $balise_ol_ouverte - 3;  
										  break;
										  
										  
								}
								
							}	
						
						// si le titre en cours est le plus élevé de la publication
						}else if ( $headings[$i]['level'] == $headings[0]['level'] ){
						
							//$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li>';
						
							// si le titre suivant est de même niveau
							// on ferme seulement la balise </li> car les balises
							// </ol> ont été fermées précédement par le titre de niveau inférieur
							if( isset($headings[$i+1]['level']) && ( $headings[$i+1]['level'] == $headings[$i]['level'] ) ) {
								$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li>';
							
							// alors le titre suivant est obligatoirement d'un niveau inférieur
							// on laisse la balise <li> ouverte pour pouvoir identer
							// pas besoin d'ouvrir la balise <ol> car cela a été fait par le 
							// 1er titre hièrarchiquement le plus élevé de la publication
							}else {
								$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a>';
							}
							
						// Sinon le titre en cours est de niveau H5,H4 ou H3
						// si le titre suivant est d'un niveau hiérachique inférieur					
						}else if( isset($headings[$i+1]['level']) && ( $headings[$i+1]['level'] > $headings[$i]['level'] ) ) {
							
							// selon (le niveau du titre précédent - le niveau du titre en cours)
							// on ouvre une balise <ol> 
							// et on laisse la balise <li> ouverte pour pouvoir identer le titre suivant
							// on ferme le nombre de balise </ol> requise pour les identations précédentes
							switch ($headings[$i-1]['level'] - $headings[$i]['level']) {
							
								case 1:
									$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></ol>';
									$balise_ol_ouverte = $balise_ol_ouverte - 1 ;
									  break;
									  
								case 2:
									$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></ol></ol>';
									$balise_ol_ouverte = $balise_ol_ouverte - 2;  
									  break;
									  
								case 3:
									$new_closing_tag .= '<ol><li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></ol></ol></ol>';
									$balise_ol_ouverte = $balise_ol_ouverte - 3;  
									  break;
									  
									  
							}
							
						// Sinon le titre en cours est de niveau H5,H4 ou H3
						// et le titre suivant est de même niveau						
						}else if( isset($headings[$i+1]['level']) && ( $headings[$i+1]['level'] == $headings[$i]['level'] ) ) {
							
							// on ferme la balise </li> 
							$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li>';
							
						// Sinon le titre en cours est de niveau H5,H4 ou H3
						// et le titre suivant est d'un niveau hiérachique supérieur		
						}else{
							
							
							// si le titre suivant est hièrarchiquement le plus élevé 
							// de la publication 
							if ( isset($headings[$i+1]['level']) && ( $headings[$i+1]['level'] == $headings[0]['level'] ) ){
						
								// selon le nombre de balise ol ouverte
								// on ferme le nombre de balise ol requise
								switch ($balise_ol_ouverte) {
								
									case 1:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol>';
										  break;
										  
									case 2:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol>';
										  break;
										  
									case 3:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol></ol>';
										  break;
										  
									case 4:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol></ol></ol>';
										  break;
										  
								}
							
								$balise_ol_ouverte = 0;
							
							}else{
								
								// selon (le niveau du titre précédent - le niveau du titre en cours)
								// on ferme le nombre de balise ol requise pour les identations précédentes
								// et on ferme la balise </li> 
								switch ($headings[$i-1]['level'] - $headings[$i]['level']) {
								
									case 1:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol> ';
										$balise_ol_ouverte = $balise_ol_ouverte - 1 ;
										  break;
										  
									case 2:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol>';
										$balise_ol_ouverte = $balise_ol_ouverte - 2;  
										  break;
										  
									case 3:
										$new_closing_tag .= '<li class="heading-level-' . $heading['level'] . '">'.'<a href="#'.sanitize_title($title) . '">' . $heading['title'] . '</a></li></ol></ol></ol>';
										$balise_ol_ouverte = $balise_ol_ouverte - 3;  
										  break;
										  
										  
								}
							
							}
							
							
						}
						
							
					}
			
				}
				
				$i++;
			
			}
			
			$new_closing_tag .= '</nav></details></div>'.$original_closing_tag;
			
			// on remplace dans le contenu du bloc la balise de fermeture originale 
			// par la nouvelle qui contient la table des matières
			$block_content = str_replace( $original_closing_tag, $new_closing_tag, $block_content );
			
			
		
		}
	
	}

	return $block_content;

}

add_filter( 'render_block', 'eccp_table_of_contents_group_block',10, 2 );


// Autre manière pour ajouter l'ancre dans la balise du titre 
// au format <h2 id="slug-titre">
// $matches[1] & $matches[4] = level du titre
// $matches[2]= attribut du titre
// $matches[3] = libellé du titre
function eccp_add_anchor_title_tag($matches){
  return '<h'.$matches[1].$matches[2].' id="'.eccp_sanitize_heading($matches[3]).'">'.$matches[3].'</h'.$matches[4].'>';
}


// Fonction pour palier aux manques de la fonction WordPress sanitize_title():
// de manière aléatoire sanitize_title() ne convertie pas un carractère accentué
// ou remplace la parenthèse '(' par rien ou un tiret
// On nettoie les titres pour les faires correspondre a des slug
// avant de pouvoir les utiliser comme référence pour les ancres
function eccp_sanitize_heading($string) {
	
	// pour le caratère & on prend son code HTML: &amp;
	$search  = array('(',')',"'",'"','′','‘','“','”','&amp;',);
	$replace = array(' ',' '," ",' ',"'","'",'"','"',' ',);

	// On supprime des caractères spéciaux comme la parenthèse du titre 
	// pour l'item de liste du sommaire par un espacement blanc. 
	// En effet l'assinissement du titre par la fonction WordPress sanitize_tittle 
	// remplace la parenthèse par rien contrairement a un espace blanc
	// qui est remplacé par un tiret,ceci afin de correspondre a une autre manière d'assainir
	// le titre de la publication  par la fonction eccp_add_anchor_title_tag($matches)
	$string = str_replace($search, $replace,$string );	
	
	$search  = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'à', 'á', 'â', 'ã', 'ä', 'å', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ð', 'ò', 'ó', 'ô', 'õ', 'ö', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ',);

	$replace = array('a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y',);

	// on retourne une chaine avec les caractères accentués
	// converti en minuscule sans accent 
	// on utilise la fonction str_replace qui ne pose pas de problème en utf-8 
	// contrairement à strtr
    //	Remarque: la fonction sanitize_title() fait la même chose
	//  mais bizarement parfois elle ne converti pas un caractère accentué.
	$string = str_replace($search, $replace, $string);	
	
	// on converti les majuscules initialement non accentués restantes en minuscule 
	// seulement maintenant car  la fonction strtolower ne gère pas les accents
    //$string = strtolower($string);
	
	$string = sanitize_title($string);

    //Rendre alphanumérique (supprime tous les autres caractères)
    //$string = preg_replace("/[^a-z0-9_\s-]/", "", $string);
	
    //Nettoyer plusieurs tirets ou espaces blancs
    //$string = preg_replace("/[\s-]+/", " ", $string);
	
    //Convertir les espaces blancs et le trait de soulignement en tiret
    //$string = preg_replace("/[\s_]/", "-", $string);
	
	// Je supprime tous les tirets en début ou en fin de chaine
	// au cas ou il y aurait eu un caractère spécial en début ou fin de chaine
	$string= trim($string, '-');

    return $string;
	
}


/* Transformer le bloc Galerie de WordPress en un slider utilisant la bibliothèque Swiper */

/*
Pour Transformer le bloc Galerie de WordPress en un slider 
utilisant la bibliothèque Swiper on doit: 
• Modifier en Front End le balisage du bloc Galerie pour 
correspondre au balisage HTML  requis par Swiper
• Ajouter des styles CSS personnalisés 
• Initialiser le slider avec des paramètres spécifiques via un script JS
• charger les fichiers js & css de la librairie Swiper via un CDN


On Transforme le bloc galerie de WordPress en slider en utilisant le hook 
render_block pour modifier le balisage en front end du bloc galerie 
pour qu'il corresponde au balisage HTML de Swiper.

- Le hook render_block s'applique a la fonction eccp_render_slideshow()
- On exécute les instructions de cette fonction:
• si c'est le bloc galerie
• si on a activé le slider dans les paramètres du bloc via le 
contôle select ayant l'attribut styleAttribute
• s'il comporte des bloc d'images interne
- On parcours les blocs d'image internes aux galeries et on extrait les ID d'image, 
avec lequel on récupère les attributs: URL, width, heigth, alt
- Dans le container Principal de classe .swiper on ajoute dans le balisage HTML
différents attributs qui sont affectés avec les valeurs des attributs 
du bloc galerie pour définir:
• le délai pour la lecture automatique
• la largeur du slider
• l'alignement centré
• la navigation par points
• la navigation par flêches
• la navigation par barre de défilement

- On construit le nouveau balisage en accord avec Swiper en incorporant
des diapositives avec les éléments <div class="swiper-slide"> container
d'une balise <img> avec tous les attributs du bloc image interne du bloc galerie.
 
- On termine le balisage de Swipe avec:
• la pagination par points: on introduit dans le balisage 
une variable CSS --slider-dotsNavColor pour la couleur 
de la navigation par points
• Navigation par flêches: on introduit dans le balisage 
une variable CSS --slider-arrowsNavColor pour la couleur 
de la navigation par points
• Barre de défilement.


La fonction eccp_enqueue_slider_swipe() ajoute du JavaScript  
via le script:eccp-slider-swiper.js pour initialiser le slider Swiper. 
• Elle définit les paramètres du slider, tels que la direction, 
la pagination, la navigation, les effets de transition, etc.
Récupère les attributs définits lors du balisage HTML du slider pour:
• Appliquer des régles CSS pour la largeur du slider, l'alignement centré ou pas
• Activer la lecture automatique ou pas

La fonction eccp_load_slider_swipe_script() est utilisée pour charger dans le head  
les scripts JavaScript et les fichiers CSS de la bibliothèque Swiper depuis un CDN.

La fonction ecpp_block_style_front_end() 
ajoute des styles CSS personnalisés pour le slider Swiper 
a cette section: Slider Swiper pour le bloc Galerie & bloc Groupe
on utilise notamment les variables globales CSS définit avec la proriété style
dans le balisage du slider pour définir:
• la couleur des flêches de navigation: --slider-arrowsNavColor
• la couleur de la navigation par points: --slider-dotsNavColor

*/

function eccp_render_slideshow_gallery($block_content, $block) {
	
	
	// les attributs styleAttribute,sliderWidth, withSliderAlignCenter,
	// withSliderDots,withSliderArrows,withSliderScrollbar,
	// withSliderAutoplay,sliderAutoplayDelay
	// ont été définit en React JS pour le bloc galerie
	// wp_parse_args permet de fusionner un tableau d'arguments $block['attrs'] 
	// et un tableau de valeurs par défaut
 	$args = wp_parse_args(
	
 		$block['attrs'],
 		[
 			'styleAttribute' => 'none',
			'withAlignFull' => false,
			'sliderWidth' => 720,
 			'withSliderAlignCenter' => false,
			'withSliderDots' => true,
			'DotsNavColorAttribute' => '#FFFFFF',
			'withSliderArrows' => true,
			'arrowsNavColorAttribute' => '#FFFFFF',
			'arrowsNavBgcolorAttribute' => 'transparent',
			'arrowsNavHoverBgcolorAttribute' => 'transparent',
			'withSliderScrollbar' => false,
 			'withSliderAutoplay' => false,
			'sliderAutoplayDelay' => 3500,
 		]
 	);
	
    // si c'est le bloc galerie
	if( 'core/gallery' === $block['blockName'] 
	// le slider est activé via l'attribut styleAttribute
	&& $args['styleAttribute'] == 'slider'
    // La galerie contient des blocs images.
	&& !empty( $inner_blocks = $block[ 'innerBlocks' ]) ) {  
      
		// valeur par défaut pour la taille des images
		$image_size = 'full';
		
		if (array_key_exists('sizeSlug', $block['attrs'])) {
			$image_size = $block['attrs']['sizeSlug'];
		}
		
		$image_ids = array();
	
		// Parcourir les blocs d'image internes et extraire les ID d'image.
		foreach ($inner_blocks as $inner_block) {
			
			if ($inner_block['blockName'] != 'core/image') {
				// ... on ne fait rien
			} elseif (($image_id = intval($inner_block['attrs']['id'])) <= 0) {
				// ... on ne fait rien
			} else {
				$image_ids[] = $image_id;
			}
			
		}
		
		
		//===== Construire le nouveau balisage pour le slider avec Swiper =======
		
		// si on a choisi l'alignement pleine largeur
		if($args['withAlignFull']){
			
			// container du slider avec la classe swiper
			// pour	personnaliser le slider via script js
			// on ajoute différents attributs dont slider-autoplay-delay
			// si on a activé la lecture automatique du slider
			// la classe native de WordPress: alignfull pour un alignement pleine largeur
			if($args['withSliderAutoplay']) {
				$block_content = '<div class="swiper alignfull" slider-autoplay-delay="' . esc_attr( $args['sliderAutoplayDelay'] ) .'"'  
				.' slider-with-arrows="' . esc_attr( $args['withSliderArrows'] ) . '">';
			}else{
				$block_content = '<div class="swiper alignfull"' 
				.' slider-width-scrollbar="'. esc_attr( $args['withSliderScrollbar'] ) .'">';
			}
			
		// sinon aucun alignement	
		}else{
			
			// container du slider avec la classe swiper
			// pour	personnaliser le slider via script js
			// on ajoute différents attributs dont slider-autoplay-delay
			// si on a activé la lecture automatique du slider
			if($args['withSliderAutoplay']) {
				$block_content = '<div class="swiper" slider-autoplay-delay="' . esc_attr( $args['sliderAutoplayDelay'] ) .'"'  
				.' slider-width="' . esc_attr( $args['sliderWidth'] ) .'"' 
				.' slider-align-center="' . esc_attr( $args['withSliderAlignCenter'] ) . '"'
				.' slider-with-arrows="' . esc_attr( $args['withSliderArrows'] ) . '">';
			}else{
				$block_content = '<div class="swiper" slider-width="' . esc_attr( $args['sliderWidth'] ) .'"' 
				.' slider-align-center="' . esc_attr( $args['withSliderAlignCenter'] ).'"' .' slider-width-scrollbar="'. esc_attr( $args['withSliderScrollbar'] ) .'">';
			}
		
		}
				
		// Additional required wrapper
		$block_content .= '<div class="swiper-wrapper">';

		// Parcourir les images du bloc galerie et les ajouter 
		// en tant que slide (diapositives)
		foreach ( $image_ids as $image_id ) { 
		
			// on récupère les attributs des images
			$image_src = wp_get_attachment_image_src ( $image_id, $image_size ) ; 
			$image_url = $image_src[0] ;
			$image_width = $image_src[1] ;
			$image_height = $image_src[2] ;
			$image_alt = get_post_meta ( $image_id, '_wp_attachment_image_alt' , true ) ; 
			
			// Chaque diapositive est une image contenu dans un élément div
			// ayant pour classe swiper-slide
			$block_content .= '<div class="swiper-slide">';
				// balisage pour agrandir l'image par geste de pincement 
				// et ou par zoom avant/arrière en appuyant deux fois
				$block_content .=	'<div class="swiper-zoom-container">';
					$block_content .= '<img src="' . esc_url($image_url) . '" width="' . esc_attr($image_width) . '" height="' . esc_attr($image_height) . '" alt="' . esc_attr($image_alt) . '">';
				$block_content .= '</div>';
			$block_content .= '</div>';
			
		}
	
		$block_content .= '</div>';// fin div wrapper
		
		// si on a activé la navigation par points
		if($args['withSliderDots']) {
			// balisage HTML pour la navigation par points 
			//en bas du slide
			$block_content .= '<div style="--slider-dotsNavColor:'.$args['DotsNavColorAttribute'].';" class="swiper-pagination"></div>';
		}
		
		// si on a activé la navigation par flêches
		if($args['withSliderArrows']) {
			// balisage HTML pour la navigation par flêches
			$block_content .= '<div style="--slider-arrowsNavColor:'.$args['arrowsNavColorAttribute']. ';'. ' --slider-arrowsNavBgcolor:'.$args['arrowsNavBgcolorAttribute']. ';' . ' --slider-arrowsNavHoverBgcolor:'.$args['arrowsNavHoverBgcolorAttribute'] . ';" class="swiper-button-prev"></div>';
			$block_content .= '<div style="--slider-arrowsNavColor:'.$args['arrowsNavColorAttribute']. ';'. ' --slider-arrowsNavBgcolor:'.$args['arrowsNavBgcolorAttribute']. ';' . ' --slider-arrowsNavHoverBgcolor:'.$args['arrowsNavHoverBgcolorAttribute'] . ';" class="swiper-button-next"></div>';
		}

		// si on a activé la lecture automatique 
		// et pas la navigation par flêches
		// on fait quand même le balisage pour la navigation par flêches 
		// car sinon le clic d'une flêche de navigation
		// sur un simple slider stoppe la lecture automatique de l'autre slider.
		// Le fait d'affficher les flêches de navigation par défaut sur le slider
		// a lecture automatique permet de palier au problème,
		// alors on les masquera ensuite par régles CSS dans le fichier:
		// eccp-slider-swiper.js.
		if($args['withSliderAutoplay'] && !$args['withSliderArrows']) {
			// balisage HTML pour la navigation par flêches
			$block_content .= '<div class="swiper-button-prev"></div>';
			$block_content .= '<div class="swiper-button-next"></div>';
		}

		// si on a activé la navigation par barre de défilement
		if($args['withSliderScrollbar']) {
			// balisage HTML pour la scrollbar
			$block_content .= '<div class="swiper-scrollbar"></div>';
		}
	
		$block_content .= '</div>'; // fin div container swipe

        // Retourner le nouveau balisage HTML
        return $block_content;
		
    }

    // Retourner le contenu inchangé pour les autres blocs
    return $block_content;
}

// si on a activé les scripts JS & CSS de la librairie Swiper
if ($custom_gutenberg_blocks_settings['eccp_settings_enable_script_js_css_swiper_radio_field'] == 'yes') {
	add_filter('render_block', 'eccp_render_slideshow_gallery', 10, 2);
}


/* Transformer le bloc Galerie de WordPress en un album d'images*/

/*
Le hook render_block est utilisé par la fonction eccp_gallery_album() 
pour modifier en Front End le balisage de fin du bloc galerie de 
classe is-style-eccp-gallery-album pour incorporer le code HTML 
d'une balise <div> qui va permettre d'afficher le titre de l'album

En React JS on ajoute dans les paramètres du bloc galerie un Panneau ECCP ALBUM
qui va comporter plusieurs composants pour:
• Activer le style album et affecter la classe: is-style-eccp-gallery-album
• Renseigner l'attribut: dataNameGalleryAlbum par le Nom de l'album
• Définir la couleur & la taille du Nom de l'album
 
Le balisage du bloc galerie simplifié est donc:

	<figure class="is-style-eccp-gallery-album">

		<figure class="wp-block-image size-large" >
			<img  width="1024" height="576" src="http://localhost/wp-chef-ocean/wp-content/uploads/2022/12/rock-that-paris-02-optimise-1024x576.png">
				<figcaption class="wp-element-caption">
					<mark style="color:#e7be49">
						<strong>1ère image</strong>
					</mark>
				</figcaption>
		</figure>



		<figure class="wp-block-image size-large">
			<img width="1024" height="576" src="http://localhost/wp-chef-ocean/wp-content/uploads/2022/12/rock-that-paris-01-optimise-1024x576.png">
				<figcaption class="wp-element-caption">
						<mark style="color:#e7be49">
							<strong>2ème image</strong>
						</mark>
				</figcaption>
		</figure>
		
		.........

		<div class="eccp-name-gallery-album"> 
		 Rock That Paris
		</div>

	</figure>
	
Des régles CSS vont permettre de centrer la balise <div> qui contient
le nom de l'album au centre du bloc galerie,renseigner la taille &
la couleur du nom de l'album et lui appliquer un effet text shadow.
De plus on va masquer toutes les images du bloc galerie exceptée
la première qui servira de couverture pour l'album d'images.

*/

function eccp_gallery_album( $block_content, $block ) {

		// l' attribut withGalleryAlbum 
		// a été définit en React JS pour le bloc Galerie, 
		// il établit que l'on a activé le style album d'images pour le bloc galerie.
		// wp_parse_args permet de fusionner un tableau d'arguments $block['attrs'] 
		// et un tableau de valeurs par défaut
		$args = wp_parse_args(
		
			$block['attrs'],
			[
				'nameGalleryAlbumAttribute' => '',
				'styleAttribute' => 'none',
			]
		);
	

	// si c'est le bloc gallery et que l'on a activé le style album d'images
	if( 'core/gallery' === $block['blockName'] && $args['styleAttribute'] ==='album' ) {
		
		/* Pour debug 
			print_r ($args['nameGalleryAlbumAttribute']);
				echo'<br>';
		*/
		
		// balise HTML de fermeture du bloc galerie
		$original_closing_tag = '</figure>';

		$album_name = $args['nameGalleryAlbumAttribute'];
		
		// nouveau balisage en fermeture du bloc galerie
		// pour notre style album d'images
		$new_closing_tag = '<div class="eccp-name-gallery-album">';
			$new_closing_tag .= esc_html($album_name); 
				$new_closing_tag .= '</div>';
		$new_closing_tag .= $original_closing_tag;
		
		// On remplace dans le contenu du bloc la balise de fermeture originale 
		// par la nouvelle qui contient le Nom de l'album d'images
		$block_content = str_replace( $original_closing_tag, $new_closing_tag, $block_content );
		
	}
	
	return $block_content;
}

add_filter( 'render_block', 'eccp_gallery_album', 10, 2 );



/* Transformer le bloc Groupe de WordPress contenant des blocs bannières en un slider avec la bibliothèque Swiper */

/*
Pour Transformer le bloc Groupe de WordPress en un slider 
utilisant la bibliothèque Swiper on doit: 
• Modifier en Front End le balisage du bloc Groupe pour 
correspondre au balisage HTML  requis par Swiper
• Ajouter des styles CSS personnalisés 
• Initialiser le slider avec des paramètres spécifiques via un script JS
• charger les fichiers js & css de la librairie Swiper via un CDN


On Transforme le bloc Groupe de WordPress en slider en utilisant le hook 
render_block pour modifier le balisage en front end du bloc Groupe 
pour qu'il corresponde au balisage HTML de Swiper.

- Le hook render_block s'applique a la fonction eccp_render_slideshow_cover()
- On exécute les instructions de cette fonction:
• si c'est le bloc Groupe
• si on a activé le style slider dans les paramètres du bloc 
• si les blocs internes correspondent a des blocs cover
- On parcours les blocs internes aux bloc Groupe et on extrait les balisages HTML, 
des blocs cover.

- Dans le container Principal de classe .swiper on ajoute dans le balisage HTML
différents attributs qui sont affectés avec les valeurs des attributs 
du bloc Groupe pour définir:
• le délai pour la lecture automatique
• la largeur du slider
• l'alignement centré
• la navigation par points
• la navigation par flêches
• la navigation par barre de défilement

- Dans le Wrapper de classe .swiper-wrapper on ajoute dans le balisage HTML
des variables CSS:
--slider-wrapperBackgroundColor couleur d'arrière plan du slider
--slider-borderRadius rayon de bordure du slider

- On construit le nouveau balisage en accord avec Swiper en incorporant
des diapositives avec les éléments <div class="swiper-slide"> container
d'un balisage HTML d'un bloc cover. 

- On termine le balisage de Swipe avec:
• la pagination par points: on introduit dans le balisage 
une variable CSS --slider-dotsNavColor pour la couleur 
de la navigation par points
• Navigation par flêches: on introduit dans le balisage 
une variable CSS --slider-arrowsNavColor pour la couleur 
de la navigation par points
• Barre de défilement.


La fonction eccp_enqueue_slider_swipe() ajoute du JavaScript  
via le script:eccp-slider-swiper.js pour initialiser le slider Swiper. 
• Elle définit les paramètres du slider, tels que la direction, 
la pagination, la navigation, les effets de transition, etc.
Récupère les attributs définits lors du balisage HTML du slider pour:
• Appliquer des régles CSS pour la largeur du slider, l'alignement centré ou pas
• Activer la lecture automatique ou pas

La fonction eccp_load_slider_swipe_script() est utilisée pour charger dans le head  
les scripts JavaScript et les fichiers CSS de la bibliothèque Swiper depuis un CDN.

La fonction ecpp_block_style_front_end() 
ajoute des styles CSS personnalisés pour le slider Swiper 
a cette section: Slider Swiper pour le bloc Galerie & bloc Groupe
on utilise notamment les variables globales CSS définit avec la proriété style
dans le balisage du slider pour définir:
• couleur d'arrière plan du slider: --slider-wrapperBackgroundColor 
• rayon de bordure du slider: --slider-borderRadius 
• la couleur des flêches de navigation: --slider-arrowsNavColor
• la couleur de la navigation par points: --slider-dotsNavColor

*/

function eccp_render_slideshow_cover($block_content, $block) {
	
	
	// les attributs withSliderSwipe,sliderWidth, withSliderAlignCenter,
	// withSliderDots,withSliderArrows,withSliderScrollbar,
	// withSliderAutoplay,sliderAutoplayDelay
	// ont été définit en React JS pour le bloc groupe
	// wp_parse_args permet de fusionner un tableau d'arguments $block['attrs'] 
	// et un tableau de valeurs par défaut
 	$args = wp_parse_args(
	
 		$block['attrs'],
 		[
 			'styleAttribute' => 'none',
			'withAlignFull' => false,
			'sliderWidth' => 720,
 			'withSliderAlignCenter' => false,
			'wrapperBackgroundColorAttribute' => 'transparent',
			'sliderStylewithBorderRadius' => false, 
			'sliderBorderRadius' => 4,
			'withSliderDots' => true,
			'DotsNavColorAttribute' => '#FFFFFF',
			'withSliderArrows' => true,
			'arrowsNavColorAttribute' => '#FFFFFF',
			'arrowsNavBgcolorAttribute' => 'transparent',
			'arrowsNavHoverBgcolorAttribute' => 'transparent',
			'withSliderScrollbar' => false,
 			'withSliderAutoplay' => false,
			'sliderAutoplayDelay' => 3500,
 		]
 	);
	
    // si c'est le bloc groupe
	if( 'core/group' === $block['blockName'] 
	// si le style sélectionné aux paramètres du bloc est slider
	&& $args['styleAttribute'] == 'slider'
    // Le bloc groupe contient des blocs internes soient des blocs bannières.
	&& !empty( $inner_blocks = $block[ 'innerBlocks' ]) ) {  
      
		// Initialisation de la variable pour stocker le balisage des slides
		$slide_content = '';
		
		$inner_cover_blocks = false;

		// Parcourir les blocs internes et extraire le balisage HTML des blocs bannières.
		foreach ($inner_blocks as $inner_block) {
			
			// Vérifiez si le bloc interne est de type core/cover
			if ($inner_block['blockName'] === 'core/cover') {
				
				$inner_cover_blocks = true;
				
				// Ajoutez le balisage interne du slider Swiper pour 
				// chaque slide(diapositive) qui sera un bloc cover
				$slide_content .= '<div class="swiper-slide">';
					
					// balisage pour agrandir l'image par geste de pincement 
					// et ou par zoom avant/arrière en appuyant deux fois
					$slide_content .= '<div class="swiper-zoom-container">';
					
						// Récupérez le balisage HTML complet du bloc cover et de ses enfants
						// on n'utilise pas $inner_block['innerHTML'] car on aurait que l'image
						// et pas les blocs ajoutés au bloc cover
						$slide_content .= render_block($inner_block);
						
					$slide_content .= '</div>';
				$slide_content .= '</div>';
				
			}
			
			
		}
		
		// s'il n'y a pas de blocs interne de type cover
		// on ne modifie pas le balisage,on sort
		if (!$inner_cover_blocks){
			return $block_content;
		}
		
		//===== Construire le nouveau balisage pour le slider avec Swiper =======
		
		
		$style='';
		
		/* On récupère le style border-radius pour le bloc Groupe apporté par l'extension */
		if ($args['sliderStylewithBorderRadius']) {
			$style='border-radius:'.$args['sliderBorderRadius'].'px; '; 
		}
		
		// si on a choisi l'alignement pleine largeur
		if($args['withAlignFull']){
			
			// container du slider avec la classe swiper
			// pour	personnaliser le slider via script js
			// on ajoute différents attributs dont slider-autoplay-delay
			// si on a activé la lecture automatique du slider
			// la classe native de WordPress: alignfull pour un alignement pleine largeur
			if($args['withSliderAutoplay']) {
				$block_content = '<div style="' .$style.'" class="swiper alignfull" slider-autoplay-delay="' . esc_attr( $args['sliderAutoplayDelay'] ) .'"'  
				.' slider-with-arrows="' . esc_attr( $args['withSliderArrows'] ) . '">';
			}else{
				$block_content = '<div style="' .$style.'" class="swiper alignfull"' 
				.' slider-width-scrollbar="'. esc_attr( $args['withSliderScrollbar'] ) .'">';
			}
			
		// sinon aucun alignement	
		}else{
			
			// container du slider avec la classe swiper
			// pour	personnaliser le slider via script js
			// on ajoute différents attributs dont slider-autoplay-delay
			// si on a activé la lecture automatique du slider
			if($args['withSliderAutoplay']) {
				$block_content = '<div style="' .$style.'" class="swiper" slider-autoplay-delay="' . esc_attr( $args['sliderAutoplayDelay'] ) .'"'  
				.' slider-width="' . esc_attr( $args['sliderWidth'] ) .'"' 
				.' slider-align-center="' . esc_attr( $args['withSliderAlignCenter'] ) . '"'
				.' slider-with-arrows="' . esc_attr( $args['withSliderArrows'] ) . '">';
			}else{
				$block_content = '<div style="' .$style.'" class="swiper" slider-width="' . esc_attr( $args['sliderWidth'] ) .'"' 
				.' slider-align-center="' . esc_attr( $args['withSliderAlignCenter'] ).'"' .' slider-width-scrollbar="'. esc_attr( $args['withSliderScrollbar'] ) .'">';
			}
		
		}
		
		// Additional required wrapper
		$block_content .= '<div style="--slider-wrapperBackgroundColor:'.$args['wrapperBackgroundColorAttribute'].'; --slider-borderRadius :'.$args['sliderBorderRadius'].';" class="swiper-wrapper">';

			// ajout du balisage pour les slides (diapositives)
			$block_content .= $slide_content;
			
	
		$block_content .= '</div>';// fin div wrapper
		
		// si on a activé la navigation par points
		if($args['withSliderDots']) {
			// balisage HTML pour la navigation par points 
			//en bas du slide
			$block_content .= '<div style="--slider-dotsNavColor:'.$args['DotsNavColorAttribute'].';" class="swiper-pagination"></div>';
		}
		
		// si on a activé la navigation par flêches
		if($args['withSliderArrows']) {
			// balisage HTML pour la navigation par flêches
			$block_content .= '<div style="--slider-arrowsNavColor:'.$args['arrowsNavColorAttribute']. ';'. ' --slider-arrowsNavBgcolor:'.$args['arrowsNavBgcolorAttribute']. ';' . ' --slider-arrowsNavHoverBgcolor:'.$args['arrowsNavHoverBgcolorAttribute'] . ';" class="swiper-button-prev"></div>';
			$block_content .= '<div style="--slider-arrowsNavColor:'.$args['arrowsNavColorAttribute']. ';'. ' --slider-arrowsNavBgcolor:'.$args['arrowsNavBgcolorAttribute']. ';' . ' --slider-arrowsNavHoverBgcolor:'.$args['arrowsNavHoverBgcolorAttribute'] . ';" class="swiper-button-next"></div>';
		}

		// si on a activé la lecture automatique 
		// et pas la navigation par flêches
		// on fait quand même le balisage pour la navigation par flêches 
		// car sinon le clic d'une flêche de navigation
		// sur un simple slider stoppe la lecture automatique de l'autre slider.
		// Le fait d'affficher les flêches de navigation par défaut sur le slider
		// a lecture automatique permet de palier au problème,
		// alors on les masquera ensuite par régles CSS dans le fichier:
		// eccp-slider-swiper.js.
		if($args['withSliderAutoplay'] && !$args['withSliderArrows']) {
			// balisage HTML pour la navigation par flêches
			$block_content .= '<div class="swiper-button-prev"></div>';
			$block_content .= '<div class="swiper-button-next"></div>';
		}

		// si on a activé la navigation par barre de défilement
		if($args['withSliderScrollbar']) {
			// balisage HTML pour la scrollbar
			$block_content .= '<div class="swiper-scrollbar"></div>';
		}
	
		$block_content .= '</div>'; // fin div container swipe

        // Retourner le nouveau balisage HTML
        return $block_content;
		
    }

    // Retourner le contenu inchangé pour les autres blocs
    return $block_content;
}

// si on a activé les scripts JS & CSS de la librairie Swiper
if ($custom_gutenberg_blocks_settings['eccp_settings_enable_script_js_css_swiper_radio_field'] == 'yes') {
	add_filter('render_block', 'eccp_render_slideshow_cover', 10, 2);
}



/* Transformer le bloc Groupe de WordPress en une Fenêtre Modale */

/*

Pour Transformer le bloc Groupe de WordPress en un Popup on doit: 
• Modifier en Front End le balisage du bloc Groupe pour 
  correspondre au balisage HTML requis pour une Fenêtre Modale
• Ajouter des styles CSS personnalisés notamment pour configurer la largeur du Popup
• Initialiser le mode de déclenchement et la fermeture du Popup avec des attributs spécifiques 
  via un script JS: eccp-popup-trigger.js


Lorsqu'on active une fenêtre modale via le style Popup aux paramètre du bloc groupe,
Le hook PHP render_block permet de Transformer le balisage HTML
pour obtenir un Popup:

<div class="eccp-popup-wrapper style="border-radius:10px;box-shadow:3px 3px 7px 0px rgba(0,0,0,0.7)" popup-is-visible" set-cookie="1" popup-cookie-exist="1" popup-trigger="trigger-delay" popup-trigger-delay="4000" popup-cookie-period="2">
	<div class="eccp-popup-inside">
		<div style="--eccp-width-popup:780px" class="wp-block-group eccp-popup-content ">
		</div>
	</div>
</div>

Lors du balisage HTML on renseigne pour le wrapper du bloc groupe des attributs 
qui vont permettre de définir et paramètrer le déclenchement du Popup via le script eccp-popup-trigger.js
• set-cookie: on a activé un cookie
• popup-cookie-exist: présence d'un cookie de suivi
• popup-trigger: Type de déclenchement(no-trigger,trigger-delay,button-clic-trigger)
• popup-trigger-delay: délai en milliseconde pour l'ouverture automatique du Popup 
• popup-cookie-period: durée de vie du cookie en nombre de mois
On renseigne également dans le balisage HTML pour le wrapper du bloc groupe, les styles
border-radius & box-shadow du bloc groupe

Ce script permet de déclencher l'ouverture d'un Popup en ajoutant la classe:popup-is-visible
dans le balisage HTML et selon deux modes:
• Délai d'ouverture automatique
• Déclenchement au clic d'un bouton

Le mode de déclenchement automatique n'est pas activé s'il y a un cookie de suivi 
ayant pour nom: eccp-cookie.
Ce cookie est activé par le script js lors de la 1ère fermeture de la fenêtre modale,
empéchant l'affichage de la fenêtre modale pendant toute la durée de vie du cookie,
définit dans les paramètres du bloc et qui affecte l'attribut: popupCookiePeriod.
*/
function eccp_render_popup( $block_content, $block ) {

		// styleAttribute = 'popup' permet d'activer une fenêtre Modale, 
		// il a été définit en React JS pour le bloc Groupe,
		// l'attribut style natif a Gutenberg permet de récupérer tous les styles du bloc		
		// wp_parse_args permet de fusionner un tableau d'arguments $block['attrs'] 
		// et un tableau de valeurs par défaut
		$args = wp_parse_args(
		
			$block['attrs'],
			[
				'styleAttribute' => 'none',
				'popupTriggerAttribute' => 'no-trigger',
				'popupTriggerDelay' => 3500,
				'withCookie' => false,
				'popupCookiePeriod' => 1,
				'popupStylewithBorderRadius' => false,
				'popupStyleRadius' => 8,
				'popupStylewithBoxShadow' => false,
				'popupStylecolorBoxShadow' => 'rgba(0,0,0,0.2)',
				'popupStylehorizontalBoxShadow' => 0,
				'popupStyleverticalBoxShadow' => 0,
				'popupStyleblurBoxShadow' => 4, 
				'popupStylespreadBoxShadow' => 1,
				'style' => '',
			]
		);
		
	
	// si c'est le bloc Groupe et que l'on a sélectionné le style Popup
	if( 'core/group' === $block['blockName'] &&  $args['styleAttribute'] == 'popup' ) {
		
		
		/* Pour debug 
		echo'déclencheur Popup: ';
		echo ($args['popupTriggerAttribute']).'<br>';
		echo'style:'.'<br>';
		print_r($args['style']).'<br>';
		*/
		
		$style='';
		
		/* On récupère le style border-radius natif de Gutenberg pour le bloc Groupe
     	   et celui apporté par l'extension */
		if ( isset($args['style']['border']['radius']) && $args['style']['border']['radius'] ){
			$style='border-radius:'.$args['style']['border']['radius'].';';
		}elseif ($args['popupStylewithBorderRadius']) {
			$style='border-radius:'.$args['popupStyleRadius'].'px; '; 
		}
		
		/* on récupère le style box-shadow du bloc groupe */
		if ($args['popupStylewithBoxShadow']){
			$style.='box-shadow:'.$args['popupStylehorizontalBoxShadow'].'px '. $args['popupStyleverticalBoxShadow'].'px '. $args['popupStyleblurBoxShadow'].'px '. $args['popupStylespreadBoxShadow'].'px '. $args['popupStylecolorBoxShadow'].';';
		}
		
		
		// si le déclencheur du Popup est un délai d'ouverture automatique
		if($args['popupTriggerAttribute'] == 'trigger-delay') {
			
			// si un cookie ayant pour nom eccp-cookie existe et que l'on a activé un cookie
			if( isset( $_COOKIE['eccp-cookie'] ) && $args['withCookie']  ) {
				$cookie_exist = '1';
			
			// sinon si un cookie ayant pour nom eccp-cookie existe et que l'on a désactivé le cookie
			}elseif( isset( $_COOKIE['eccp-cookie'] ) && !$args['withCookie']  ){
				$cookie_exist = '1';
			}else{
				$cookie_exist = '0';
			}
			
			// Wrapper pour la fenêtre modale
			// on ajoute dans le balisage
			// • Les styles du bloc groupe
			// • L'attribut popup-cookie-exist qui définit si un cookie a été crée
			// • L'attribut popup-trigger qui définit le type de déclenchement
			// • L'attribut popup-trigger-delay qui définit la valeur en milliseconde pour l'ouverture automatique
			$popup_wrapper = '<div style="' .$style.'" class="eccp-popup-wrapper" set-cookie="' .$args['withCookie'].'" popup-cookie-exist="' .$cookie_exist.'" popup-trigger="' . esc_attr( $args['popupTriggerAttribute'] ) .'" popup-trigger-delay="' . esc_attr( $args['popupTriggerDelay'] ) .'" popup-cookie-period="' . esc_attr( $args['popupCookiePeriod'] ) .'"><div class="eccp-popup-inside">';
		  
		// sinon le déclencheur est le clic d'un bouton ou il n'y a pas de déclencheur
		}else{
			
			// Wrapper pour la fenêtre modale
			// on ajoute dans le balisage
			// • Les styles du bloc groupe
			// • L'attribut popup-trigger qui définit le type de déclenchement
			$popup_wrapper = '<div style="' .$style.'" class="eccp-popup-wrapper" popup-trigger="' . esc_attr( $args['popupTriggerAttribute'] ) .'"><div class="eccp-popup-inside">';
		
		}

		$block_content = $popup_wrapper.$block_content.'</div></div>';
		
	}
	
	return $block_content;
}

add_filter('render_block', 'eccp_render_popup', 10, 2);


// Créer un cookie en PHP
// Le temps après lequel le cookie expire est définit par défaut a 30 jours
// 3 paramètres essentiels + 4 paramètres facultatif:
// • Nom du Cookie
// • Valeur du Cookie
// • Expiration du cookie(définit une période en seconde après laquelle le cookie expire)
function eccp_cookie() {
	
	// si le cookie ayant pour nom:cookie-eccp n'existe pas, on le crée
	if( ! isset( $_COOKIE['cookie-eccp'] ) ) {
		echo'toto';
		$time = date("d-m-Y");
		setcookie( 'cookie-eccp', $time, time() + 30 * 60*60*24 );
	}
	
}
//add_action( 'init', 'eccp_cookie' );


/* Transformer le bloc Groupe de WordPress pour afficher une carte Google Maps */

/*
Pour Transformer le bloc Groupe de manière a afficher une carte Google Maps il faut: 
• Modifier en Front End le balisage du bloc Groupe pour 
  correspondre au balisage HTML requis par l'API MAPS EMBED selon la doc:
  https://developers.google.com/maps/documentation/embed/embedding-map?hl=fr
	
	<iframe
		height="400"
		frameborder="0" style="border:0"
		referrerpolicy="no-referrer-when-downgrade"
		src="https://www.google.com/maps/embed/v1/MAP_MODE?key=YOUR_API_KEY&PARAMETERS"
		allowfullscreen>
	</iframe>
	
- la propriété allowfullscreen pour permettre l'affichage de certaines parties 
de la carte en plein écran 
- Propriétés frameborder="0" et style="border:0" permettant de supprimer la bordure 
iFrame standard de la carte.
- La propriété referrerpolicy="no-referrer-when-downgrade" pour permettre au navigateur 
d'envoyer l'URL complète en tant qu'en-tête Referer avec la requête afin que 
les restrictions de clé API puissent fonctionner correctement.
- avec src="https://www.google.com/maps/embed/v1/MAP_MODE?key=YOUR_API_KEY&PARAMETERS" 
on transmet l'URL qui charge l'API Maps Embed:
• MAP_MODE: mode carte
place: affiche un repère sur la carte à un lieu ou une adresse spécifique 
(un point de repère, un établissement, un élément géographique ou une ville, par exemple).
il ya aussi view,directions,streetview,search
• YOUR_API_KEY a remplacer par la clé API MAPS EMBED
• PARAMETERS:
q: Nom de lieu, adresse, L'API Maps Embed accepte à la fois + et %20 
lors de l'échappement des espaces.
ex: 53+Route+De+La+Monteux+50110+Bretteville
zoom:
1 : Le monde
5 : le continent
10 : La ville
15 : Les rues
20 : Les bâtiments
maptype: Définit le type de carte à charger. roadmap (par défaut) ou satellite
center: Définit le centre de la vue plan.Accepte les valeurs de latitude et de longitude 
séparées par une virgule. Exemple : 37.4218,-122.0840.
	
*/

function eccp_render_google_maps( $block_content, $block ) {
	
	// styleAttribute = 'google-maps' permet d'activer l'affichage, 
	// d'une carte Google Maps il a été définit en React JS pour le bloc Groupe,		
	// wp_parse_args permet de fusionner un tableau d'arguments $block['attrs'] 
	// et un tableau de valeurs par défaut
	$args = wp_parse_args(
	
		$block['attrs'],
		[
		 'styleAttribute' => 'none',
		 'googleMapsAddressAttribute' => 'Tour Eiffel,Paris France',
		 'googleMapsZoomAttribute' => '15',
		 'googleMapsHeightAttribute' => '400',
		]
	);
	
	$maps_api_key = '';
	
	//on récupère les paramètres de réglages de l'extension pour personnaliser le Front End
	$custom_front_end_settings = get_option( 'eccp_settings_custom_front_end' );

	// on effecte la clé de l'API d'intégration de Google Maps
	$maps_api_key = $custom_front_end_settings ['eccp_settings_google_maps_embed_api_key_text_field'];
	
	// si c'est le bloc groupe et que l'on a sélectionné le style google-maps
	// et que l'on arenseigné la clé API Google Maps Embed
	if( 'core/group' === $block['blockName'] && $args['styleAttribute'] == 'google-maps' 
		&& !empty($maps_api_key) )	{
			
		$maps_height = $args['googleMapsHeightAttribute'];

        // si l'on a pas renseigné l'adresse, par défaut la carte affichera
		// le lieu de la tour Eiffel
		$address = $args['googleMapsAddressAttribute'];
		
		// On remplace tous les espaces blancs par le signe "+" pour correspondre 
		// au modèle de recherche Google Maps
		$address = str_replace(' ', '+', $address); 
	
		$maps_zoom = $args['googleMapsZoomAttribute'];
			
		// balise HTML de fermeture du bloc Groupe
		$original_closing_tag = '</div>';

		// nouveau balisage en fermeture du bloc Groupe
		// pour intégrer notre carte Google Maps
		// suivant la doc: https://developers.google.com/maps/documentation/embed/embedding-map?hl=fr
		$new_closing_tag = '<iframe
							  height='.$maps_height.'
							  width= 100%
							  frameborder="0" style="border:0"
							  referrerpolicy="no-referrer-when-downgrade"
							  src="https://www.google.com/maps/embed/v1/place?key='.$maps_api_key.'&q='.$address.'&zoom='.$maps_zoom.'"
							  allowfullscreen>
							</iframe>';
							
		$new_closing_tag .= $original_closing_tag;
			
		// On remplace dans le contenu du bloc la balise de fermeture originale 
		// par la nouvelle qui contient le Nom de l'album d'images
		$block_content = str_replace( $original_closing_tag, $new_closing_tag, $block_content );
		
		
	}
	
	return $block_content;
	
}

add_filter('render_block', 'eccp_render_google_maps', 10, 2);


/* Bloc Galerie de WordPress style justifié */

/*
Ce style va permettre de justifier toutes les images entre elles 
en fonction de leur format.		
Pour cela on va modifier les balises <figure> du bloc Galerie pour ajouter
• les dimensions de l'image via la propriété style ="--width:largeur --height:hauteur" 
• une classe selon le format de l'image:
- eccp-landscape pour les formats 3/2 ou 16/9 ou 4/3
- eccp-portrait pour les formats 1/1 ou une largeur < hauteur

On va afficher les images du bloc galerie dans une grille CSS
avec la régle: display:grid
cela va permettre d'étendre sur deux colonnes les images dont le bloc container
<figure> a la classe eccp-landscape par la régle css:grid-column: span 2.
Les images aux format 1/1 ou 4/3 vont s'étendre par défaut sur 1 colonne.		
*/
function eccp_add_justified_gallery_style( $block_content, $block ) {

    // l' attribut styleAttribute 
	// a été définit en React JS pour le bloc Galerie, 
	// il établit que l'on a activé le style justifié pour le bloc galerie.
	// wp_parse_args permet de fusionner un tableau d'arguments $block['attrs'] 
	// et un tableau de valeurs par défaut
    $args = wp_parse_args(
        $block['attrs'],
        [
            'styleAttribute' => 'none',
        ]
    );

    // Si c'est le bloc galerie et que l'on a activé le style justifié
	// et Le bloc galerie contient des blocs images.
    if ( 'core/gallery' === $block['blockName'] && $args['styleAttribute'] === 'justified' && ! empty( $inner_blocks = $block['innerBlocks'] ) ) {

		// valeur par défaut pour la taille des images
		$image_size = 'full';

        if ( array_key_exists( 'sizeSlug', $block['attrs'] ) ) {
            $image_size = $block['attrs']['sizeSlug'];
        }

        $image_ids = array();

        // Parcourir les blocs d'image internes et extraire les ID d'image.
        foreach ( $inner_blocks as $inner_block ) {

            if ( $inner_block['blockName'] != 'core/image' ) {
                // ... on ne fait rien
            } elseif ( ( $image_id = intval( $inner_block['attrs']['id'] ) ) <= 0 ) {
                // ... on ne fait rien
            } else {
                $image_ids[] = $image_id;
            }

        }

        // Parcourir les images du bloc galerie et ajouter la propriété style
		// avec la dimmension de l'image aux balises <figure>
        foreach ( $image_ids as $image_id ) {

            /* On récupère les attributs des images ancienne méthode qui
			   ne donne pas les bonnes dimensions
            $image_src     = wp_get_attachment_image_src( $image_id, $image_size );
            $image_width   = $image_src[1];
            $image_height  = $image_src[2];
			*/
			
			//On récupère les dimensions originales des images via les métadonnées
            $image_metadata = wp_get_attachment_metadata( $image_id );
            
			/* 
			echo'$image_id: '.$image_id.'<br>';
			echo'image_width: '.$image_metadata['width'].'<br>';
			echo'image_height: '.$image_metadata['height'].'<br><br>';
			echo'<pre>';
			print_r($image_metadata['sizes']);
			echo'<pre><br>';
			*/
			
			if ( ! empty( $image_metadata['sizes']['large']['width'] ) && ! empty( $image_metadata['sizes']['large']['height'] ) ) {
				
				$image_width  = $image_metadata['sizes']['large']['width'];
				$image_height = $image_metadata['sizes']['large']['height'];
				
			}else if ( ! empty( $image_metadata['sizes']['medium_large']['width'] ) && ! empty( $image_metadata['sizes']['medium_large']['height'] ) ) {
				
				$image_width  = $image_metadata['sizes']['medium_large']['width'];
				$image_height = $image_metadata['sizes']['medium_large']['height'];

            }else if ( ! empty( $image_metadata['sizes']['medium']['width'] ) && ! empty( $image_metadata['sizes']['medium']['height'] ) ) {
				
				$image_width  = $image_metadata['sizes']['medium']['width'];
				$image_height = $image_metadata['sizes']['medium']['height'];
				
			}else if ( ! empty( $image_metadata['sizes']['thumbnail']['width'] ) && ! empty( $image_metadata['sizes']['thumbnail']['height'] ) ) {
			
				$image_width  = $image_metadata['sizes']['thumbnail']['width'];
				$image_height = $image_metadata['sizes']['thumbnail']['height'];
				
			}else{
				
				return $block_content;
				
			}
			
			// Construire la propriété de style avec les dimensions
			$style_attribute = 'style="--width: ' . $image_width . '; --height: ' . $image_height . ';"';

			// Classes native de la balise figure
            $figure_classes = 'wp-block-image';
			
			// Ajouter les classes eccp-landscape ou eccp-portrait 
			// en fonction des dimensions de l'image
            if ( $image_width > $image_height ) {
                $figure_classes .= ' eccp-landscape';
            } elseif ( $image_width <= $image_height ) {
                $figure_classes .= ' eccp-portrait';
            }

			// Rechercher la balise <figure> contenant l'image avec le bon ID 
			// et ajouter la propriété de style
            // ainsi que les classes eccp-landscape ou eccp-portrait
            $block_content = preg_replace_callback(
                '/<figure[^>]*?\bclass=[\'"][^\'"]*?\bwp-block-image\b[^\'"]*?[\'"][^>]*?>.*?data-id=["\']' . $image_id . '["\'][^>]*?>/',
                function ( $matches ) use ( $style_attribute, $figure_classes ) {
                    return str_replace( '<figure', '<figure class="' . $figure_classes . '" ' . $style_attribute, $matches[0] );
                },
                $block_content
            );
			
			
		}

    }

    return $block_content;
}

add_filter( 'render_block', 'eccp_add_justified_gallery_style', 10, 2 );



/* Bloc Icônes Sociales: transformer Liens Profil en Liens de Partage */

// Comme on a  besoin d'une variable PHP après que l'utilisateur 
// ait effectué l' action de cliquer sur un bouton de partage social
// on va utiliser DOM pour passer la variable PHP à JavaScript
// en concret on utilise un div caché pour afficher notre variable sur la page HTML
// pour la récupérer ensuite par javascript avec le script: eccp-social-link-sharing.js */  
 function eccp_get_featured_image_url(){  
 
	// on réitinialise la boucle de requête WordPress
	// a la boucle de requête principale avant d'utiliser $post
	wp_reset_postdata();
 
    // la variable globale $post va nous permettre
	// d'accèder en dehors de la boucle de requête principale de WordPress
	// a l'id de la publication en cours
	global $post;
	
	// Récupérer l'image à la une pour article ou CPT
	if(is_single()) {
		
		// le deuxième argument est full pour récupèrer la taille d'origine de l'image en avant
		$featured_img_url = get_the_post_thumbnail_url($post->ID, 'full'); 
	
		?>
		<div id="data-featured-image-url" style="display:none;" >
			<?php
				echo $featured_img_url; 
			?>
		</div>
		<?php
		
	}
	
 }
 
add_action( 'wp_head','eccp_get_featured_image_url',100 );


/*========================================================== 
				Visibilité des blocs Gutenberg 
============================================================*/

/*--------- Visibilité des blocs pour les utilisateurs connectés ou déconnectés -----------*/

// Ajouter une classe CSS a la balise body pour 
// les utilisateurs connectés ou déconnectés.
// Ensuite selon la sélection Connecté ou déconnecté aux paramètres du bloc
// on va ajouter en React JS une classe CSS au bloc:
// connecté: is-style-eccp-hide-logged-in
// déconnecté: is-style-eccp-hide-logged-out
// A cette section: VISIBILITÉ BLOC GUTENBERG FRONT END
// on applique des régles CSS afin de masquer
// le bloc selon qu'un utilisateur est connecté ou déconnecté

add_filter('body_class','eccp_logged_in_filter');

function eccp_logged_in_filter($classes) {
	
	if( is_user_logged_in() ) {
		$classes[] = 'eccp-logged-in-condition';
		} else {
		$classes[] = 'eccp-logged-out-condition';
	}
	
	// return $classes array
	return $classes;

}


/*---------  Visibilité des blocs selon le role de l'utilisateur connecté  -----------*/

/*
 • Une requête REST API est initialisé  par le hook rest_api_init 
   et permettra de récupérer tous les rôles utilisateurs retournés
   par la fonction PHP get-all-roles()     
   et selon  la route personnalisé que l'on a définit: 
   editor-custom-color-palette/v1/get-all-roles
   
 • Cette requête: https://mon-site.fr/wp-json/editor-custom-color-palette/v1/get-all-roles
 sera exécutée en React JS et retourne un tableau affecté a l'attribut: allUsersRole
 qui permettra de renseigner la propriété suggestions d'un composant <FormTokenField>.
 Ce composant <FormTokenField> permet de sélectionner les rôles utilisateur pour lesquel 
 on souhaite masquer un bloc.Ces rôles sélectionnés seront affectés 
 a l'attribut de bloc: selectedRoles

• Le hook render_block qui déclenche la fonction eccp_hide_block_based_on_role() 
va permettre d'effacer un bloc en Front End si le role de l'utlisateur connecté 
correspond a un des rôles de l'attribut: selectedRoles
il effacera également le bloc si l'utilisateur est déconnecté.
*/


/*
Fonction permettant d'enregistrer une nouvelle route d’API
Il suffit d’appeler la fonction register_rest_route sur 
le hook rest_api_init et de fournir une fonction de rappel (callback) 
qui aura pour mission de traiter les requêtes sur le nouvel endpoint enregistré.
on transmet deux ou trois paramètres:
- l'espace de noms: editor-custom-color-palette/v1 par convention le nom de notre plugin
suivi de la version de cette API personnalisé.
c'est le préfixe global qui précèdera nos routes placé après:
https://mon-site.fr/wp-json/ 
- le deuxième est une chaîne de caractère indiquant 
la route à enregistrer:  get-all-roles
- le troisième est un tableau d’options qui va nous permettre 
de définir la configuration de notre nouvelle route, avec entre autre :
la méthode HTTP autorisée: 'methods' => 'GET',
la fonction de rappel à exécuter pour envoyer la réponse:
'callback' => 'eccp_get_all_roles'
permission callback: Autorisations pour le point de terminaison: 
vérifie si l'utilisateur peut effectuer l'action:
pour les éditeurs ou supérieurs, mais dans ce cas on doit fournir une nonce de sécurité:
'permission_callback' => function () {
	return current_user_can( 'edit_others_posts' );
}
si on veut rendre la route publique:
'permission_callback' => '__return_true'

La route est https://mon-site.fr/wp-json/editor-custom-color-palette/v1/get-all-roles
La valeur de retour est convertie en JSON et renvoyée au client
*/
add_action('rest_api_init', function() {
	
    register_rest_route('editor-custom-color-palette/v1', '/get-all-roles', array(
        'methods' => 'GET',
        'callback' => 'eccp_get_all_roles',
		'permission_callback' => '__return_true'
    ));
	
});

/*
Fonction permettant de récupérer tous les rôles utilisateurs

structure $all_roles:

array (
     'rolename' => array (
         'name' => 'rolename',
         'capabilities' => array()
     )
)


valeurs retournées par $role_names:

Array
(
    [0] => administrator
    [1] => editor
    [2] => author
    [3] => contributor
    [4] => subscriber
    [5] => customer
    [6] => shop_manager
    [7] => wpseo_manager
    [8] => wpseo_editor
)

*/
function eccp_get_all_roles() {
    
	$all_roles = wp_roles()->roles;
	
	$role_names = array();

    foreach ($all_roles as $role => $details) {
        $role_names[] = $role;
    }
	
	// gestion des erreurs
	if ( empty( $role_names ) ) {
		return new WP_Error( 'no_users', 'Empty users role', array( 'status' => 404 ) );
	}

	// Si la validation est bonne et que vous souhaitez par contre 
	// envoyer un statut HTTP autre que 200, 
	// la réponse à renvoyer doit être un objet WP_REST_Response 
	// instancié avec la valeur du statut en 2ème paramètre :
    //return new WP_REST_Response($role_names, 201);
	
	return $role_names;
	
}


// Masquer un bloc en Front End en fonction du rôle de l'utilisateur connecté
function eccp_hide_block_based_on_role($block_content, $block) {
    
	// Vérifier dans le bloc si les attributs accountAttribute & selectedRoles ne sont pas  vide. 
	// selectedRoles est l'Attribut pour stocker les rôles sélectionnés
    // aux paramètres du bloc et qui définit la visibilité du bloc
    if ( !empty($block['attrs']['accountAttribute']) && !empty($block['attrs']['selectedRoles'] )  ) {
	
		if ($block['attrs']['accountAttribute'] =='users-role') {	
			
			// Vérifier si l'utilisateur est connecté
			if (is_user_logged_in()) {
				
				// Récupérer le rôle de l'utilisateur connecté
				$user = wp_get_current_user();
				$userRoleLogged = $user->roles[0];

				// rôles utilisateur non autorisés a visionner ce bloc
				$roleNotAllowed = $block['attrs']['selectedRoles'];
				
				/* Pour Debug 
				echo'<pre>';
				echo'Rôle utilisateur connecté: '.$userRoleLogged.'<br>';
				echo'Nom des rôles Utilisateur non Autorisés: '.'<br>';
				print_r($roleNotAllowed);
				echo'</pre>';
				*/

				// Vérifier si le rôle de l'utilisateur connecté n'est pas autorisé
				if (in_array($userRoleLogged, $roleNotAllowed)) {
					// Retourner une chaîne vide pour effacer le bloc
					return '';
				}
			//Sinon l'utilisateur n'est pas connecté	
			} else {
				// Retourner une chaîne vide pour effacer le bloc
				return '';
			}
			
		}
	
	}

    return $block_content;
	
}

// Appliquer le filtre sur le contenu du bloc lorsqu'il est rendu en Front End
add_filter('render_block', 'eccp_hide_block_based_on_role', 10, 2);




/*---------  Visibilité des blocs selon le nom affiché publiquement pour l'utilisateur connecté  -----------*/

/*
 • Une requête REST API est initialisé  par le hook rest_api_init 
   et permettra de récupérer les noms affichés publiquement
   pour tous les comptes utilisateurs et retournés 
   par la fonction PHP eccp_get_all_user_account_display_name()     
   et selon  la route personnalisé que l'on a définit: 
   editor-custom-color-palette/v1/get-all-user-account-display-name
   
 • Cette requête: https://mon-site.fr/wp-json/editor-custom-color-palette/v1/get-all-user-account-display-name
 sera exécutée en React JS et retourne un tableau affecté a l'attribut: allUsersAccountName
 qui permettra de renseigner la propriété suggestions d'un composant <FormTokenField>.
 Ce composant <FormTokenField> permet de sélectionner les noms des comptes utilisateur pour lesquels 
 on souhaite Afficher ou Masquer un bloc selon la valeur booléenne de l'attribut: 
 hideSelectedNameAccount d'un composant <toogle>.
 Ces noms des comptes utilisateurs sélectionnés seront affectés a l'attribut de bloc: 
 selectedNameAccount

• Le hook render_block qui déclenche la fonction eccp_hide_block_based_on_name_account() 
va permettre d'effacer un bloc en Front End s'il ne vérifie pas aux conditions de visibilité
sélectionné aux paramètres du bloc et retourné par les attributs: selectedNameAccount &
hideSelectedNameAccount 
il effacera également le bloc si l'utilisateur est déconnecté.
*/

// On définit La route pour la requête REST API et la fonction permettant de récupérer 
// les noms affichés publiquement pour tous les comptes utilisateur:
// https://mon-site.fr/wp-json/editor-custom-color-palette/v1/get-all-user-account-display-name
// La valeur de retour est convertie en JSON et renvoyée au client
function eccp_rest_api_init_get_all_user_account_display_name() {
	
	register_rest_route('editor-custom-color-palette/v1', '/get-all-user-account-display-name', array(
        'methods' => 'GET',
        'callback' => 'eccp_get_all_user_account_display_name',
		'permission_callback' => '__return_true'
    ));
	
}
add_action('rest_api_init', 'eccp_rest_api_init_get_all_user_account_display_name');



/* 
Fonction pour récupérer tous les noms affichés publiquement
des comptes utilisateurs
*/
function eccp_get_all_user_account_display_name() {
	
	// on récupère un tableau indexé numériquement
    $user_account_display_name = get_users(array(
        'fields' => 'display_name', 
    ));
	
	// gestion des erreurs
	if ( empty( $user_account_display_name ) ) {
		return new WP_Error( 'no_users_display_name', 'Empty users account display name', array( 'status' => 404 ) );
	}
	
	return $user_account_display_name;

}


// Rendre un bloc Visible ou Masquer en Front End en fonction 
// du nom affiché publiquement pour le compte de l'utilisateur connecté
function eccp_hide_block_based_on_name_account($block_content, $block) {
	
	// l' attribut hideSelectedNameAccount de type booléen
	// définit par défaut a false en React JS
	// renvoi NULL en PHP avec dans ce cas une erreur: index indéfini
	// wp_parse_args va permettre de fusionner un tableau d'arguments $block['attrs'] 
	// et un tableau de valeurs par défaut
	$args = wp_parse_args(
	
		$block['attrs'],
		[
			'hideSelectedNameAccount' => false,
		]
	);
    
	// Vérifier dans le bloc si les attributs accountAttribute & selectedNameAccount sont définit. 
	// selectedNameAccount est l'Attribut pour stocker les Noms des comptes utilisateurs 
    // aux paramètres du bloc et qui définit la visibilité du bloc
    if ( !empty($block['attrs']['accountAttribute']) && 
	     !empty($block['attrs']['selectedNameAccount'] ) ) {
		
		if ($block['attrs']['accountAttribute'] =='account-name') {	
			
			// Vérifier si l'utilisateur est connecté
			if (is_user_logged_in()) {
				
				// Récupérer le rôle de l'utilisateur connecté
				$user = wp_get_current_user();
				$userNameLogged = $user->data->display_name;

				// comptes utilisateur sélectionnés aux paramètres du bloc
				// pour être visible ou masqué selon l'attribut:hideSelectedNameAccount
				$selectedNameAccount = $block['attrs']['selectedNameAccount'];
				
				// masquer le bloc pour les comptes utilisateurs sélectionnés
				// aux paramètres du bloc
				$hideSelectedNameAccount = $args['hideSelectedNameAccount'];
				
				/* Pour Debug 
				echo'<pre>';
				echo'Nom utilisateur connecté: '.$userNameLogged.'<br>';
				echo'Nom Compte Utilisateur Sélectionné: '.'<br>';
				print_r($selectedNameAccount);
				echo'Masquer les comptes sélectionnés: '.$hideSelectedNameAccount.'<br>';
				echo'</pre>';
				*/
				
				// Si on a choisi de masquer les blocs
				// sélectionnés aux paramètres du bloc
				if ($hideSelectedNameAccount){
					
					// Vérifier si le compte utilisateur connecté
					// fait partie des comptes sélectionnés pour être masqué
					if (in_array($userNameLogged, $selectedNameAccount)) {
					
					// Retourner une chaîne vide pour effacer le bloc
					return '';
					
					}else{
						return $block_content;
					}
					
				// Sinon on choisi d'afficher les blocs
				// sélectionnés aux paramètres du bloc		
				}else{
					
					// Vérifier si le compte utilisateur connecté
					// fait partie des comptes sélectionnés pour être afficher
					if (in_array($userNameLogged, $selectedNameAccount)) {
					
						return $block_content;
					
					}else{
						// Retourner une chaîne vide pour effacer le bloc
						return '';
					}
					
				}
				
			//Sinon l'utilisateur n'est pas connecté	
			} else {
				// Retourner une chaîne vide pour effacer le bloc
				return '';
			}
			
		}
	
	}

    return $block_content;
	
}

// Appliquer le filtre sur le contenu du bloc lorsqu'il est rendu en Front End
add_filter('render_block', 'eccp_hide_block_based_on_name_account', 10, 2);





/* AJOUT EN FRONT END DU BOUTON CLICK TO TWEET POUR LE STYLE TWEET DU BLOC PARAGRAPHE */

function eccp_tweet_button( $block_content, $block ) {
	
	// si c'est le bloc paragraphe avec une classe is-style-eccp-tweet
	if( 'core/paragraph' === $block['blockName'] && !empty( $block['attrs']['className'] ) && 'is-style-eccp-tweet' === $block['attrs']['className'] ) {

		// on récupère le contenu du bloc paragraphe
		// explode scinde le contenu délimité par le séparateur:<p>
		// en sous chaine retourné dans un tableau
		$content = explode( '<p>', $block_content );
		
		// on récupère le texte du bloc paragraphe de style ECCP Tweet
		// wp_strip_all_tags permet de supprimer toutes les balise HTML du contenu
		$text = rawurlencode( wp_strip_all_tags( $content[0]) );
		
		//rawurlencode: fonction qui évite que les caractères spéciaux soient interprétés 
		//comme des délimiteurs, en les remplaçant par %xy avec x & y deux chiffres héxadécimaux		
		//et permet aussi de protéger les URL lors du transfert 
		$url_post = rawurlencode(get_permalink());
		
		$url_twiter = 'https://twitter.com/intent/tweet?url='. $url_post .'&text=' . $text;
		
		// on récupère le lien Twitter renseigné dans les paramètres de l'extension Yoast SEO
		$seo_data = get_option( 'wpseo_social' );
		
		if( !empty( $seo_data['twitter_site'] ) ){
			$url_twiter .= '&via=' . esc_attr( $seo_data['twitter_site'] );
		}
		
		// balise HTML de fermeture du bloc paragraphe
		$original_closing_tag = '</p>';
		
		// nouvelle balise de fermeture du bloc paragraphe 
		// on incorpore le bouton Click to Tweet 
		// il a pour style la classe d'un bouton par défaut de Gutenberg: is-style-default
		// et on ajoute notre classe:eccp-tweet-button
		// avec la pseudo régle ::after on icorpore par régle CSS
		// le nouveau logo x de twitter au format SVG en remplcement de l'icône Dashicons	
		$new_closing_tag = '<span style="display:block; margin-top:0.5em; margin-bottom:2.2em;">';
		$new_closing_tag .= '<a class="is-style-default eccp-tweet-button" href="' . esc_url_raw( $url_twiter ) . '" target="_blank" rel="noopener noreferer">';
		//$new_closing_tag.= 'Click to Tweet <span class="dashicons dashicons-twitter"></span></a>';
		$new_closing_tag.= 'Click to Tweet </a>';
		//$new_closing_tag .= '</span>';
		$new_closing_tag.= $original_closing_tag;
		
		
		// on remplace dans le contenu du bloc la balise de fermeture originale 
		// par la nouvelle qui contient le bouton Click to Tweet
		$block_content = str_replace( $original_closing_tag, $new_closing_tag, $block_content );
		
	}
	
	return $block_content;
}

add_filter( 'render_block', 'eccp_tweet_button', 10, 2 );


/*------------  ANIMATION DES BLOCS GUTENBERG AVEC LA LIBRAIRIE AOS ------------*/

/*

On utilise la librairie AOS qui necessite deux fichiers
pour céer des animations en front End:
- asset/aos.css
- asset/js/aos.js
De plus il faut initialiser la librairie AOS cela se fait avec le script
- asset/js/eccp-aos-init.js
Source Librairie AOS: https://github.com/michalsnik/aos/tree/v2#-animations

Pour que l'animation soit effective en back office j'ai établi le fichier
asset/css/aos-admin.css qui est une modification du fichier aos.css 
ou j'ai ajouté des keyframes.
Ce fichier est chargé dans l'editeur Gutenberg via le hook enqueue_block_editor_assets

Pour utiliser cette librairie il suffit d'ajouter un attribut data-aos à l'élément html,
comme ceci :
data-aos="fade-zoom-in">
puis d'autres attributs HTML qui seront les options de réglages par ex:
'data-aos-delay': 0,
'data-aos-duration': 1500,
'data-aos-once': true,
'data-aos-mirror': false,
'data-aos-easing': 'ease',
'data-aos-anchor-placement': 'top-bottom',
'data-aos-offset': 120,

Ces attributs data-aos ont déja été ajouté dans le HTML du bloc en back office
et ont pour valeur les attributs de blocs définit en ReactJs respectivement:
animationAttribute
delayAttribute
durationAttribute
onceAttribute
mirrorAttribute
easingAttribute
anchorPlacementAttribute
offsetAttribute


• Le hook render_block qui déclenche la fonction eccp_animate_block() 
va permettre d'ajouter les attributs d'animation data-aos à l'élément HTML 
racine des blocs

Ce code est largement inspiré de l'extension: 
https://fr.wordpress.org/plugins/animations-for-blocks/

avec pour la fonction hooké sur render_block:
https://github.com/websevendev/animations-for-blocks/blob/main/animations-for-blocks.php#L32-L35


*/

/**
 * Retourne les blocs connus pour ne pas fonctionner correctement 
 * avec les animations pour les blocs.
 *
 * @return array
 */
function eccp_get_unsupported_blocks() {
	return [
		'core/freeform',
		'core/html',
		'core/shortcode',
		'core/legacy-widget',
	];
}


/**
 * Déterminez si le bloc est pris en charge pour avoir une animation.
 *
 * @param string $block_name
 * @return boolean
 */
function eccp_is_supported($block_name) {

	static $not_supported;
	
	if(!is_array($not_supported)) {
		$not_supported = eccp_get_unsupported_blocks();
	}

	return !in_array($block_name, $not_supported, true);
}


/** Cette fonction retourne les attributs d'animation data-aos
 *  avec leurs valeurs pour être ajoutés à la balise HTML racine du bloc
 *
 * @param array $args valeurs des attributs d'animation.
 * @return array $attributes à ajouter à l'élément racine.
 */
function eccp_get_animation_attributes($args = []) {

	$args = wp_parse_args($args, [
		'animationAttribute' => 'none',
		'delayAttribute' => 0,
		'durationAttribute' => 400,
		'onceAttribute' => false,
		'mirrorAttribute' => false,
		'easingAttribute' => 'ease',
		'offsetAttribute' => 120,
		'anchorPlacementAttribute' => 'top-bottom',
	]);

	$attributes = [];

	if(empty($args['animationAttribute']) || $args['animationAttribute'] === 'none') {
		return $attributes;
	}

	/** Animation. */
	$attributes['data-aos'] = $args['animationAttribute'];

	/** Delay. */
	if(is_numeric($args['delayAttribute']) ) {
		$attributes['data-aos-delay'] = (int)$args['delayAttribute'];
	}

	/** Duration. */
	if(is_numeric($args['durationAttribute']) ) {
		$attributes['data-aos-duration'] = (int)$args['durationAttribute'];
	}

	/** Easing. */
	if(!empty($args['easingAttribute']) ) {
		$attributes['data-aos-easing'] = $args['easingAttribute'];
	}

	/** Once. */
	if($args['onceAttribute'] === 'true' || $args['onceAttribute'] === true) {
		$attributes['data-aos-once'] = 'true';
	}

	/** Mirror. */
	if($args['mirrorAttribute'] === 'true' || $args['mirrorAttribute'] === true) {
		$attributes['data-aos-mirror'] = 'true';
	}

	/** Offset. */
	if(is_numeric($args['offsetAttribute']) ) {
		$attributes['data-aos-offset'] = (int)$args['offsetAttribute'];
	}

	/** Anchor placement. */
	if(!empty($args['anchorPlacementAttribute']) ) {
		$attributes['data-aos-anchor-placement'] = $args['anchorPlacementAttribute'];
	}

	return $attributes;
}


/**
 * Ajoutez des attributs d'animation à l'élément racine.
 *
 * @param string $html Block HTML.
 * @param array $args attribut d'animation du bloc.
 * @return Bloc HTML avec les attributs d'animation.
 */
 
/*
On utilise la classe WP_HTML_Tag_Processor faisant partie de l'API HTML
utilisée pour modifier les attributs d'un document HTML 
pour les balises correspondant à une requête.

L'utilisation de cette classe nécessite trois étapes :

• Créez une nouvelle instance de classe 
en passant le code HTML que nous souhaitons modifier: $html
• avec next_tag() on accéde a la première balise HTML racine du bloc 
si cette balise racine du bloc posséde déjà l'attribut 
data-aos qui définit le type d'animation on sort
sinon on ajoute les attributs d'animation 
• On retourne le HTML du bloc mis à jour 

*/
function eccp_add_animation_attributes($html, $args) {

	$tags = new WP_HTML_Tag_Processor($html);

	if($tags->next_tag()) {

		/** Possède déjà des attributs d'animation.*/ 
		if($tags->get_attribute('data-aos')) {
			return $html;
		}

		/** Ajoutez des attributs d'animation. 
		    sous la forme [data-aos] = slide-right
			[data-aos-duration] = 500 ....
			dans la balise conteneur du bloc*/
		foreach(eccp_get_animation_attributes($args) as $key => $value) {
			$tags->set_attribute($key, $value);
		}

		return $tags->get_updated_html();
	}

	return $html;
}


/**
 * Ajouter des attributs d'animation à l'élément HTML racine des blocs, .
 *
 * @param string $block_content Rendered block.
 * 
 * @return string
 */
function eccp_animate_block($block_content, $block) {
	
	// wp_parse_args va permettre de fusionner un tableau d'arguments $block['attrs'] 
	// et un tableau de valeurs par défaut
	$args = wp_parse_args(
		
			$block['attrs'],
			[
				'animationAttribute' => 'none',
				'delayAttribute' => 0,
				'durationAttribute' => 400,
				'onceAttribute' => false,
				'mirrorAttribute' => false,
				'easingAttribute' => 'ease',
				'offsetAttribute' => 120,
				'anchorPlacementAttribute' => 'top-bottom',
			]
	);
	
	// Si le bloc supporte les animations et si l'on a définit une animation
	// alors on affecte au tableau $attributes[] les attributs
	// a passer a la fonction eccp_add_animation_attributes() qui va 
	// ajouter les attributs d'animation dans la balise HTML conteneur du bloc
	if( eccp_is_supported($block['blockName']) && !empty($args['animationAttribute']) && $args['animationAttribute'] !== 'none' ) {

		/** Animation. */
		$attributes['animationAttribute'] = $args['animationAttribute'];

		/** Delay. */
		if(is_numeric($args['delayAttribute']) && (int)$args['delayAttribute'] !== 0) {
			$attributes['delayAttribute'] = (int)$args['delayAttribute'];
		}

		/** Duration. */
		if(is_numeric($args['durationAttribute']) && (int)$args['durationAttribute'] !== 400) {
			$attributes['durationAttribute'] = (int)$args['durationAttribute'];
		}

		/** Easing. */
		if(!empty($args['easingAttribute']) && $args['easingAttribute'] !== 'ease') {
			$attributes['easingAttribute'] = $args['easingAttribute'];
		}

		/** Once. */
		if($args['onceAttribute'] === 'true' || $args['onceAttribute'] === true) {
			$attributes['onceAttribute'] = 'true';
		}

		/** Mirror. */
		if($args['mirrorAttribute'] === 'true' || $args['mirrorAttribute'] === true) {
			$attributes['mirrorAttribute'] = 'true';
		}

		/** Offset. */
		if(is_numeric($args['offsetAttribute']) && (int)$args['offsetAttribute'] !== 120) {
			$attributes['offsetAttribute'] = (int)$args['offsetAttribute'];
		}

		/** Anchor placement. */
		if(!empty($args['anchorPlacementAttribute']) && $args['anchorPlacementAttribute'] !== 'top-bottom') {
			$attributes['anchorPlacementAttribute'] = $args['anchorPlacementAttribute'];
		}
		
		return eccp_add_animation_attributes($block_content, $attributes);
	}

	return $block_content;
}
add_filter('render_block','eccp_animate_block', 10, 2);
