# Kódrészletek

> Kész PHP- és JavaScript-részletek a pénztár, az e-mailek, a vásárlói profil, az árak, a Stripe és a kampánykövetés testreszabásához.

Ezek a kész részletek a FluentCart működését szabják testre. Másold őket a sablonod `functions.php` fájljába, vagy használj kódrészlet-kezelő bővítményt.

A részletek horgokon (hook) keresztül működnek. A horog a FluentCartba épített kapcsolódási pont, ahová néhány sor kóddal beavatkozhatsz egy működésbe. Kódban élnek, nem a vezérlőpulton, ezért kapcsolót vagy mezőt nem találsz hozzájuk az admin felületen.

## Pénztár

### Felesleges tizedesek elrejtése

Alapból az árak tizedesekkel jelennek meg (például 10,00). Ha tisztább árakat szeretnél, használd ezt:

```php
<?php

add_filter('fluent_cart/hide_unnecessary_decimals', '__return_true');
```

A szűrő a záró nullákat hagyja el: a 10,00 helyett 10 látszik, a 10,50 viszont marad 10,50.

### Egyéni tételadat a pénztáron

A `fluent_cart/cart/line_item/line_meta` művelet a pénztár rendelésösszegzésében minden kosártétel alá kiírhat egyéni adatot. A horog a termék, a változat neve és a gyermekváltozatok kiírása után, de a tétel ára előtt fut le.

```php
add_action('fluent_cart/cart/line_item/line_meta', function ($data) {
    $item = $data['item'] ?? [];

    if (empty($item['line_meta']) || !is_array($item['line_meta'])) {
        return;
    }

    $giftMessage = $item['line_meta']['gift_message'] ?? '';

    if (!$giftMessage) {
        return;
    }

    echo '<div class="fct-custom-line-meta">';
    echo '<small>' . esc_html__('Üzenet az ajándékhoz:', 'sajat-szovegtar') . ' ' . esc_html($giftMessage) . '</small>';
    echo '</div>';
}, 10, 1);
```

A függvény egy `$data` tömböt kap:

```php
$data = [
    'item'    => $item,     // A kosártétel adatai. Ezt használd.
    'cart'    => $cart,     // Az aktuális kosár, ha van, különben null.
    'product' => $product,  // Fenntartva a termékadatnak; jelenleg lehet null.
    'variant' => $variant,  // Fenntartva a változatnak; jelenleg lehet null.
];
```

Az `item` a megbízható forrás. A `$data['item']['line_meta']` tételenként tárolt adatokat ad, például ajándékszöveget, gravírozást, licencadatot vagy foglalási dátumot.

### Számlázási mezők elrejtése nulla összegű pénztárnál

Ingyenes webinárhoz vagy más, fizetés nélküli pénztárhoz elrejtheted a számlázási cím mezőit, ha a kosár végösszege nulla. A második szűrő ugyanezekről a mezőkről leveszi a hibaüzeneteket, így a vevő cím megadása nélkül is befejezheti a vásárlást.

```php
<?php

/**
 * Számlázási címmezők elrejtése nulla összegű pénztárnál.
 */
add_filter(
    'fluent_cart/checkout_renderer/billing_fields',
    function ($fields, $data) {
        $cart = $data['cart'] ?? null;

        if ($cart && $cart->isZeroPayment()) {
            return [];
        }

        return $fields;
    },
    10,
    2
);

/**
 * A számlázási cím hibaüzeneteinek törlése nulla összegű pénztárnál.
 */
add_filter(
    'fluent_cart/checkout/validate_data',
    function ($errors, $data) {
        $cart = $data['cart'] ?? null;

        if (!$cart || !$cart->isZeroPayment()) {
            return $errors;
        }

        $addressFields = [
            'billing_country',
            'billing_state',
            'billing_address_1',
            'billing_address_2',
            'billing_city',
            'billing_postcode',
            'billing_phone',
        ];

        foreach ($addressFields as $field) {
            unset($errors[$field]);
        }

        return $errors;
    },
    10,
    2
);
```

Mindkét szűrő a `$cart->isZeroPayment()` értékét nézi, ezért a fizetős pénztárakon a számlázási mezők és ellenőrzésük változatlan marad.

