# Egyedi mező, ellenőrzés és űrlapattribútum

> Egyedi mező felvétele a pénztárra, saját ellenőrzés a mezőkhöz, az ellenőrzés indítójának módosítása és egyedi űrlapattribútumok.

Ez a fejezet azt mutatja meg, hogyan vehetsz fel saját mezőt a pénztárra, hogyan ellenőriztetheted a mezők értékét saját szabállyal, és hogyan adhatsz egyedi attribútumot az űrlaphoz. A kódrészleteket a téma (vagy gyermektéma) `functions.php` fájljába, egy kódrészlet-kezelő bővítménybe vagy a **CheckoutWC → Haladó → Szkriptek** fül **PHP kódrészletek** mezőjébe írhatod. A mezőbe írt kódnál ne szerepeljen a nyitó `<?php` címke.

![A Szkriptek fül PHP kódrészletek mezője](./kepek/fejlesztoknek-php-kodreszletek.webp)

*A Szkriptek fül PHP kódrészletek mezője* (https://minta-bolt.hu/wp-admin/admin.php?page=cfw-settings-cfw_manage_advanced&subpage=scripts)

A képen a **Globális** szakasz harmadik mezője, a **PHP kódrészletek** az, ahová a kódrészleteket beillesztheted.

## Egyedi mező felvétele

Egyedi mezőt többféleképp vehetsz fel.

### 1. lehetőség: WooCommerce Checkout Field Editor

A WooCommerce Checkout Field Editor a hivatalos mezőszerkesztő bővítmény. A CheckoutWC mellett alapból csak a **Kiegészítő mezők** (Additional Fields) fül érhető el benne. Vedd fel a mezőidet, és mentsd el.

Ha a számlázási vagy szállítási címmezőket is módosítani akarod a mezőszerkesztővel (a legtöbb webshopnak erre nincs szüksége, és nem is érdemes):

1. Menj ide: **CheckoutWC → Integrációk**, és jelöld be a mezőszerkesztő címmező-felülírását engedélyező jelölőnégyzetet.
2. Módosítsd a címmezőket a mezőszerkesztő bővítmény saját oldalán (a WooCommerce menüben található).
3. Ha új mezőt veszel fel a számlázási címhez, ugyanazt a mezőt vedd fel a szállítási címhez is, hogy az értéke akkor is mentődjön a számlázási címbe, ha a vásárló a „Megegyezik a szállítási címmel” lehetőséget választja.

Hogy a mezők megfelelően működjenek:

- A mezők neve `shipping_` vagy `billing_` előtaggal kezdődjön, például `billing_fax`.
- Az összehangolandó mezőknek azonos legyen a nevük az előtagot leszámítva: ha felveszed a `shipping_fax` mezőt, a számlázási mező neve `billing_fax` legyen.

### 2. lehetőség: ThemeHigh Checkout Field Editor

A ThemeHigh bővítményének van ingyenes és Pro változata. A mezők elrendezéséhez előbb állítsd a kívánt sorrendbe a mezőket, majd adj mindegyikhez egy CSS-osztályt, amely a szélességet adja meg:

| Osztály | Szélesség |
| --- | --- |
| `form-row-wide` | 100% |
| `form-row-first` | 50% |
| `form-row-last` | 50% |
| `col-lg-3` | 3/12 (25%) |
| `col-lg-4` | 4/12 (33%) |
| `col-lg-6` | 6/12 (50%) |
| `col-lg-8` | 8/12 (66%) |
| `col-lg-9` | 9/12 (75%) |

Sokan a Pro változatot választják, mert az feltételes mezőket is tud. A hivatalos mezőszerkesztőhöz hasonlóan itt is engedélyezned kell a címmezők módosítását a **CheckoutWC → Integrációk** oldalon.

A ThemeHigh alapból bekapcsolja a select2 (selectWoo) kezelőt a legördülő mezőkön. Ha ezt egy mezőnél nem akarod, add a mezőhöz a `cfw-no-select2` osztályt.

### 3. lehetőség: saját kód a functions.php fájlban

Egy egyedi mezőhöz általában négy dolog kell: a mező kirajzolása egy horogra kötve, a kitöltöttség ellenőrzése, az érték elmentése a rendeléshez, és az érték kiírása a rendelés szerkesztő oldalán. A horog helyét a [Akciókampók listája](https://hub.hellowp.io/hu/plugins/checkout-for-woocommerce/fejlesztoknek-akciok/) fejezetben választhatod ki.

Kötelező jelölőnégyzet a feltételek után:

```php
// A mező kirajzolása a pénztáron
add_action( 'woocommerce_checkout_after_terms_and_conditions', 'example_required_checkbox' );

function example_required_checkbox() {
	woocommerce_form_field(
		'required_checkbox',
		array(
			'type'     => 'checkbox',
			'value'    => 'Yes',
			'required' => true,
			'label'    => __( 'Ez egy kötelező jelölőnégyzet.' ),
			'columns'  => 12,
		),
		WC()->checkout()->get_value( 'required_checkbox' )
	);
}

// Ellenőrzés: hiba, ha nincs bejelölve
add_action( 'woocommerce_after_checkout_validation', 'example_validate_required_checkbox_field', 10, 2 );

function example_validate_required_checkbox_field( &$data, &$errors ) {
	if ( ! isset( $_POST['required_checkbox'] ) ) {
		$errors->add( 'terms', 'Be kell jelölnöd a kötelező jelölőnégyzetet!' );
	}
}

// Az érték mentése a rendeléshez
add_action( 'woocommerce_checkout_update_order_meta', 'example_required_checkbox_checkout_field_update_order_meta' );

function example_required_checkbox_checkout_field_update_order_meta( $order_id ) {
	if ( ! empty( $_POST['required_checkbox'] ) ) {
		update_post_meta( $order_id, 'required_checkbox', sanitize_text_field( $_POST['required_checkbox'] ) );
	}
}

// Az érték megjelenítése a rendelés szerkesztő oldalán
add_action( 'woocommerce_admin_order_data_after_billing_address', 'example_required_checkbox_display_admin_order_meta', 10, 1 );

function example_required_checkbox_display_admin_order_meta( $order ) {
	$value = get_post_meta( $order->get_id(), 'required_checkbox', true );

	if ( '1' === $value ) {
		$value = 'Igen';
	} else {
		$value = 'Nem';
	}

	echo '<p><strong>' . __( 'Kötelező jelölőnégyzet' ) . ':</strong> <br/>' . $value . '</p>';
}
```

Aláírást kérő jelölőnégyzet a megjegyzések mező után (ez nem kötelező mező):

```php
add_action( 'woocommerce_after_order_notes', 'signature_required_checkout_field' );

function signature_required_checkout_field( $checkout ) {
	woocommerce_form_field(
		'signature_required',
		array(
			'type'  => 'checkbox',
			'class' => array( 'my-field-class form-row-wide' ),
			'value' => 'Yes',
			'label' => __( 'Aláírás szükséges' ),
		),
		$checkout->get_value( 'signature_required' )
	);
}

add_action( 'woocommerce_checkout_update_order_meta', 'signature_required_checkout_field_update_order_meta' );

function signature_required_checkout_field_update_order_meta( $order_id ) {
	if ( ! empty( $_POST['signature_required'] ) ) {
		update_post_meta( $order_id, 'signature_required', sanitize_text_field( $_POST['signature_required'] ) );
	}
}

add_action( 'woocommerce_admin_order_data_after_billing_address', 'signature_required_display_admin_order_meta', 10, 1 );

function signature_required_display_admin_order_meta( $order ) {
	$value = get_post_meta( $order->get_id(), 'signature_required', true );

	echo '<p><strong>' . __( 'Aláírás szükséges' ) . ':</strong> <br/>' . ( '1' === $value ? 'Igen' : 'Nem' ) . '</p>';
}
```

Üdvözlőkártya szövegmező a CheckoutWC saját horgára kötve, a fizetési mód feltételeinek jelölőnégyzete előtt:

```php
add_action( 'cfw_checkout_before_payment_method_terms_checkbox', 'customise_checkout_field' );

function customise_checkout_field() {
	woocommerce_form_field(
		'greeting_card',
		array(
			'type'        => 'textarea',
			'label'       => 'Üdvözlőkártya',
			'placeholder' => 'Üdvözlőkártya',
			'required'    => false,
			'class'       => array(),
			'autofocus'   => false,
			'priority'    => 10,
			'columns'     => 12,
		),
		WC()->checkout->get_value( 'greeting_card' )
	);
}

add_action( 'woocommerce_checkout_update_order_meta', 'customise_checkout_field_update_order_meta' );

function customise_checkout_field_update_order_meta( $order_id ) {
	if ( ! empty( $_POST['greeting_card'] ) ) {
		update_post_meta( $order_id, 'greeting_card', sanitize_text_field( $_POST['greeting_card'] ) );
	}
}

add_action( 'woocommerce_admin_order_data_after_billing_address', 'greeting_card_checkout_field_display_admin_order_meta', 10, 1 );

function greeting_card_checkout_field_display_admin_order_meta( $order ) {
	echo '<p><strong>' . __( 'Üdvözlőkártya' ) . ':</strong> <br/>' . get_post_meta( $order->get_id(), 'greeting_card', true ) . '</p>';
}
```

### 4. lehetőség: Checkout Add-ons

A WooCommerce Checkout Add-ons bővítmény is használható egyedi mezőkhöz. Akkor működik a legjobban, ha a választható opciókért felárat kérsz. Ingyenesen is használható, de ilyenkor minden mező 0 Ft-os sorként megjelenik az összesítésben. A bővítményhez külön licenc kell, a mezőket a saját felületén veheted fel.

### 5. lehetőség: más bővítmények

Más bővítmények is működnek a CheckoutWC-vel. A Cashier bővítményhez részleges támogatás van.

## Saját ellenőrzés a mezőkhöz

A CheckoutWC a mezők ellenőrzéséhez a Parsley JavaScript-könyvtárat használja. A Parsley egyedi ellenőrzői (validator) segítségével a hagyományosnál jóval összetettebb szabályt is megadhatsz egy mezőre. Két részből áll a megoldás: az ellenőrzőből és a mezőből.

1. **Az ellenőrző.** A Parsley saját leírása szerint írd meg a JavaScript-ellenőrzőt, majd add hozzá az oldalhoz: **CheckoutWC → Haladó → Szkriptek → Globális → Fejléc szkriptek**. A szkriptet `<script>` címkébe kell csomagolni.
2. **A mező.** Az ellenőrzőt a mezőhöz egy PHP-kódrészlettel köted. A példában a `multiple-of` nevű ellenőrző a keresztnév mezőn 3-as értékkel fut:

```php
add_filter( 'woocommerce_default_address_fields', function( $fields ) {
	$fields['first_name']['custom_attributes']['data-parsley-multiple-of'] = '3';

	return $fields;
}, 100100 );
```

Ha mindkettő a helyén van, az ellenőrző a pénztáron a megadott szabály szerint fut, és hibásan kitöltött mezőnél nem enged továbblépni.

## Az ellenőrzés indítójának módosítása

A számlázási e-mail-cím mezőt alapból gépelés közben (keyup) ellenőrzi a pénztár. Ha azt szeretnéd, hogy csak akkor ellenőrizze, amikor a vásárló végzett a mezővel és kilép belőle, állítsd a mező `data-parsley-trigger` attribútumát `focusout` értékre:

```php
add_filter(
	'woocommerce_checkout_fields',
	function( $fields ) {
		// A számlázási e-mail ellenőrzése a mezőből való kilépéskor
		$fields['billing']['billing_email']['custom_attributes']['data-parsley-trigger'] = 'focusout';

		return $fields;
	},
	2000
);
```

Más mezőnél ugyanígy járj el, csak a mezőcsoportot (`billing`) és a mező kulcsát (`billing_email`) cseréld ki.

## Egyedi űrlapattribútum

A `cfw_form_attributes` szűrővel saját attribútumot adhatsz a pénztár űrlapjához. A szűrő két értéket kap: az attribútumok tömbjét és az űrlap azonosítóját. A pénztár űrlapjának azonosítója `checkout`, a rendelés fizetése oldalé `order_review`. A példa csak a pénztáron ad hozzá egy `foo="bar"` attribútumot:

```php
add_filter(
	'cfw_form_attributes',
	function( $attributes, $id ) {
		// Csak a pénztáron, a rendelés fizetése oldalon nem
		if ( 'checkout' !== $id ) {
			return $attributes;
		}

		$attributes['foo'] = 'bar';
		return $attributes;
	},
	10,
	2
);
```