### A Stripe kártyamentésének szabályozása

Stripe-fizetésnél a FluentCart dönti el, kérje-e a Stripe-tól, hogy tárolja a kártyát későbbi használatra. A szűrővel felülírhatod ezt a döntést. Például előfizetéses pénztárnál mentheted a kártyát, egyszeri vásárlásnál soha.

A szűrő megkapja az aktuális értéket és egy `data` és `has_subscription` elemet tartalmazó tömböt. Az `on_session` vagy `off_session` érték a kártya tárolását kéri, a hamis értékű nem.

```php
<?php

/**
 * Csak akkor tároltassa a Stripe a kártyát, ha a pénztárban előfizetés is van.
 */
add_filter(
    'fluent_cart/stripe/client_setup_future_usage',
    function ($setupFutureUsage, $context) {
        if (empty($context['has_subscription'])) {
            return null;
        }

        return $setupFutureUsage;
    },
    10,
    2
);
```

Fontos: a Stripe elutasítja a fizetést, ha a kártyaelem létrehozásakor és a megerősítéskor küldött érték nem egyezik. A szűrő logikája legyen determinisztikus, azaz ugyanaz a pénztár mindig ugyanazt az eredményt adja, és ne függjön olyasmitől, ami a két kérés között változhat.

### A rendelés adatainak módosítása létrehozás előtt

Közvetlenül az új rendelés mentése előtt a FluentCart átadja neked a rendelés adatait. Amit itt módosítasz (megjegyzés, pénznem, végösszeg), az kerül a rendelésbe, a tranzakcióba és az előfizetésbe, ha van.

A szűrő megkapja az előkészített rendeléstömböt és egy tömböt `items` (a formázott tételek árral és mennyiséggel) és `args` (a pénztár paraméterei: vevői adatok, fizetési mód, szállítás, adó, kuponok, díjak) elemmel.

```php
<?php

/**
 * Teljesítési megjegyzés minden pénztárban létrejött rendelésre.
 */
add_filter(
    'fluent_cart/checkout/order_data',
    function ($orderData, $context) {
        $orderData['note'] = 'Elsőbbségi kezelés';

        return $orderData;
    },
    10,
    2
);
```

Ugyanez a szűrő az adminból kézzel létrehozott rendeléseknél is lefut, az `args` ilyenkor az admin rendelés paramétereit hordozza. Egy részlet így mindkét utat lefedi.

Mindig a teljes tömböt add vissza: ami kimarad, kimarad a rendelésből is. A végösszegeket úgy használja a rendszer, ahogy megadod, ezért összeg módosításakor számold újra magad.

## E-mailek

### E-mail módosítása közvetlenül küldés előtt

A FluentCart minden értesítést teljesen előkészít (tárgy, szöveg, címzett, mellékletek), mielőtt a levélküldőnek adná. A szűrő ezt a kész levelet adja a kezedbe az utolsó pillanatban.

A függvény a levélküldő objektumot és egy `event`, `mail_name`, `recipient`, `notification`, `data` elemeket tartalmazó tömböt kap. A végén a levélküldőt add vissza. Bármi mást visszaadva az eredeti levél változatlan marad, így egy hiba a részletedben nem akadályozza meg a levelek kimenetelét.

```php
<?php

/**
 * A raktár másolatot kap minden fizetett rendelésről szóló, vevőnek küldött levélből.
 */
add_filter(
    'fluent_cart/email_notification/mailer',
    function ($mailer, $context) {
        if ($context['mail_name'] === 'order_paid_customer') {
            $mailer->addBCC('raktar@pelda.hu');
        }

        return $mailer;
    },
    10,
    2
);
```

A levélküldő metódusai: `addCC()`, `addBCC()`, `setFrom()`, `setReplyTo()`, `setSubject()`, `body()`, `addAttachment()` és `setIsHtml()`. A legtöbb utolsó pillanatos módosítás egyetlen hívás.

A szűrő a küldési lépésen ül, ezért a háttérben kiküldött rendelési és előfizetési leveleket is lefedi, nem csak a azonnal küldötteket.

## Vásárlói profil

### Egyéni menüpont a vásárlói profilban

Az `addCustomerDashboardEndpoint()` metódussal új menüpontot adhatsz a FluentCart vásárlói profiljához.

```php
<?php

add_action('init', function () {
    \FluentCart\Api\FluentCartGeneralApi::getInstance()->addCustomerDashboardEndpoint(
        'support', [
            'title' => __('Ügyfélszolgálat', 'fluent-cart-pro'),
            // 'render_callback' => function () {
            //     echo 'Ide írd a szöveget';
            // },
            'icon_svg' => '<svg style="padding: 2px;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.25v8.25a1.5 1.5 0 0 1-1.5 1.5H4.5a1.5 1.5 0 0 1-1.5-1.5v-8.25M12 4.875A2.625 2.625 0 1 0 9.375 7.5H12m0-2.625V7.5m0-2.625A2.625 2.625 0 1 1 14.625 7.5H12m0 0V21m-8.625-9.75h18c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125h-18c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125Z"></path></svg>',
            'page_id' => 178,
        ]
    );
});
```

Ha `render_callback` függvényt adsz meg, a menüpont ennek a kimenetét mutatja. Ha egy meglévő WordPress-oldalt akarsz megjeleníteni, hagyd el a `render_callback` részt, és add meg a `page_id` értékét.

### E-mail-megerősítés és vendégvásárlások visszaállítása kikapcsolása

Ha a **Megfelelőség** beállításai között a **Vásárlói e-mail cím ellenőrzése** értéke **Kötelező** (alapból ki van kapcsolva), az új vevői fióknak előbb meg kell erősítenie az e-mail-címét, hogy a vezérlőpult fiókadatot mutasson. A megerősítés egyben behozza a korábbi, vendégként, ugyanezzel a címmel leadott vásárlásokat is. Ha ez ütközik a saját regisztrációs folyamatoddal, ez a szűrő kikapcsolja a megerősítést és a visszaállítást:

```php
add_filter('fluent_cart/customer/enable_email_claim', '__return_false');
```

Kikapcsolt szűrő mellett az a fiók, amelynek e-mail-címe eltér a vevő adatlapjától, megtartja az eltérést, amíg egy munkatárs fel nem oldja, a vendégvásárlásokat pedig a rendszer sosem ajánlja fel automatikus visszaállításra. A szűrő magát a beállítást nem kapcsolja ki: ha a **Kötelező** érték marad, a meg nem erősített fiókok továbbra sem látják a vezérlőpultot.

## Termékárak

### Utótag az ár mellett

A `fluent_cart/product/price_suffix_atts` szűrővel rövid megjegyzést írhatsz az ár után, például „áfával” vagy „fejenként”. Add vissza a szöveget, és a FluentCart egy `fct_price_suffix` osztályú elembe írja az ár mellé.

```php
add_filter('fluent_cart/product/price_suffix_atts', function ($suffix, $context) {
    return 'áfával';
}, 10, 2);
```

A `$context` tömb tartalmazza a `product`, `variant` és `scope` elemeket, így a szöveg változhat termékenként vagy aszerint, hol látszik az ár. Üres szöveg esetén nem jelenik meg semmi.

Ha az adóbeállításaid már kiírnak adó utótagot, a FluentCart maga is megadja azt, és a te szűrőd utána fut, ezért a te értéked érvényesül. A beépített adómegjelenítési lehetőségek kód nélkül is lefedik a legtöbb áruházat; lásd az [Az adó beállításai](https://hub.hellowp.io/hu/plugins/fluent-cart-pro/ado-konfiguracio/) fejezetet.

## Megjelenés

### A Stripe fizetési űrlapjának színei

Ha a **Megjelenés** forrása a sablon színpalettájának öröklése vagy egyéni paletta, a FluentCart automatikusan számol a beágyazott Stripe fizetési űrlapnak megfelelő háttér-, szöveg- és kiemelő színt. Ezt a szűrővel felülírhatod, vagy akkor is megadhatod a saját színeidet, amikor a forrás a FluentCart saját alapértelmezése.

```php
add_filter('fluent_cart/stripe_appearance', function ($appearance) {
    $appearance['theme'] = 'night';
    $appearance['variables']['colorPrimary'] = '#7c3aed';

    return $appearance;
}, 10, 1);
```

A szűrő a Stripe Appearance API konfigurációs tömbjét (`theme` és `variables`) kapja, és ugyanilyen szerkezetet vár vissza. Amihez nem nyúlsz, az marad, azt is beleértve, amit a FluentCart már a palettából levezetett.

## Kampánykövetés

### Kampányforrás megőrzése több webhelyen át

Ha az áruházad több domainre terjed, például a marketingoldal egy külön pénztárdomainre küldi a vevőket, az átadásnál megszakadhat a kampányforrás követése. A második webhely az elsőt látja hivatkozóként, az eredeti `utm_source` elvész, a jelentések pedig a saját webhelyedhez írják az eladást, nem a hirdetéshez vagy hírlevélhez, amely hozta.

Add meg a FluentCartnak a saját domainjeidet, és a köztük lévő mozgást belső navigációnak tekinti. A saját domainjeid sosem kerülnek hivatkozóként rögzítésre, az eredeti kampányértékek pedig átkerülnek a hivatkozással.

```php
add_filter('fluent_cart/utm/internal_domains', function ($domains) {
    return ['bolt.pelda.hu', 'penztar.pelda.hu'];
});
```

Add meg a hálózatod minden domainjét, a pénztárét is. Az egyezés a puszta domainre, a `www.` változatra és minden aldomainre kiterjed, ezért az `example.com` megadása a `shop.example.com` címet is fedi.

Alapból a FluentCart nem alkalmaz belső domaineket, tehát a követés pontosan úgy működik, mint eddig, amíg ezt a részletet nem adod hozzá. A kampányértékek 30 napig tárolódnak a látogató böngészőjében. A rögzített adatok a jelentésekben a marketingforrás alatt jelennek meg; lásd az [Értékesítés riport](https://hub.hellowp.io/hu/plugins/fluent-cart-pro/riportok-ertekesites/) fejezetet.

### A kampánykövetés tárolásának hozzájáráshoz kötése

A kampányadatok a látogató böngészőjében tárolódnak, és az adatvédelmi szabályok (például a GDPR és a német TDDDG) ezt a tárolást a sütikkel azonosan kezelik. Ha az áruházban sütihozzájárulási sáv működik, így kötheted ahhoz a követést.

A FluentCart a `window` objektumon egy megszakítható `fluent_cart_utm_before_store` eseményt indít közvetlenül az írás előtt. A `preventDefault()` hívással lefoglalod az írást, utána az esemény `detail` részének `allow()` vagy `deny()` függvényével válaszolsz. Ez JavaScript, ezért a nyilvános oldalon tölts be, ne a `functions.php` fájlba másold.

```js
window.addEventListener('fluent_cart_utm_before_store', function (event) {
    // Foglald le az írást. Amíg nem válaszolsz, semmi sem tárolódik.
    event.preventDefault();

    myConsentBanner.ask('marketing').then(function (granted) {
        if (granted) {
            event.detail.allow();
        } else {
            event.detail.deny();
        }
    });
});
```

Három dolog teszi ezt biztonságossá:

- Akkor válaszolsz, amikor akarsz. Amíg a döntés függőben van, a kampányértékek az oldal memóriájában vannak, és nem íródnak az eszközre. Aki azon az oldalon fogad el, ahová érkezett, megtartja a követést.
- A `deny()` törli is a tárolt értékeket. Az elutasítás mindent töröl, ami már eltárolódott, ezért egyben a hozzájárulás visszavonásának kezelője is, így a visszavonás ugyanolyan könnyű, mint a megadás.
- Ha nem teszel semmit, nem változik semmi. Ha egyetlen figyelő sem foglalja le az eseményt, az írás a megszokott módon azonnal megtörténik, így a hozzájárulási sáv nélküli áruházakra nincs hatással.

A hozzájárulás későbbi visszavonásához, például egy beállítási hivatkozásról, közvetlenül hívd a kezelőt:

```js
window.fluentCartUtmManager?.revokeConsent();
```

Hogy a látogató mit döntött már, azt a `window.fluentCartUtmManager?.hasConsent()` hívással nézheted meg. Igazat ad vissza, amíg a követés olvasható és írható. Ezt érdemes ellenőrizned, mielőtt a FluentCart mellé saját követést kötsz.
