Release 0.9a: Move ng to main, modernize PHP 8.1+ client, update documentation and add Gitea workflow

This commit is contained in:
sandros committed 2026-09-28 09:19:38 +02:00
1 parent 76e09c0b96
commit 67bc8aa462
9 files changed
+1560 -1455

No files matched your search

+40
View File
@@ -0,0 +1,40 @@
name: Release PHP Validity Check
on:
release:
types: [published, created]
push:
branches: [master, main]
tags: ['v*']
pull_request:
branches: [master, main]
jobs:
php-validity:
name: PHP Validity (PHP ${{ matrix.php-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php-version: ['8.1', '8.2', '8.3', '8.4']
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: curl, json
coverage: none
- name: PHP Syntax Check (Lint)
run: |
php -l ninjamail.class.php
php -l test_all.php
php -l tests/test_validity.php
- name: Run PHP Validity & Type Tests (Offline - No API Calls)
run: |
php tests/test_validity.php
+26
View File
@@ -0,0 +1,26 @@
# Changelog
A ninjaMail API klienskönyvtár változásainak jegyzéke.
---
## [0.9a] - 2026-09-28
### Hozzáadva (Added)
- **Modern PHP 8.1+ támogatás:** Szigorú típusosság (`declare(strict_types=1);`), típusos osztálytulajdonságok, skalár és union típusok minden osztályban (`ninjaMail`, `ninjaMailSend`, `ninjaMailSubscription`, `ninjaMailNewsletter`, `ninjaMailCampaign`, `ninjaMailStatistics`).
- **Gitea Actions CI/CD automatizáció:** Új `.gitea/workflows/release-test.yaml` munkafolyamat, amely automatikusan ellenőrzi a PHP érvényességet és szintaxist (PHP 8.1, 8.2, 8.3, 8.4 verziókon) minden kiadáskor (`release`), címkénél (`tag`) és push eseménynél külső API hívások nélkül.
- **Offline érvényesség-ellenőrzés:** Új `tests/test_validity.php` tesztcsomag a metódusok, típusok és kivételkezelés tesztelésére hálózati forgalom nélkül.
- **Anonimizált tesztelő szkript:** Új `test_all.php` futtatható tesztfájl környezeti változókból (`NINJAMAIL_HOST`, `NINJAMAIL_KEY`) konfigurálható, anonimizált tesztadatokkal.
- **Kriptográfiailag biztonságos token generálás:** A `login()` metódusban `bin2hex(random_bytes(16))` használata a korábbi gyenge `md5(time())` helyett.
### Módosítva (Changed)
- **Főkönyvtár átszervezése:** Az `ng` mappa tartalma átkerült a projekt gyökerébe, az új generációs kód vált a hivatalos kiadássá.
- **Terminológia szabványosítása:** A félrevezető „gyár” kifejezés cseréje a szabványos „végpont” (*endpoint*) megnevezésre a kódban és a teljes dokumentációban.
- **Dokumentáció egyesítése és felülvizsgálata:** A `README.md` összefésülése és frissítése, a hibás adatok tisztítása (pl. `fekiratkozó` elgépelés, kampányvégpont feladatának pontosítása, hiányzó listakezelési útmutató és hírlevél frissítési adatok pótlása).
- **cURL kéréskódolás:** A POST kérések form-urlencoded kódolást (`http_build_query`) használnak, biztosítva a tömbösített és összetett paraméterek (pl. kampány listák `update()`) hibátlan szerveroldali fogadását.
- **Kampány-hírlevél összerendelés:** A `ninjaMailCampaign::attach()` metódus mostantól mind a `campaign`, mind az `id` paramétert továbbítja, biztosítva a szerveroldali `relations` végpont kompatibilitását.
- **PHP 8.5 kompatibilitás:** A PHP 8.5-ben elavulttá vált `curl_close()` hívás eltávolítása, és üres API válaszok robusztus kezelése JSON szintaxishiba dobása nélkül.
### Eltávolítva (Removed)
- Az elavult, nem típusos örökölt kódok (`example.simple.php` és az eredeti gyökér `ninjamail.class.php`) törlésre kerültek az új kiadásokból.
- Az `ng` alkönyvtár megszüntetésre került.
+589 -153
View File
@@ -1,207 +1,643 @@
ninjaMail API
===============
Ebben a fájlban olvashat arról, hogyan használhatja a levelező
alkalmazásprogramozási interfészét.
A példákban szereplő lekérések PHP programozási szemszögből készültek, viszont
felhasználható más nyelven íródott projektekben is, amennyiben az rendelkezik
CURL könyvtárral vagy más, GET és POST hívást támogató eszközzel.
## Bevezetés
Az API használatához regisztráció után generálni kell egy kulcsot. Ez a
Beállítások -> API menüből érhető el. A generált kulcsot tartsa titokban!
Míg API kulccsal nem lehet bejelentkezni a webes felületen, az API felületen a
legtöbb funkció elérhető. A kulcs felhasználásával lehetőség nyílik többek
között feliratkozók hozzáadására, törlésére.
## API URL
Az URL kulcsgenerálás után ugyan azon a felületen lesz látható.
`Példa: http://example.org/a/<gyár>?key=<kulcs>
Ahol: example.org - szolgáltató, <gyár> - részegység, <kulcs> - API kulcs
# ninjaMail API
A ninjaMail levelező alkalmazásprogramozási interfészének (API) hivatalos dokumentációja és PHP klienskönyvtára.
A dokumentáció ismerteti a közvetlen HTTP (cURL, GET/POST) végpontok hívását, valamint a modern, szigorúan típusos PHP 8.1+ kliensosztályok használatát.
---
## Tartalomjegyzék
- [Követelmények](#követelmények)
- [Bevezetés és hitelesítés](#bevezetés-és-hitelesítés)
- [API alap URL](#api-alap-url)
- [Hibakezelés](#hibakezelés)
- [API végpontok](#api-végpontok)
- [Feliratkozó hozzáadása (subscribe)](#feliratkozó-hozzáadása)
- [Feliratkozó eltávolítása (unsubscribe)](#feliratkozó-eltávolítása)
- [Listák kezelése (list)](#listák-kezelése)
- [Hírlevél létrehozása (newsletter)](#hírlevél-létrehozása)
- [Hírlevél frissítése (newsletter)](#hírlevél-frissítése)
- [Hírlevél küldése (newsletter)](#hírlevél-küldése)
- [Hírlevelek listázása (newsletter)](#hírlevelek-listázása)
- [Kampány létrehozása (campaign)](#kampány-létrehozása)
- [Kampány törlése (campaign)](#kampány-törlése)
- [Kampány frissítése – listák csatolása (campaign)](#kampány-frissítése-listák-csatolása)
- [Kampány csatolása hírlevélhez (campaign)](#kampány-csatolása-hírlevélhez)
- [Egyedi e-mail küldése (send)](#egyedi-e-mail-küldése)
- [E-mail küldés állapotának ellenőrzése (send)](#e-mail-küldés-állapotának-ellenőrzése)
- [Statisztikák lekérdezése (statistics)](#statisztikák-lekérdezése)
- [Távoli belépés (login)](#távoli-belépés)
- [PHP kliens használati útmutató és példák](#php-kliens-használati-útmutató-és-példák)
- [Inicializálás és távoli belépés](#inicializálás-és-távoli-belépés)
- [Feliratkozás és leiratkozás](#feliratkozás-és-leiratkozás)
- [Egyedi levél küldése](#egyedi-levél-küldése)
- [Hírlevél létrehozása, frissítése és küldése](#hírlevél-létrehozása-frissítése-és-küldése)
- [Kampány kezelése](#kampány-kezelése)
- [Statisztika lekérdezése](#statisztika-lekérdezése)
---
## Követelmények
A PHP kliens használatához az alábbi környezet szükséges:
- **PHP 8.1** vagy újabb (`declare(strict_types=1);`, típusos osztálymezők és metódusok)
- `curl` PHP kiterjesztés
- `json` PHP kiterjesztés
---
## Bevezetés és hitelesítés
Az API használatához regisztráció után API kulcsot kell generálni a **Beállítások → API** menüpontban.
A generált kulcsot kezelje bizalmasan — a kulccsal a funkciók túlnyomó része elérhető programozottan, beleértve a feliratkozók kezelését, kampányok indítását és egyedi levelek küldését.
Webes adminisztrációs belépésre az API kulcs önmagában nem alkalmas (erre a távoli `login` végpont által adott egyszer használatos token szolgál).
---
## API alap URL
A kulcsgenerálás után az API URL a felületen is megjelenik:
```
https://example.org/a/<végpont>/?key=<kulcs>
```
| Elem | Leírás |
|---|---|
| `example.org` | A szolgáltató domain címe / alap URL-je |
| `<végpont>` | A meghívandó funkciót kezelő végpont neve (pl. `subscribe`, `send`, `newsletter`) |
| `<kulcs>` | Az API hitelesítési kulcs |
> **Biztonsági megjegyzés:** Éles környezetben mindig biztonságos HTTPS kapcsolatot használjon!
---
## Hibakezelés
A modern PHP kliens kétféle kivételt dobhat:
- `InvalidArgumentException`: ha egy kötelező mező hiányzik vagy érvénytelen (pl. hiányzó lista ID feliratkozáskor, üres címzett/tárgy/üzenet küldéskor, üres kampánynév).
- `RuntimeException`: kommunikációs vagy hitelesítési hibák esetén (hiányzó gazdagép vagy API kulcs, cURL hálózati hiba, érvénytelen JSON válasz).
A legutóbbi sikeres API kérés nyers, dekódolt JSON válasza elérhető az objektum publikus `$data` mezőjében (`$client->data`).
Ajánlott try/catch mintázat:
```php
try {
$mailer = new ninjaMailSend('https://example.org', 'API_KEY');
$mailer->to('ugyfel@example.com');
$mailer->subject('Értesítés');
$mailer->message('<p>Üdvözöljük!</p>');
$ok = $mailer->send();
} catch (InvalidArgumentException $e) {
// Kliensoldali validációs hiba
error_log('Validációs hiba: ' . $e->getMessage());
} catch (RuntimeException $e) {
// Hálózati vagy szerveroldali JSON hiba
error_log('API hiba: ' . $e->getMessage());
}
```
---
## API végpontok
### Feliratkozó hozzáadása
Feliratkozó hozzáadása esetén tudni kell a lista azonosítóját. Ez a webes
felületre történő belépés után a Listák menüpontban a kettőskereszt oszlopban
látható. A feliratkozást végző gyár: subscribe
A kérés a következőképpen alakul:
`POST: http://example.org/a/subscribe?key=<kulcs>`
`DATA: list=<id>&name=<Feliratkozó neve>&email=<Feliratkozó E-mail>&activated=<1|0>`
Az activated paraméter 1-es állásban megerősítettként rögzíti a feliratkozót,
míg 0 állásban küld megerősítő hivatkozást a megadott címre.
(Opcionális) Feliratkozó nevének módosítása: `forcenamechange=<1|0>`
#### Várható válaszok
Sikeres feliratkozás: `success`, Sikertelen feliratkozás: `sub_error`,
Nincs MX rekord: `no_mx_record` (ez lehet átmeneti hiba is),
Rossz lista azonosító: `bad_list`, Sikertelen regisztráció: `reg_error`
Új feliratkozót ad hozzá a megadott azonosítójú listához. A lista azonosítója a webes adminisztrációs felületen a **Listák** menüpontban, a kettőskereszt (`#`) oszlopban található.
### Feliratkozó eltávolítása listáról
Feliratkozó eltávolításához szükségünk van a lista azonosítójára és a feliratkozó
e-mail címére.
A leiratkozást végző gyár: unsubscribe
A kérés a következőképpen alakul:
`POST: http://example.org/a/unsubscribe?key=<kulcs>`
`DATA: list=<id>&email=<Feliratkozó E-mail>`
**Végpont:** `subscribe`
```
POST: https://example.org/a/subscribe/?key=<kulcs>
DATA: list=<id>&name=<Feliratkozó neve>&email=<E-mail>&activated=<1|0>&forcenamechange=<1|0>
```
Paraméterek:
- `list` (kötelező): A levelezőlista azonosítója (pozitív egész szám).
- `email` (kötelező): A feliratkozó e-mail címe.
- `name` (opcionális): A feliratkozó neve.
- `activated` (kötelező):
- `1`: a feliratkozó azonnal megerősítettként (aktívként) kerül mentésre.
- `0`: a rendszer megerősítő e-mailt küld a megadott címre.
- `forcenamechange` (opcionális):
- `1`: ha az e-mail cím már szerepel a listában, a feliratkozó neve felülírásra kerül.
- `0`: meglévő feliratkozó esetén a név változatlan marad.
#### Várható válaszok
Sikeres leiratkozás: `success`, Sikertelen leiratkozás: `unsub_error`,
Ismeretlen E-mail cím: `unknown_email`, Hiányzó paraméterek: `missing_parameters`
| Státusz | Leírás |
|---|---|
| `success` | Sikeres feliratkozás |
| `sub_error` | Sikertelen feliratkozás |
| `no_mx_record` | Nincs érvényes MX rekord (lehet átmeneti DNS hiba is) |
| `bad_list` | Érvénytelen lista azonosító |
| `reg_error` | Sikertelen regisztráció |
### Lista létrehozás
Levelezőlista létrehozására alkalmas.
A listát kezelő gyár: list
A kérés a következőképpen alakul:
`POST: http://example.org/a/list?key=<kulcs>`
`DATA: new&name=<Lista neve>`
---
### Feliratkozó eltávolítása
Feliratkozó törlése az adott listáról.
**Végpont:** `unsubscribe`
```
POST: https://example.org/a/unsubscribe/?key=<kulcs>
DATA: list=<id>&email=<E-mail>
```
Paraméterek:
- `list` (kötelező): A levelezőlista azonosítója.
- `email` (kötelező): A leiratkozó e-mail címe.
#### Várható válaszok
Sikeres kérés: `success`, Sikertelen kérés: `failed`,
Nem megfelelő név: `bad_name`
| Státusz | Leírás |
|---|---|
| `success` | Sikeres leiratkozás |
| `unsub_error` | Sikertelen leiratkozás |
| `unknown_email` | Ismeretlen e-mail cím a megadott listában |
| `missing_parameters` | Hiányzó kötelező paraméterek |
### Lista törlése
Levelezőlista törlésére alkalmas.
A listát kezelő gyár: list
A kérés a következőképpen alakul:
`POST: http://example.org/a/list?key=<kulcs>`
`DATA: remove&id=<Lista ID>`
---
### Listák kezelése
Levelezőlisták létrehozása, törlése és listázása a nyers API végponton keresztül.
> **Megjegyzés:** A PHP klienskönyvtár a lista-műveletekhez nem tartalmaz külön burkolóosztályt; a hívások közvetlenül a `ninjaMail::process('list', $data)` metódussal kezdeményezhetők, míg a `ninjaMailSubscription::list(int $id)` metódus a fel- és leiratkozás cél-listájának kiválasztására szolgál.
**Végpont:** `list`
#### Lista létrehozása
```
POST: https://example.org/a/list/?key=<kulcs>
DATA: new&name=<Lista neve>
```
| Státusz | Leírás |
|---|---|
| `success` | Sikeres létrehozás |
| `failed` | Sikertelen kérés |
| `bad_name` | Nem megfelelő vagy üres név |
#### Lista törlése
```
POST: https://example.org/a/list/?key=<kulcs>
DATA: remove&id=<Lista ID>
```
| Státusz | Leírás |
|---|---|
| `success` | Sikeres törlés |
| `failed` | Sikertelen törlés |
#### Listák lekérdezése
```
POST: https://example.org/a/list/?key=<kulcs>
DATA: get
```
Válasz: Sikeres kérés esetén a listák tömbje/objektuma.
---
### Hírlevél létrehozása
Új hírlevél piszkozatot hoz létre a megadott tartalommal.
**Végpont:** `newsletter`
```
POST: https://example.org/a/newsletter/?key=<kulcs>
DATA: new&subject=<Tárgy>&message=<HTML tartalom>&message_text=<Szöveges tartalom>
```
Paraméterek:
- `new`: Műveletjelző.
- `subject`: A hírlevél tárgya.
- `message`: A levél HTML tartalma.
- `message_text` (opcionális): A levél egyszerű szöveges (Plain text) változata. Ha nincs megadva, automatikusan a HTML tartalomból származik a HTML tag-ek eltávolításával.
#### Várható válaszok
Sikeres kérés: `success`, Sikertelen kérés: `failed`
| Státusz | Leírás |
|---|---|
| `success` + `id` | Sikeres létrehozás, visszaadja az új hírlevél azonosítóját |
| `failed` | Sikertelen kérés |
| `bad_subject` | Érvénytelen vagy üres tárgy |
| `message_too_powerful` | Túl hosszú levéltartalom |
| `message_too_short` | Túl rövid levéltartalom |
### Listák lekérdezése
Levelezőlisták lekérdezésére alkalmas.
A listát kezelő gyár: list
A kérés a következőképpen alakul:
`POST: http://example.org/a/list?key=<kulcs>`
`DATA: get`
---
### Hírlevél frissítése
Meglévő hírlevél tartalmának és tárgyának módosítása.
**Végpont:** `newsletter`
```
POST: https://example.org/a/newsletter/?key=<kulcs>
DATA: new&id=<Levél ID>&subject=<Tárgy>&message=<HTML tartalom>&message_text=<Szöveges tartalom>
```
Várható válaszok: megegyeznek a hírlevél létrehozásánál leírtakkal.
---
### Hírlevél küldése
Hírlevél azonnali vagy ütemezett kiküldése.
**Végpont:** `newsletter`
```
POST: https://example.org/a/newsletter/?key=<kulcs>
DATA: send&id=<Levél ID>&start=<Unix timestamp vagy 0>
```
Paraméterek:
- `send`: Műveletjelző.
- `id`: A kiküldendő hírlevél azonosítója.
- `start`: Unix időbélyeg az ütemezéshez, vagy `0` / üres érték azonnali kiküldéshez.
#### Várható válaszok
Sikeres kérés: -tömb-
| Státusz | Leírás |
|---|---|
| `success` | Sikeresen sorba állítva kiküldésre |
| `already_queued` | A levél már szerepel a kiküldési várólistán |
| `failed` | Sikertelen sorbaállítás |
### Levél létrehozás
Levelek létrehozására alkalmas.
A leveleket kezelő gyár: newsletter
A kérés a következőképpen alakul:
`POST: http://example.org/a/newsletter?key=<kulcs>`
`DATA: new&subject=<Levél tárgya>&message=<Levél HTML tartalma>&message_text=<Levél TEXT tartalma>`
---
#### Várható válaszok
Sikeres kérés: `success`, `id`, Sikertelen kérés: `failed`,
Nem megfelelő tárgy: `bad_subject`, Túl hosszú üzenet: `message_too_powerful`,
Túl rövid üzenet: `message_too_short`
### Hírlevelek listázása
Lekérdezi az elérhető hírlevelek listáját.
### Levél küldése
Levelek küldésére alkalmas.
A leveleket kezelő gyár: newsletter
A kérés a következőképpen alakul:
`POST: http://example.org/a/newsletter?key=<kulcs>`
`DATA: send&id=<Levél ID>&start=<Unix timestamp vagy 0 azonnal>`
**Végpont:** `newsletter`
#### Várható válaszok
Sikeres kérés: `success`, Már várólistán: `already_queued`, Sikertelen kérés: `failed`
```
POST: https://example.org/a/newsletter/?key=<kulcs>
DATA: get
```
Válasz: Sikeres kérés esetén a leveleket tartalmazó lista / objektum.
### Levelek listázása
Levelek listázására alkalmas.
A leveleket kezelő gyár: newsletter
A kérés a következőképpen alakul:
`POST: http://example.org/a/newsletter?key=<kulcs>`
`DATA: get`
#### Várható válaszok
Sikeres kérés: -tömb-
---
### Kampány létrehozása
Kampányok létrehozására alkalmas.
A leveleket kezelő gyár: campaign
A kérés a következőképpen alakul:
`POST: http://example.org/a/campaign?key=<kulcs>`
`DATA: new&name=<Kampány neve>`
Új kampányt hoz létre.
**Végpont:** `campaign`
```
POST: https://example.org/a/campaign/?key=<kulcs>
DATA: new&name=<Kampány neve>
```
#### Várható válaszok
Sikeres kérés: `success`, `id`, Sikertelen kérés: `failed`
| Státusz | Leírás |
|---|---|
| `success` + `id` | Sikeres létrehozás, visszaadja az új kampány azonosítóját |
| `failed` | Sikertelen létrehozás |
---
### Kampány törlése
Kampányok törlésére alkalmas.
A leveleket kezelő gyár: campaign
A kérés a következőképpen alakul:
`POST: http://example.org/a/campaign?key=<kulcs>`
`DATA: remove&id=<Kampány ID>`
Törli a kiválasztott kampányt.
**Végpont:** `campaign`
```
POST: https://example.org/a/campaign/?key=<kulcs>
DATA: remove&id=<Kampány ID>
```
#### Várható válaszok
Sikeres kérés: `success`, Sikertelen kérés: `failed`
| Státusz | Leírás |
|---|---|
| `success` | Sikeres törlés |
| `failed` | Sikertelen törlés |
### Kampány frissítése (csatolás)
Kampányok listához történő csatolására alkalmas.
A leveleket kezelő gyár: campaign
A kérés a következőképpen alakul:
`POST: http://example.org/a/campaign?key=<kulcs>`
`DATA: update&id=<Kampány ID>&lists=<Array of ListIDs>`
---
### Kampány frissítése – listák csatolása
Levelezőlistákat rendel egy meglévő kampányhoz.
**Végpont:** `campaign`
```
POST: https://example.org/a/campaign/?key=<kulcs>
DATA: update&id=<Kampány ID>&lists=<Lista ID-k tömbje>
```
#### Várható válaszok
Sikeres kérés: `success`, Sikertelen kérés: `failed`
| Státusz | Leírás |
|---|---|
| `success` | Sikeres frissítés |
| `failed` | Sikertelen frissítés |
### Kampány csatolása levélhez
Kampányok levélhez történő csatolására alkalmas.
A leveleket kezelő gyár: campaign
A kérés a következőképpen alakul:
`POST: http://example.org/a/campaign?key=<kulcs>`
`DATA: relations&campaign=<Kampány ID1,ID2,ID3>&newsletter=<Levél ID>`
---
### Kampány csatolása hírlevélhez
Hírlevelet rendel a kampányhoz.
**Végpont:** `campaign`
```
POST: https://example.org/a/campaign/?key=<kulcs>
DATA: relations&id=<Kampány ID>&newsletter=<Levél ID>
```
> **Megjegyzés:** A PHP kliens az `attach()` metódusban az `id` mezőben küldi el az aktív kampány azonosítóját. Közvetlen HTTP kérések esetén több kampány azonosítója vesszővel elválasztva a `campaign=<ID1,ID2...>` mezőben is átadható.
#### Várható válaszok
Sikeres kérés: `success`, Sikertelen kérés: `failed`
| Státusz | Leírás |
|---|---|
| `success` | Sikeres hozzárendelés |
| `failed` | Sikertelen művelet |
### E-mail küldése
Egyéni e-mail küldését, valamint annak sikerességének vizsgálatát teszi lehetővé.
Az üzenet HTML és Plain text formában kerül kiküldésre. Ha a `message_text` értéke
üres, a HTML formátumú levél tartalmával minusz HTML tag-ek lesz azonos. Az üzenet
csak a HTML body részét tartalmazza! Nagy mennyiségű üzenet küldésére használja a
newsletter, list és campaigns gyárakat!
A küldést és ellenőrzést végző gyár: send
A kérés a következőképpen alakul:
`POST: http://example.org/a/send?key=<kulcs>`
`DATA: to=<subscriber ID vagy Email cím>&subject=<Tárgy>&message=<Üzenet HTML formában>&message_text=<Üzenet TXT formában>`
---
### Egyedi e-mail küldése
Egyéni, tranzakciós e-mail kiküldésére alkalmas.
Nagy mennyiségű, tömeges levélküldéshez a `newsletter`, `list` és `campaign` végpontokat használja!
Az üzenet csak a HTML `<body>` belső tartalmát tartalmazza. Ha a `message_text` nincs megadva, automatikusan a HTML tag-ek nélküli szövegből generálódik.
**Végpont:** `send`
```
POST: https://example.org/a/send/?key=<kulcs>
DATA: to=<Feliratkozó ID vagy E-mail>&subject=<Tárgy>&message=<HTML tartalom>&message_text=<Szöveges tartalom>
```
#### Várható válaszok
Sikeres sorbaállítás: `message_queued`, `id`, Nem található feliratkozó: `subscriber_not_found`,
Sikertelen fekiratkozó mentés: `subscriber_error`, Sikertelen sorbaállítás: `message_failed`,
Csomagkorlát elérve: `quota_reached`, Hiányzó paraméter: `missing_parameter`
| Státusz | Leírás |
|---|---|
| `message_queued` + `id` | Sikeresen sorba állítva a kiküldéshez |
| `subscriber_not_found` | A megadott feliratkozó nem található |
| `subscriber_error` | Feliratkozó mentési hiba |
| `message_failed` | Sikertelen sorbaállítás |
| `quota_reached` | Elérte a csomagban engedélyezett korlátot |
| `missing_parameter` | Hiányzó kötelező mező |
### E-mail küldés ellenőrzés
A send gyáron keresztül küldött levelek ellenőrzésére alkalmas. A kimenő levelek
pixel2 lekérésének idejét, a küldés befejezésének idejét és a sikerességét tudja.
`GET: http://example.org/a/send?key=<kulcs>`
`DATA: just_asking=<id>`
---
### E-mail küldés állapotának ellenőrzése
A `send` végponton keresztül küldött egyedi levelek kézbesítési és megnyitási állapotának ellenőrzésére szolgál.
**Végpont:** `send`
```
GET: https://example.org/a/send/?key=<kulcs>&just_asking=<id>
```
Paraméter:
- `just_asking`: A kiküldött levél azonosítója (`id`), amit a sikeres küldéskor adott vissza az API.
#### Várható válaszok
Sikeres lekérdezés: (status)`success/failed`, `read`, `to`, `time`
Sikertelen lekérdezés: `wrong_id`
| Státusz | Visszaadott mezők | Leírás |
|---|---|---|
| `success` | `status`, `read`, `to`, `time` | Sikeres lekérdezés; a levél sikeresen elküldve (és megnyitva, ha `read` be van állítva) |
| `failed` | `status`, `read`, `to`, `time` | Sikertelen küldés |
| `wrong_id` | — | Nem létező levél azonosító |
### Belépés távolról
Lehetőség van távoli belépésre. Ilyenkor felhasználói név és jelszó megadása
nélkül is lehetőség adódik az adminisztrációs felület elérésére. Az API kérés
egy véletlenszerű kulcsot ad vissza, amit a http://example.org/ oldalnak kell
elküldeni böngészőből.
A belépést végző gyár: login
A kérés a következőképpen alakul:
`POST: http://example.org/a/login?key=<kulcs>`
`DATA: rkey=<véletlenszerű string>`
---
### Statisztikák lekérdezése
Kiküldött hírlevelek részletes statisztikai mutatóinak (megnyitások, kattintások, visszapattanók stb.) lekérdezése.
**Végpont:** `statistics`
```
POST: https://example.org/a/statistics/?key=<kulcs>
DATA: newsletter=<Levél ID>&type=1
```
Válasz: A statisztikai adatokat tartalmazó objektum.
---
### Távoli belépés
Lehetővé teszi az adminisztrációs felület közvetlen elérését felhasználónév és jelszó megadása nélkül.
Az API kérés egy egyszer használatos bejelentkezési tokent generál, amellyel a böngészőből átirányítható a felhasználó.
**Végpont:** `login`
```
POST: https://example.org/a/login/?key=<kulcs>
DATA: rkey=<véletlenszerű string>
```
> **Biztonsági megjegyzés:** A PHP kliens kriptográfiailag biztonságos `bin2hex(random_bytes(16))` segítségével generálja az `rkey` paramétert. Ne használjon gyenge megoldásokat (pl. `md5(time())`).
#### Várható válaszok
Sikeres token generálás: `success` és `token`
| Státusz | Leírás |
|---|---|
| `success` + `token` | Sikeres token generálás. A belépési link a megadott oldalra vezet a token átadásával. |
---
## PHP kliens használati útmutató és példák
A PHP kliens használatához illessze be a `ninjamail.class.php` fájlt:
```php
require_once __DIR__ . '/ninjamail.class.php';
```
### Inicializálás és távoli belépés
```php
$api = new ninjaMail('https://example.org', 'AZ_ON_API_KULCSA');
if (!$api->check()) {
die('Hiányzó gazdagép vagy API kulcs!');
}
// Egyszer használatos bejelentkezési token kérése
try {
$loginData = $api->login();
if (($loginData->status ?? '') === 'success') {
echo 'Bejelentkezési token: ' . $loginData->token;
}
} catch (RuntimeException $e) {
error_log('Hiba a távoli belépéskor: ' . $e->getMessage());
}
```
---
### Feliratkozás és leiratkozás
```php
$sub = new ninjaMailSubscription('https://example.org', 'AZ_ON_API_KULCSA');
// Lista kiválasztása
$sub->list(12);
// true = azonnali aktiválás; false = megerősítő levél küldése
$sub->activated(true);
// Opcionális: meglévő feliratkozó nevének felülírása engedélyezett
$sub->namechange(true);
try {
// Feliratkozás
$success = $sub->subscribe('teszt@example.com', 'Teszt Elek');
if ($success) {
echo 'Sikeres feliratkozás!';
} else {
echo 'Sikertelen feliratkozás. Válasz: ' . json_encode($sub->data);
}
// Leiratkozás ugyanarról a listáról
$unsubSuccess = $sub->unsubscribe('teszt@example.com');
if ($unsubSuccess) {
echo 'Sikeres leiratkozás!';
}
} catch (InvalidArgumentException $e) {
echo 'Paraméterhiba: ' . $e->getMessage();
} catch (RuntimeException $e) {
echo 'API kommunikációs hiba: ' . $e->getMessage();
}
```
---
### Egyedi levél küldése
```php
$mailer = new ninjaMailSend('https://example.org', 'AZ_ON_API_KULCSA');
$mailer->to('ugyfel@example.com');
$mailer->subject('Rendelés visszaigazolása');
$mailer->message(
'<h1>Köszönjük a vásárlást!</h1><p>A rendelését feldolgozzuk.</p>',
'Köszönjük a vásárlást! A rendelését feldolgozzuk.' // opcionális plain text
);
try {
$sent = $mailer->send();
if ($sent) {
echo 'Levél sikeresen sorba állítva!';
} else {
echo 'Küldési hiba: ' . json_encode($mailer->data);
}
} catch (InvalidArgumentException $e) {
echo 'Hiányzó kötelező adat: ' . $e->getMessage();
} catch (RuntimeException $e) {
echo 'Hálózati hiba: ' . $e->getMessage();
}
```
---
### Hírlevél létrehozása, frissítése és küldése
```php
$nl = new ninjaMailNewsletter('https://example.org', 'AZ_ON_API_KULCSA');
$nl->subject('Havi hírlevelünk - 2026 Október');
$nl->message('<p>Itt olvashatóak az e havi újdonságok...</p>');
try {
// 1. Hírlevél létrehozása
$newsletterId = $nl->create();
if ($newsletterId !== false) {
echo 'Hírlevél létrehozva, ID: ' . $newsletterId . PHP_EOL;
// 2. Hírlevél frissítése szükség esetén
$nl->subject('Havi hírlevelünk - 2026 Október (Frissített tárgy)');
$nl->update();
// 3. Azonnali kiküldés:
$queued = $nl->send();
// Vagy ütemezett kiküldés holnap reggel 8-kor:
// $queued = $nl->send(strtotime('+1 day 08:00'));
if ($queued) {
echo 'Hírlevél sikeresen sorba állítva a kiküldéshez!';
}
}
// 4. Elérhető hírlevelek listázása
$allNewsletters = $nl->get();
} catch (InvalidArgumentException $e) {
echo 'Paraméterhiba: ' . $e->getMessage();
} catch (RuntimeException $e) {
echo 'Hiba a hírlevél művelet során: ' . $e->getMessage();
}
```
---
### Kampány kezelése
```php
$campaign = new ninjaMailCampaign('https://example.org', 'AZ_ON_API_KULCSA');
try {
// 1. Új kampány létrehozása
$campaignId = $campaign->create('Tavaszi Akció 2026');
if ($campaignId !== false) {
echo 'Kampány létrehozva, ID: ' . $campaignId . PHP_EOL;
// 2. Levelezőlisták hozzárendelése (lista azonosítók tömbje)
$campaign->update([12, 15]);
// 3. Hírlevél csatolása a kampányhoz
$campaign->attach(42);
// 4. Kampány törlése szükség esetén
// $campaign->remove();
}
} catch (InvalidArgumentException $e) {
echo 'Paraméterhiba: ' . $e->getMessage();
} catch (RuntimeException $e) {
echo 'Kampány hiba: ' . $e->getMessage();
}
```
---
### Statisztika lekérdezése
```php
$stats = new ninjaMailStatistics('https://example.org', 'AZ_ON_API_KULCSA');
try {
$newsletterId = 42;
$result = $stats->get($newsletterId);
print_r($result);
} catch (InvalidArgumentException $e) {
echo 'Érvénytelen hírlevél ID: ' . $e->getMessage();
} catch (RuntimeException $e) {
echo 'Statisztika lekérdezési hiba: ' . $e->getMessage();
}
```
-22
View File
@@ -1,22 +0,0 @@
<?php
include "ninjamail.class.php";
// Mail
$mail = new ninjaMailSend('https://admin.dimail.hu', 'API_KEY');
$mail->to('webmaster@example.org');
$mail->subject('Hello');
$mail->message('HTML_CONTENT', 'TEXT_CONTENT');
var_dump($mail->send());
// Newsletter
$newsletter = new ninjaMailNewsletter('https://admin.dimail.hu', 'API_KEY');
$newsletter->subject('New subject');
$newsletter->message('HTML_CONTENT', 'TEXT_CONTENT OR NULL');
if ($newsletter->update() && $newsletter->send())
echo "updated & sent\n";
// Stats
$stat = new ninjaMailStatistics('https://admin.dimail.hu', 'API_KEY');
print_r($stat->get(3512201));
-429
View File
@@ -1,429 +0,0 @@
# ninjaMail API
Ebben a dokumentumban megismerheti a levelező alkalmazásprogramozási interfészének használatát.
A példák PHP szemszögből készültek, de bármely nyelvből felhasználható, amely támogatja a cURL-t vagy GET/POST hívásokat.
---
## Bevezetés
Az API használatához regisztráció után API kulcsot kell generálni a **Beállítások → API** menüpontban.
A generált kulcsot tartsa titokban — a kulccsal a legtöbb funkció elérhető programozottan, beleértve feliratkozók hozzáadását és törlését is.
Webes bejelentkezésre az API kulcs önmagában nem alkalmas.
---
## API URL
A kulcsgenerálás után az API alap URL ugyanazon a felületen jelenik meg.
```
http://example.org/a/<gyár>?key=<kulcs>
```
| Elem | Leírás |
|-------------|-------------------------------------|
| `example.org` | A szolgáltató domainje |
| `<gyár>` | A funkciót kezelő végpont neve |
| `<kulcs>` | Az API hitelesítési kulcs |
> **Megjegyzés:** Éles környezetben mindig HTTPS-t használjon.
---
## Hibakezelés
A PHP kliens `RuntimeException`-t dob hálózati vagy JSON hibák esetén, `InvalidArgumentException`-t hiányzó vagy érvénytelen paraméterek esetén. Mindig try/catch blokkban hívja az API metódusokat:
```php
try {
$result = $mailer->send();
} catch (InvalidArgumentException $e) {
// hiányzó / érvénytelen paraméter
error_log($e->getMessage());
} catch (RuntimeException $e) {
// hálózati hiba, JSON hiba, hiányzó kulcs
error_log($e->getMessage());
}
```
---
## Végpontok
### Feliratkozó hozzáadása
**Gyár:** `subscribe`
```
POST: http://example.org/a/subscribe?key=<kulcs>
DATA: list=<id>&name=<Feliratkozó neve>&email=<E-mail>&activated=<1|0>
```
Az `activated` paraméter:
- `1` — a feliratkozó azonnal megerősítettként kerül rögzítésre
- `0` — megerősítő e-mail kerül kiküldésre a megadott címre
Opcionális: `forcenamechange=<1|0>` — meglévő feliratkozó nevének felülírása.
#### Várható válaszok
| Státusz | Leírás |
|-------------------|--------------------------------|
| `success` | Sikeres feliratkozás |
| `sub_error` | Sikertelen feliratkozás |
| `no_mx_record` | Nincs MX rekord (lehet átmeneti) |
| `bad_list` | Érvénytelen lista azonosító |
| `reg_error` | Sikertelen regisztráció |
---
### Feliratkozó eltávolítása
**Gyár:** `unsubscribe`
```
POST: http://example.org/a/unsubscribe?key=<kulcs>
DATA: list=<id>&email=<E-mail>
```
#### Várható válaszok
| Státusz | Leírás |
|------------------------|---------------------------------|
| `success` | Sikeres leiratkozás |
| `unsub_error` | Sikertelen leiratkozás |
| `unknown_email` | Ismeretlen e-mail cím |
| `missing_parameters` | Hiányzó paraméterek |
---
### Lista létrehozása
**Gyár:** `list`
```
POST: http://example.org/a/list?key=<kulcs>
DATA: new&name=<Lista neve>
```
#### Várható válaszok
| Státusz | Leírás |
|--------------|-----------------------|
| `success` | Sikeres létrehozás |
| `failed` | Sikertelen kérés |
| `bad_name` | Nem megfelelő név |
---
### Lista törlése
**Gyár:** `list`
```
POST: http://example.org/a/list?key=<kulcs>
DATA: remove&id=<Lista ID>
```
#### Várható válaszok
| Státusz | Leírás |
|-----------|--------------------|
| `success` | Sikeres törlés |
| `failed` | Sikertelen törlés |
---
### Listák lekérdezése
**Gyár:** `list`
```
POST: http://example.org/a/list?key=<kulcs>
DATA: get
```
#### Várható válasz
Sikeres kérés esetén a listák tömbje.
---
### Levél létrehozása
**Gyár:** `newsletter`
```
POST: http://example.org/a/newsletter?key=<kulcs>
DATA: new&subject=<Tárgy>&message=<HTML tartalom>&message_text=<Szöveges tartalom>
```
#### Várható válaszok
| Státusz | Leírás |
|------------------------|---------------------------|
| `success` + `id` | Sikeres létrehozás |
| `failed` | Sikertelen kérés |
| `bad_subject` | Érvénytelen tárgy |
| `message_too_powerful` | Túl hosszú üzenet |
| `message_too_short` | Túl rövid üzenet |
---
### Levél frissítése
**Gyár:** `newsletter`
```
POST: http://example.org/a/newsletter?key=<kulcs>
DATA: new&id=<Levél ID>&subject=<Tárgy>&message=<HTML tartalom>&message_text=<Szöveges tartalom>
```
#### Várható válaszok
Azonos a levél létrehozásával.
---
### Levél küldése
**Gyár:** `newsletter`
```
POST: http://example.org/a/newsletter?key=<kulcs>
DATA: send&id=<Levél ID>&start=<Unix timestamp vagy 0 azonnal>
```
#### Várható válaszok
| Státusz | Leírás |
|-------------------|--------------------------------|
| `success` | Sikeres sorbaállítás |
| `already_queued` | Már várólistán szerepel |
| `failed` | Sikertelen kérés |
---
### Levelek listázása
**Gyár:** `newsletter`
```
POST: http://example.org/a/newsletter?key=<kulcs>
DATA: get
```
#### Várható válasz
Sikeres kérés esetén a levelek tömbje.
---
### Kampány létrehozása
**Gyár:** `campaign`
```
POST: http://example.org/a/campaign?key=<kulcs>
DATA: new&name=<Kampány neve>
```
#### Várható válaszok
| Státusz | Leírás |
|------------------|----------------------|
| `success` + `id` | Sikeres létrehozás |
| `failed` | Sikertelen kérés |
---
### Kampány törlése
**Gyár:** `campaign`
```
POST: http://example.org/a/campaign?key=<kulcs>
DATA: remove&id=<Kampány ID>
```
#### Várható válaszok
| Státusz | Leírás |
|-----------|--------------------|
| `success` | Sikeres törlés |
| `failed` | Sikertelen törlés |
---
### Kampány frissítése (lista csatolás)
**Gyár:** `campaign`
```
POST: http://example.org/a/campaign?key=<kulcs>
DATA: update&id=<Kampány ID>&lists=<Lista ID-k tömbje>
```
#### Várható válaszok
| Státusz | Leírás |
|-----------|---------------------|
| `success` | Sikeres frissítés |
| `failed` | Sikertelen kérés |
---
### Kampány csatolása levélhez
**Gyár:** `campaign`
```
POST: http://example.org/a/campaign?key=<kulcs>
DATA: relations&campaign=<Kampány ID1,ID2,ID3>&newsletter=<Levél ID>
```
#### Várható válaszok
| Státusz | Leírás |
|-----------|-------------------|
| `success` | Sikeres csatolás |
| `failed` | Sikertelen kérés |
---
### E-mail küldése
Egyéni e-mail küldésére alkalmas. Nagy mennyiségű levélhez használja a `newsletter`, `list` és `campaign` gyárakat.
Ha a `message_text` üres, az értéke a HTML tartalom tag-ek nélküli változata lesz.
Az üzenet csak a HTML `<body>` tartalmát tartalmazza.
**Gyár:** `send`
```
POST: http://example.org/a/send?key=<kulcs>
DATA: to=<Feliratkozó ID vagy E-mail>&subject=<Tárgy>&message=<HTML tartalom>&message_text=<Szöveges tartalom>
```
#### Várható válaszok
| Státusz | Leírás |
|--------------------------|---------------------------------|
| `message_queued` + `id` | Sikeres sorbaállítás |
| `subscriber_not_found` | Ismeretlen feliratkozó |
| `subscriber_error` | Feliratkozó mentési hiba |
| `message_failed` | Sikertelen sorbaállítás |
| `quota_reached` | Csomagkorlát elérve |
| `missing_parameter` | Hiányzó paraméter |
---
### E-mail küldés ellenőrzése
A `send` gyáron keresztül küldött levelek állapotát kérdezi le: az olvasás időpontját, a küldés befejezésének idejét és sikerességét.
**Gyár:** `send`
```
GET: http://example.org/a/send?key=<kulcs>&just_asking=<id>
```
#### Várható válaszok
| Státusz | Mezők | Leírás |
|-----------|------------------------------------|---------------------------|
| `success` | `status`, `read`, `to`, `time` | Sikeres lekérdezés |
| `failed` | `status`, `read`, `to`, `time` | Sikertelen küldés |
| `wrong_id`| — | Érvénytelen azonosító |
---
### Statisztikák lekérdezése
**Gyár:** `statistics`
```
POST: http://example.org/a/statistics?key=<kulcs>
DATA: newsletter=<Levél ID>&type=1
```
#### Várható válasz
A hírlevél statisztikai adatait tartalmazó objektum.
---
### Belépés távolról
Lehetővé teszi az adminisztrációs felület elérését felhasználói név és jelszó megadása nélkül.
Az API egy egyszer használatos tokent ad vissza, amelyet böngészőből kell elküldeni a `http://example.org/` oldalra.
> **Biztonsági megjegyzés:** A PHP kliens `bin2hex(random_bytes(16))` segítségével generálja a véletlenszerű kulcsot — ne használjon gyengébb módszert (pl. `md5(time())`).
**Gyár:** `login`
```
POST: http://example.org/a/login?key=<kulcs>
DATA: rkey=<véletlenszerű string>
```
#### Várható válaszok
| Státusz | Leírás |
|---------------------|--------------------------------|
| `success` + `token` | Sikeres token generálás |
---
## PHP használati példák
### Feliratkozó hozzáadása
```php
$sub = new ninjaMailSubscription('https://example.org', 'az-api-kulcsom');
$sub->list(3);
$sub->activated(true);
try {
$ok = $sub->subscribe('pelda@email.hu', 'Kovács János');
echo $ok ? 'Sikeres feliratkozás' : 'Sikertelen feliratkozás';
} catch (RuntimeException $e) {
error_log($e->getMessage());
}
```
### E-mail küldése
```php
$mailer = new ninjaMailSend('https://example.org', 'az-api-kulcsom');
$mailer->to('pelda@email.hu');
$mailer->subject('Üdvözlünk!');
$mailer->message('<p>Szia!</p>');
try {
$ok = $mailer->send();
echo $ok ? 'Levél elküldve' : 'Küldés sikertelen';
} catch (InvalidArgumentException $e) {
echo 'Hiányzó mező: ' . $e->getMessage();
} catch (RuntimeException $e) {
error_log($e->getMessage());
}
```
### Hírlevél létrehozása és küldése
```php
$nl = new ninjaMailNewsletter('https://example.org', 'az-api-kulcsom');
$nl->subject('Havi összefoglaló');
$nl->message('<h1>Hírek</h1><p>Tartalom...</p>');
try {
$id = $nl->create();
if ($id) {
$nl->send(); // azonnali küldés
// $nl->send(strtotime('+1 day')); // ütemezett küldés
}
} catch (RuntimeException $e) {
error_log($e->getMessage());
}
```
-612
View File
@@ -1,612 +0,0 @@
<?php
declare(strict_types=1);
/**
* ninjaMail API kliens alaposztály
*
* Kezeli a HTTP kommunikációt a ninjaMail API végponttal.
*/
class ninjaMail
{
private string $host;
private string $key;
public ?object $data = null;
/** @var int cURL időtúllépés másodpercben */
private int $timeout = 15;
/**
* @param string $host Az API gazdagép alap URL-je (pl. https://example.org)
* @param string|bool $key API hitelesítési kulcs
*/
public function __construct(string $host, string|bool $key = false)
{
$this->host = rtrim($host, '/');
if ($key !== false && $key !== '') {
$this->key = (string)$key;
}
}
/**
* Ellenőrzi, hogy az API gazdagép és kulcs be van-e állítva.
*/
public function check(): bool
{
return !empty($this->host) && !empty($this->key);
}
/**
* POST kérést küld az API adott végpontjára.
*
* @param string $f A gyár/végpont neve (pl. 'subscribe')
* @param array $data POST mezők tömbje
* @return object A dekódolt JSON válasz objektumként
* @throws RuntimeException Ha hiányoznak a hitelesítési adatok, cURL hiba
* esetén, vagy ha a válasz nem érvényes JSON
*/
public function process(string $f, array $data): object
{
if (!$this->check()) {
throw new RuntimeException('ninjaMail: hiányzó gazdagép vagy API kulcs.');
}
$url = $this->host . '/a/' . rawurlencode($f) . '/?key=' . urlencode($this->key);
$ch = curl_init($url);
if ($ch === false) {
throw new RuntimeException('ninjaMail: nem sikerült inicializálni a cURL munkamenetet.');
}
curl_setopt_array($ch, [
CURLOPT_ENCODING => 'UTF-8',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_MAXREDIRS => 0,
CURLOPT_HTTPHEADER => ['Accept: application/json'],
]);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
if ($response === false) {
throw new RuntimeException(
sprintf('ninjaMail: cURL hiba (%d): %s', $errno, $error)
);
}
$decoded = json_decode((string)$response);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException(
'ninjaMail: érvénytelen JSON válasz: ' . json_last_error_msg()
);
}
$result = (object)$decoded;
$this->data = $result;
return $result;
}
/**
* Véletlenszerű kulccsal indít távoli belépési munkamenetet.
*
* @return object API válasz (tartalmaz 'token' mezőt siker esetén)
* @throws RuntimeException Lásd: process()
*/
public function login(): object
{
return $this->process('login', [
'rkey' => bin2hex(random_bytes(16)),
]);
}
}
// ---------------------------------------------------------------------------
// Levélküldés
// ---------------------------------------------------------------------------
/**
* Egyszeri e-mail küldése megadott címzettnek.
*/
class ninjaMailSend extends ninjaMail
{
private string $to = '';
private string $subject = '';
private string $message = '';
private string $message_text = '';
/**
* @param string $to Feliratkozó azonosítója vagy e-mail cím
*/
public function to(string $to): true
{
$this->to = trim($to);
return true;
}
/**
* @param string $s Az e-mail tárgya
*/
public function subject(string $s): true
{
$this->subject = $s;
return true;
}
/**
* @param string $m HTML tartalom
* @param string|bool $t Opcionális egyszerű szöveges változat;
* ha nincs megadva, a HTML-ből kerül levezetésre
*/
public function message(string $m, string|bool $t = false): true
{
$this->message = $m;
$this->message_text = ($t !== false && $t !== '')
? (string)$t
: trim(strip_tags($m));
return true;
}
/**
* Elküldi az e-mailt.
*
* @return bool true ha a levél sikeresen sorba állt
* @throws InvalidArgumentException Ha kötelező mező hiányzik
* @throws RuntimeException Lásd: process()
*/
public function send(): bool
{
if (empty($this->to) || empty($this->subject) || empty($this->message)) {
throw new InvalidArgumentException(
'ninjaMailSend: a to, subject és message mezők kötelezők.'
);
}
$post = [
'to' => $this->to,
'subject' => $this->subject,
'message' => $this->message,
'message_text' => $this->message_text,
];
return $this->process('send', $post)->status === 'message_queued';
}
}
// ---------------------------------------------------------------------------
// Feliratkozások
// ---------------------------------------------------------------------------
/**
* Feliratkozók hozzáadása és eltávolítása levelezőlistákból.
*/
class ninjaMailSubscription extends ninjaMail
{
private int $list = 0;
private int $activated = 0;
private int $forcenamechange = 0;
/**
* @param int $id Lista azonosítója
* @return bool false ha az azonosító nem pozitív egész szám
*/
public function list(int $id): bool
{
if ($id <= 0) {
return false;
}
$this->list = $id;
return true;
}
/**
* @param bool $s true = azonnal megerősített; false = megerősítő e-mail küldése
*/
public function activated(bool $s): true
{
$this->activated = $s ? 1 : 0;
return true;
}
/**
* @param bool $s true = névfrissítés engedélyezése meglévő feliratkozóknál
*/
public function namechange(bool $s): true
{
$this->forcenamechange = $s ? 1 : 0;
return true;
}
/**
* Feliratkozó hozzáadása a listához.
*
* @param string $email A feliratkozó e-mail címe
* @param string $name A feliratkozó neve (opcionális)
* @return bool true sikeres feliratkozás esetén
* @throws InvalidArgumentException Ha a lista nincs beállítva
* @throws RuntimeException Lásd: process()
*/
public function subscribe(string $email, string $name = ''): bool
{
if ($this->list <= 0) {
throw new InvalidArgumentException(
'ninjaMailSubscription: lista azonosítója nincs beállítva.'
);
}
$post = [
'list' => $this->list,
'name' => $name,
'email' => $email,
'activated' => $this->activated,
'forcenamechange' => $this->forcenamechange,
];
return $this->process('subscribe', $post)->status === 'success';
}
/**
* Feliratkozó eltávolítása a listából.
*
* @param string $email A leiratkozó e-mail címe
* @return bool true sikeres leiratkozás esetén
* @throws InvalidArgumentException Ha a lista nincs beállítva
* @throws RuntimeException Lásd: process()
*/
public function unsubscribe(string $email): bool
{
if ($this->list <= 0) {
throw new InvalidArgumentException(
'ninjaMailSubscription: lista azonosítója nincs beállítva.'
);
}
$post = [
'list' => $this->list,
'email' => $email,
];
return $this->process('unsubscribe', $post)->status === 'success';
}
}
// ---------------------------------------------------------------------------
// Hírlevél
// ---------------------------------------------------------------------------
/**
* Hírlevelek létrehozása, frissítése és küldése.
*/
class ninjaMailNewsletter extends ninjaMail
{
private int $newsletter = 0;
private string $subject = '';
private string $message = '';
private string $message_text = '';
/**
* Lekérdezi vagy beállítja az aktuális hírlevél azonosítóját.
*
* @param int|false $id Hírlevél azonosítója a beállításhoz; false = lekérdezés
* @return int|bool Lekérdezési módban az aktuális azonosítót adja vissza;
* beállítási módban true/false
*/
public function newsletter(int|false $id = false): int|bool
{
if ($id !== false) {
if ($id > 0) {
$this->newsletter = $id;
return true;
}
return false;
}
return $this->newsletter;
}
/**
* @param string $s A hírlevél tárgya
*/
public function subject(string $s): true
{
$this->subject = $s;
return true;
}
/**
* @param string $m HTML tartalom
* @param string|bool $t Opcionális egyszerű szöveges változat
*/
public function message(string $m, string|bool $t = false): true
{
$this->message = $m;
$this->message_text = ($t !== false && $t !== '')
? (string)$t
: trim(strip_tags($m));
return true;
}
/**
* @param bool $update true = meglévő frissítése; false = új létrehozása
* @return int|false Az új/frissített hírlevél azonosítója, vagy false hiba esetén
* @throws InvalidArgumentException Ha nincs üzenet beállítva
* @throws RuntimeException Lásd: process()
*/
private function query(bool $update = false): int|false
{
if (empty($this->message)) {
throw new InvalidArgumentException(
'ninjaMailNewsletter: az üzenet tartalma kötelező.'
);
}
$post = [
'new' => true,
'id' => $update ? $this->newsletter : false,
'subject' => $this->subject,
'message' => $this->message,
'message_text' => $this->message_text,
];
$data = $this->process('newsletter', $post);
if ($data->status === 'success' && isset($data->id) && is_numeric($data->id)) {
$this->newsletter = (int)$data->id;
return $this->newsletter;
}
return false;
}
/**
* Új hírlevelet hoz létre.
*
* @return int|false Az új hírlevél azonosítója, vagy false hiba esetén
*/
public function create(): int|false
{
return $this->query(false);
}
/**
* Meglévő hírlevelet frissít.
*
* @return int|false A hírlevél azonosítója, vagy false hiba esetén
* @throws InvalidArgumentException Ha nincs hírlevél kiválasztva
*/
public function update(): int|false
{
if ($this->newsletter <= 0) {
throw new InvalidArgumentException(
'ninjaMailNewsletter: hírlevél azonosítója nincs beállítva a frissítéshez.'
);
}
return $this->query(true);
}
/**
* Hírlevelet küld azonnali vagy ütemezett időpontban.
*
* @param int|false $time Unix időbélyeg a küldés időpontjához; false vagy 0 = azonnali
* @return bool true sikeres sorbaállítás esetén
* @throws InvalidArgumentException Ha nincs hírlevél kiválasztva
* @throws RuntimeException Lásd: process()
*/
public function send(int|false $time = false): bool
{
if ($this->newsletter <= 0) {
throw new InvalidArgumentException(
'ninjaMailNewsletter: hírlevél azonosítója nincs beállítva a küldéshez.'
);
}
$post = [
'send' => true,
'id' => $this->newsletter,
'start' => ($time && $time > 0) ? $time : 0,
];
$data = $this->process('newsletter', $post);
return in_array($data->status ?? '', ['success', 'already_queued'], true);
}
/**
* Listázza az elérhető híreveleket.
*
* @return object API válasz tömbbel
* @throws RuntimeException Lásd: process()
*/
public function get(): object
{
return $this->process('newsletter', ['get' => true]);
}
}
// ---------------------------------------------------------------------------
// Kampány
// ---------------------------------------------------------------------------
/**
* Kampányok létrehozása, törlése és konfigurálása.
*/
class ninjaMailCampaign extends ninjaMail
{
private int $campaign = 0;
/**
* Lekérdezi vagy beállítja az aktuális kampány azonosítóját.
*
* @param int|false $id Kampány azonosítója beállításhoz; false = lekérdezés
* @return int|bool Lekérdezési módban az aktuális azonosítót adja vissza;
* beállítási módban true/false
*/
public function campaign(int|false $id = false): int|bool
{
if ($id === false) {
return $this->campaign;
}
if ($id > 0) {
$this->campaign = $id;
return true;
}
return false;
}
/**
* Új kampányt hoz létre.
*
* @param string $name A kampány neve
* @return int|false Az új kampány azonosítója, vagy false hiba esetén
* @throws InvalidArgumentException Ha a név üres
* @throws RuntimeException Lásd: process()
*/
public function create(string $name): int|false
{
if (trim($name) === '') {
throw new InvalidArgumentException(
'ninjaMailCampaign: a kampány neve nem lehet üres.'
);
}
$post = [
'new' => true,
'name' => $name,
];
$data = $this->process('campaign', $post);
if ($data->status === 'success' && isset($data->id) && is_numeric($data->id)) {
$this->campaign = (int)$data->id;
return $this->campaign;
}
return false;
}
/**
* Törli az aktuális kampányt.
*
* @return bool true sikeres törlés esetén
* @throws InvalidArgumentException Ha nincs kampány kiválasztva
* @throws RuntimeException Lásd: process()
*/
public function remove(): bool
{
if ($this->campaign <= 0) {
throw new InvalidArgumentException(
'ninjaMailCampaign: kampány azonosítója nincs beállítva a törléshez.'
);
}
$post = [
'remove' => true,
'id' => $this->campaign,
];
return $this->process('campaign', $post)->status === 'success';
}
/**
* Listákat rendel a kampányhoz.
*
* @param int[] $lists Lista azonosítók tömbje
* @return bool true sikeres frissítés esetén
* @throws InvalidArgumentException Ha a $lists üres vagy nincs kampány beállítva
* @throws RuntimeException Lásd: process()
*/
public function update(array $lists): bool
{
if (empty($lists)) {
throw new InvalidArgumentException(
'ninjaMailCampaign: legalább egy lista azonosítója szükséges.'
);
}
if ($this->campaign <= 0) {
throw new InvalidArgumentException(
'ninjaMailCampaign: kampány azonosítója nincs beállítva a frissítéshez.'
);
}
$post = [
'update' => true,
'id' => $this->campaign,
'lists' => $lists,
];
return $this->process('campaign', $post)->status === 'success';
}
/**
* Hírlevelet csatol a kampányhoz.
*
* @param int $newsletter A csatolni kívánt hírlevél azonosítója
* @return bool true sikeres csatolás esetén
* @throws InvalidArgumentException Ha az azonosító érvénytelen vagy nincs kampány beállítva
* @throws RuntimeException Lásd: process()
*/
public function attach(int $newsletter): bool
{
if ($newsletter <= 0) {
throw new InvalidArgumentException(
'ninjaMailCampaign: érvénytelen hírlevél azonosító.'
);
}
if ($this->campaign <= 0) {
throw new InvalidArgumentException(
'ninjaMailCampaign: kampány azonosítója nincs beállítva a csatoláshoz.'
);
}
$post = [
'relations' => true,
'id' => $this->campaign,
'newsletter' => $newsletter,
];
return $this->process('campaign', $post)->status === 'success';
}
}
// ---------------------------------------------------------------------------
// Statisztika
// ---------------------------------------------------------------------------
/**
* Hírlevél-statisztikák lekérdezése.
*/
class ninjaMailStatistics extends ninjaMail
{
/**
* Statisztikát kér le egy adott hírlevélről.
*
* @param int $id A hírlevél azonosítója
* @return object Az API statisztikai válasza
* @throws InvalidArgumentException Ha az azonosító érvénytelen
* @throws RuntimeException Lásd: process()
*/
public function get(int $id): object
{
if ($id <= 0) {
throw new InvalidArgumentException(
'ninjaMailStatistics: érvénytelen hírlevél azonosító.'
);
}
$post = [
'newsletter' => $id,
'type' => 1,
];
return $this->process('statistics', $post);
}
}
+531 -239
View File
@@ -1,327 +1,619 @@
<?php
declare(strict_types=1);
/**
* ninjaMail API kliens alaposztály
*
* Kezeli a HTTP kommunikációt a ninjaMail API végponttal.
*/
class ninjaMail
{
private string $host = '';
private string $key = '';
public ?object $data = null;
private $host;
private $key;
public $data;
/** @var int cURL időtúllépés másodpercben */
private int $timeout = 15;
public function __construct($host, $key = false)
{
$this->host = $host;
if ($key) $this->key = $key;
}
/**
* @param string $host Az API gazdagép alap URL-je (pl. https://example.org)
* @param string|bool $key API hitelesítési kulcs
*/
public function __construct(string $host, string|bool $key = false)
{
$this->host = rtrim($host, '/');
if ($key !== false && $key !== '') {
$this->key = (string)$key;
}
}
public function check()
{
if (!$this->host || !$this->key)
return false;
return true;
}
/**
* Ellenőrzi, hogy az API gazdagép és kulcs be van-e állítva.
*/
public function check(): bool
{
return !empty($this->host) && !empty($this->key);
}
public function process($f, $data, $post_method = true)
{
$ch = curl_init($this->host.'/a/'.$f.'/?key='.$this->key);
curl_setopt($ch, CURLOPT_ENCODING, 'UTF-8');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$data = curl_exec($ch);
curl_close($ch);
/**
* POST kérést küld az API adott végpontjára.
*
* @param string $endpoint A végpont neve (pl. 'subscribe')
* @param array $data POST mezők tömbje
* @return object A dekódolt JSON válasz objektumként
* @throws RuntimeException Ha hiányoznak a hitelesítési adatok, cURL hiba
* esetén, vagy ha a válasz nem érvényes JSON
*/
public function process(string $endpoint, array $data): object
{
if (!$this->check()) {
throw new RuntimeException('ninjaMail: hiányzó gazdagép vagy API kulcs.');
}
$data = @(object)json_decode($data);
$this->data = $data;
return $data;
}
$url = $this->host . '/a/' . rawurlencode($endpoint) . '/?key=' . urlencode($this->key);
public function login()
{
return $this->process('login', ['rkey' => md5(time().rand(0,65500).rand(0,10))]);
}
$ch = curl_init($url);
if ($ch === false) {
throw new RuntimeException('ninjaMail: nem sikerült inicializálni a cURL munkamenetet.');
}
curl_setopt_array($ch, [
CURLOPT_ENCODING => 'UTF-8',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => is_array($data) ? http_build_query($data) : $data,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_MAXREDIRS => 0,
CURLOPT_HTTPHEADER => ['Accept: application/json'],
]);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
if ($response === false) {
throw new RuntimeException(
sprintf('ninjaMail: cURL hiba (%d): %s', $errno, $error)
);
}
$responseStr = trim((string)$response);
if ($responseStr === '') {
$result = (object)[];
$this->data = $result;
return $result;
}
$decoded = json_decode($responseStr);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException(
'ninjaMail: érvénytelen JSON válasz: ' . json_last_error_msg()
);
}
$result = (object)$decoded;
$this->data = $result;
return $result;
}
/**
* Véletlenszerű kulccsal indít távoli belépési munkamenetet.
*
* @return object API válasz (tartalmaz 'token' mezőt siker esetén)
* @throws RuntimeException Lásd: process()
*/
public function login(): object
{
return $this->process('login', [
'rkey' => bin2hex(random_bytes(16)),
]);
}
}
// Send Email
// ---------------------------------------------------------------------------
// Levélküldés
// ---------------------------------------------------------------------------
/**
* Egyszeri e-mail küldése megadott címzettnek.
*/
class ninjaMailSend extends ninjaMail
{
private string $to = '';
private string $subject = '';
private string $message = '';
private string $message_text = '';
private $to;
private $subject;
private $message;
private $message_text;
public function to($to)
/**
* @param string $to Feliratkozó azonosítója vagy e-mail cím
*/
public function to(string $to): true
{
$this->to = $to;
return true;
$this->to = trim($to);
return true;
}
public function subject($s)
/**
* @param string $s Az e-mail tárgya
*/
public function subject(string $s): true
{
$this->subject = $s;
return true;
$this->subject = $s;
return true;
}
public function message($m, $t = false)
/**
* @param string $m HTML tartalom
* @param string|bool $t Opcionális egyszerű szöveges változat;
* ha nincs megadva, a HTML-ből kerül levezetésre
*/
public function message(string $m, string|bool $t = false): true
{
$this->message = $m;
if (!$t) $this->message_text = trim(strip_tags($m));
else $this->message_text = $t;
return true;
$this->message = $m;
$this->message_text = ($t !== false && $t !== '')
? (string)$t
: trim(strip_tags($m));
return true;
}
public function send()
/**
* Elküldi az e-mailt.
*
* @return bool true ha a levél sikeresen sorba állt
* @throws InvalidArgumentException Ha kötelező mező hiányzik
* @throws RuntimeException Lásd: process()
*/
public function send(): bool
{
$post = [
'to' => $this->to,
'subject' => $this->subject,
'message' => $this->message,
'message_text' => $this->message_text
];
return $this->process('send', $post, true)->status == 'message_queued' ? true : false;
if (empty($this->to) || empty($this->subject) || empty($this->message)) {
throw new InvalidArgumentException(
'ninjaMailSend: a to, subject és message mezők kötelezők.'
);
}
$post = [
'to' => $this->to,
'subject' => $this->subject,
'message' => $this->message,
'message_text' => $this->message_text,
];
return ($this->process('send', $post)->status ?? '') === 'message_queued';
}
}
// Subscribe
// ---------------------------------------------------------------------------
// Feliratkozások
// ---------------------------------------------------------------------------
/**
* Feliratkozók hozzáadása és eltávolítása levelezőlistákból.
*/
class ninjaMailSubscription extends ninjaMail
{
private int $list = 0;
private int $activated = 0;
private int $forcenamechange = 0;
private $list;
private $activated = 0;
private $forcenamechange = 0;
public function list($id)
/**
* @param int $id Lista azonosítója
* @return bool false ha az azonosító nem pozitív egész szám
*/
public function list(int $id): bool
{
if (is_numeric($id))
{
$this->list = $id;
return true;
}
return false;
if ($id <= 0) {
return false;
}
$this->list = $id;
return true;
}
public function activated($s)
/**
* @param bool $s true = azonnal megerősített; false = megerősítő e-mail küldése
*/
public function activated(bool $s): true
{
if ($s) $this->activated = 1;
else $this->activated = 0;
return true;
$this->activated = $s ? 1 : 0;
return true;
}
public function namechange($s)
{
if ($s) $this->forcenamechange = 1;
else $this->forcenamechange = 0;
return true;
}
public function subscribe($email, $name = '')
/**
* @param bool $s true = névfrissítés engedélyezése meglévő feliratkozóknál
*/
public function namechange(bool $s): true
{
if (!$this->list || !is_numeric($this->activated))
return false;
$post = [
'list' => $this->list,
'name' => $name,
'email' => $email,
'activated' => $this->activated,
'forcenamechange' => $this->forcenamechange
];
return $this->process('subscribe', $post, true)->status == 'success' ? true : false;
$this->forcenamechange = $s ? 1 : 0;
return true;
}
public function unsubscribe($email)
/**
* Feliratkozó hozzáadása a listához.
*
* @param string $email A feliratkozó e-mail címe
* @param string $name A feliratkozó neve (opcionális)
* @return bool true sikeres feliratkozás esetén
* @throws InvalidArgumentException Ha a lista nincs beállítva
* @throws RuntimeException Lásd: process()
*/
public function subscribe(string $email, string $name = ''): bool
{
if (!$this->list)
return false;
if ($this->list <= 0) {
throw new InvalidArgumentException(
'ninjaMailSubscription: lista azonosítója nincs beállítva.'
);
}
$post = [
'list' => $this->list,
'email' => $email
];
return $this->process('unsubscribe', $post, true)->status == 'success' ? true : false;
$post = [
'list' => $this->list,
'name' => $name,
'email' => $email,
'activated' => $this->activated,
'forcenamechange' => $this->forcenamechange,
];
return ($this->process('subscribe', $post)->status ?? '') === 'success';
}
/**
* Feliratkozó eltávolítása a listából.
*
* @param string $email A leiratkozó e-mail címe
* @return bool true sikeres leiratkozás esetén
* @throws InvalidArgumentException Ha a lista nincs beállítva
* @throws RuntimeException Lásd: process()
*/
public function unsubscribe(string $email): bool
{
if ($this->list <= 0) {
throw new InvalidArgumentException(
'ninjaMailSubscription: lista azonosítója nincs beállítva.'
);
}
$post = [
'list' => $this->list,
'email' => $email,
];
return ($this->process('unsubscribe', $post)->status ?? '') === 'success';
}
}
// Newsletter
// ---------------------------------------------------------------------------
// Hírlevél
// ---------------------------------------------------------------------------
/**
* Hírlevelek létrehozása, frissítése és küldése.
*/
class ninjaMailNewsletter extends ninjaMail
{
private int $newsletter = 0;
private string $subject = '';
private string $message = '';
private string $message_text = '';
private $newsletter;
private $subject;
private $message;
private $message_text;
public function newsletter($id = false)
{
if (is_numeric($id))
{
$this->newsletter = $id;
return true;
}
return $this->newsletter;
}
public function subject($s)
/**
* Lekérdezi vagy beállítja az aktuális hírlevél azonosítóját.
*
* @param int|false $id Hírlevél azonosítója a beállításhoz; false = lekérdezés
* @return int|bool Lekérdezési módban az aktuális azonosítót adja vissza;
* beállítási módban true/false
*/
public function newsletter(int|false $id = false): int|bool
{
$this->subject = $s;
return true;
if ($id !== false) {
if ($id > 0) {
$this->newsletter = $id;
return true;
}
return false;
}
return $this->newsletter;
}
public function message($m, $t = false)
/**
* @param string $s A hírlevél tárgya
*/
public function subject(string $s): true
{
$this->message = $m;
if (!$t) $this->message_text = trim(strip_tags($m));
else $this->message_text = $t;
return true;
$this->subject = $s;
return true;
}
public function query($update = false)
{
if (!$this->message)
return false;
/**
* @param string $m HTML tartalom
* @param string|bool $t Opcionális egyszerű szöveges változat
*/
public function message(string $m, string|bool $t = false): true
{
$this->message = $m;
$this->message_text = ($t !== false && $t !== '')
? (string)$t
: trim(strip_tags($m));
return true;
}
$post = [
'new' => true,
'id' => $update ? $this->newsletter : false,
'subject' => $this->subject,
'message' => $this->message,
'message_text' => $this->message_text
];
$data = $this->process('newsletter', $post, true);
if ($data->status == 'success')
{
$this->newsletter = $data->id;
return $data->id;
}
return false;
}
/**
* @param bool $update true = meglévő frissítése; false = új létrehozása
* @return int|false Az új/frissített hírlevél azonosítója, vagy false hiba esetén
* @throws InvalidArgumentException Ha nincs üzenet beállítva
* @throws RuntimeException Lásd: process()
*/
private function query(bool $update = false): int|false
{
if (empty($this->message)) {
throw new InvalidArgumentException(
'ninjaMailNewsletter: az üzenet tartalma kötelező.'
);
}
public function create()
{
return $this->query(false);
}
$post = [
'new' => true,
'id' => $update ? $this->newsletter : false,
'subject' => $this->subject,
'message' => $this->message,
'message_text' => $this->message_text,
];
public function update()
{
if (!$this->newsletter)
return false;
$data = $this->process('newsletter', $post);
if (($data->status ?? '') === 'success' && isset($data->id) && is_numeric($data->id)) {
$this->newsletter = (int)$data->id;
return $this->newsletter;
}
return $this->query(true);
}
return false;
}
public function send($time = false)
{
if (!$this->newsletter)
return false;
/**
* Új hírlevelet hoz létre.
*
* @return int|false Az új hírlevél azonosítója, vagy false hiba esetén
*/
public function create(): int|false
{
return $this->query(false);
}
$post = [
'send' => true,
'id' => $this->newsletter,
'start' => $time ? $time : 0
];
$data = $this->process('newsletter', $post, true);
if ($data->status == 'success' || $this->status == 'already_queued')
return true;
/**
* Meglévő hírlevelet frissít.
*
* @return int|false A hírlevél azonosítója, vagy false hiba esetén
* @throws InvalidArgumentException Ha nincs hírlevél kiválasztva
*/
public function update(): int|false
{
if ($this->newsletter <= 0) {
throw new InvalidArgumentException(
'ninjaMailNewsletter: hírlevél azonosítója nincs beállítva a frissítéshez.'
);
}
return $this->query(true);
}
return false;
}
/**
* Hírlevelet küld azonnali vagy ütemezett időpontban.
*
* @param int|false $time Unix időbélyeg a küldés időpontjához; false vagy 0 = azonnali
* @return bool true sikeres sorbaállítás esetén
* @throws InvalidArgumentException Ha nincs hírlevél kiválasztva
* @throws RuntimeException Lásd: process()
*/
public function send(int|false $time = false): bool
{
if ($this->newsletter <= 0) {
throw new InvalidArgumentException(
'ninjaMailNewsletter: hírlevél azonosítója nincs beállítva a küldéshez.'
);
}
public function get()
{
return $this->process('newsletter', ['get' => true], true);
}
$post = [
'send' => true,
'id' => $this->newsletter,
'start' => ($time && $time > 0) ? $time : 0,
];
$data = $this->process('newsletter', $post);
return in_array($data->status ?? '', ['success', 'already_queued'], true);
}
/**
* Listázza az elérhető híreveleket.
*
* @return object API válasz tömbbel
* @throws RuntimeException Lásd: process()
*/
public function get(): object
{
return $this->process('newsletter', ['get' => true]);
}
}
// Campaign
// ---------------------------------------------------------------------------
// Kampány
// ---------------------------------------------------------------------------
/**
* Kampányok létrehozása, törlése és konfigurálása.
*/
class ninjaMailCampaign extends ninjaMail
{
private $campaign;
private int $campaign = 0;
public function campaign($id = false)
{
if (!$id)
return $this->campaign;
/**
* Lekérdezi vagy beállítja az aktuális kampány azonosítóját.
*
* @param int|false $id Kampány azonosítója beállításhoz; false = lekérdezés
* @return int|bool Lekérdezési módban az aktuális azonosítót adja vissza;
* beállítási módban true/false
*/
public function campaign(int|false $id = false): int|bool
{
if ($id === false) {
return $this->campaign;
}
if ($id > 0) {
$this->campaign = $id;
return true;
}
return false;
}
if (is_numeric($id))
{
$this->campaign = $id;
return true;
}
return false;
}
/**
* Új kampányt hoz létre.
*
* @param string $name A kampány neve
* @return int|false Az új kampány azonosítója, vagy false hiba esetén
* @throws InvalidArgumentException Ha a név üres
* @throws RuntimeException Lásd: process()
*/
public function create(string $name): int|false
{
if (trim($name) === '') {
throw new InvalidArgumentException(
'ninjaMailCampaign: a kampány neve nem lehet üres.'
);
}
public function create($name)
{
$post = [
'new' => true,
'name' => $name
];
$data = $this->process('campaign', $post, true);
if ($data->status == 'success')
{
$this->campaign = $data->id;
return $data->id;
}
$post = [
'new' => true,
'name' => $name,
];
return false;
}
$data = $this->process('campaign', $post);
if (($data->status ?? '') === 'success' && isset($data->id) && is_numeric($data->id)) {
$this->campaign = (int)$data->id;
return $this->campaign;
}
public function remove()
{
$post = [
'remove' => true,
'id' => $this->campaign
];
return $this->process('campaign', $post, true)->status == 'success' ? true : false;
}
return false;
}
public function update($lists)
{
if (!is_array($lists))
return false;
/**
* Törli az aktuális kampányt.
*
* @return bool true sikeres törlés esetén
* @throws InvalidArgumentException Ha nincs kampány kiválasztva
* @throws RuntimeException Lásd: process()
*/
public function remove(): bool
{
if ($this->campaign <= 0) {
throw new InvalidArgumentException(
'ninjaMailCampaign: kampány azonosítója nincs beállítva a törléshez.'
);
}
$post = [
'update' => true,
'id' => $this->campaign,
'lists' => $lists
];
return $this->process('campaign', $post, true)->status == 'success' ? true : false;
}
$post = [
'remove' => true,
'id' => $this->campaign,
];
public function attach($newsletter)
{
if (!is_numeric($newsletter))
return false;
return ($this->process('campaign', $post)->status ?? '') === 'success';
}
$post = [
'relations' => true,
'id' => $this->campaign,
'newsletter' => $newsletter
];
return $this->process('campaign', $post, true)->status == 'success' ? true : false;
}
/**
* Listákat rendel a kampányhoz.
*
* @param int[] $lists Lista azonosítók tömbje
* @return bool true sikeres frissítés esetén
* @throws InvalidArgumentException Ha a $lists üres vagy nincs kampány beállítva
* @throws RuntimeException Lásd: process()
*/
public function update(array $lists): bool
{
if (empty($lists)) {
throw new InvalidArgumentException(
'ninjaMailCampaign: legalább egy lista azonosítója szükséges.'
);
}
if ($this->campaign <= 0) {
throw new InvalidArgumentException(
'ninjaMailCampaign: kampány azonosítója nincs beállítva a frissítéshez.'
);
}
$post = [
'update' => true,
'id' => $this->campaign,
'lists' => $lists,
];
return ($this->process('campaign', $post)->status ?? '') === 'success';
}
/**
* Hírlevelet csatol a kampányhoz.
*
* @param int $newsletter A csatolni kívánt hírlevél azonosítója
* @return bool true sikeres csatolás esetén
* @throws InvalidArgumentException Ha az azonosító érvénytelen vagy nincs kampány beállítva
* @throws RuntimeException Lásd: process()
*/
public function attach(int $newsletter): bool
{
if ($newsletter <= 0) {
throw new InvalidArgumentException(
'ninjaMailCampaign: érvénytelen hírlevél azonosító.'
);
}
if ($this->campaign <= 0) {
throw new InvalidArgumentException(
'ninjaMailCampaign: kampány azonosítója nincs beállítva a csatoláshoz.'
);
}
$post = [
'relations' => true,
'campaign' => $this->campaign,
'id' => $this->campaign,
'newsletter' => $newsletter,
];
return ($this->process('campaign', $post)->status ?? '') === 'success';
}
}
// Statistics
// ---------------------------------------------------------------------------
// Statisztika
// ---------------------------------------------------------------------------
/**
* Hírlevél-statisztikák lekérdezése.
*/
class ninjaMailStatistics extends ninjaMail
{
/**
* Statisztikát kér le egy adott hírlevélről.
*
* @param int $id A hírlevél azonosítója
* @return object Az API statisztikai válasza
* @throws InvalidArgumentException Ha az azonosító érvénytelen
* @throws RuntimeException Lásd: process()
*/
public function get(int $id): object
{
if ($id <= 0) {
throw new InvalidArgumentException(
'ninjaMailStatistics: érvénytelen hírlevél azonosító.'
);
}
public function get($id)
{
if (!is_numeric($id))
return false;
$post = [
'newsletter' => $id,
'type' => 1
];
return $this->process('statistics', $post, true);
}
$post = [
'newsletter' => $id,
'type' => 1,
];
return $this->process('statistics', $post);
}
}
+214
View File
@@ -0,0 +1,214 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/ninjamail.class.php';
/**
* ninjaMail API teljes körű tesztelő szkript
*
* Anonimizált tesztkörnyezet. Valós környezetben a konfiguráció
* a NINJAMAIL_HOST és NINJAMAIL_KEY környezeti változókon keresztül
* vagy az alábbi változók megadásával állítható be.
*/
$host = getenv('NINJAMAIL_HOST') ?: 'https://example.org';
$key = getenv('NINJAMAIL_KEY') ?: '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
$testEmail = 'teszt.felhasznalo@example.com';
$sendEmail = 'cimzett@example.com';
echo "====================================================\n";
echo "ninjaMail API funkciók tesztelése\n";
echo "Host: $host\n";
echo "Key: " . substr($key, 0, 8) . "..." . substr($key, -8) . "\n";
echo "====================================================\n\n";
// ---------------------------------------------------------------------------
// 1. Alaposztály
// ---------------------------------------------------------------------------
echo "=== 1. ninjaMail ALAPOSZTÁLY TESZTELÉSE ===\n";
$base = new ninjaMail($host, $key);
echo "[+] check(): ";
var_dump($base->check());
echo "[+] login(): ";
try {
$login = $base->login();
echo json_encode($login, JSON_UNESCAPED_UNICODE) . "\n";
} catch (Throwable $e) {
echo "Hiba: " . $e->getMessage() . "\n";
}
// ---------------------------------------------------------------------------
// 2. Lista műveletek
// ---------------------------------------------------------------------------
echo "\n=== 2. LISTA MŰVELETEK (ninjaMail::process) ===\n";
$listId = null;
try {
echo "[+] Lista létrehozása (list -> new): ";
$createdList = $base->process('list', ['new' => true, 'name' => 'Teszt Lista 2026']);
echo json_encode($createdList, JSON_UNESCAPED_UNICODE) . "\n";
$listId = $createdList->id ?? null;
echo "[+] Listák lekérdezése (list -> get): ";
$lists = $base->process('list', ['get' => true]);
echo json_encode($lists, JSON_UNESCAPED_UNICODE) . "\n";
} catch (Throwable $e) {
echo "Hiba: " . $e->getMessage() . "\n";
}
// ---------------------------------------------------------------------------
// 3. Feliratkozások
// ---------------------------------------------------------------------------
echo "\n=== 3. ninjaMailSubscription TESZTELÉSE ===\n";
$sub = new ninjaMailSubscription($host, $key);
$activeListId = $listId ? (int)$listId : 1;
echo "[+] list($activeListId): ";
var_dump($sub->list($activeListId));
echo "[+] activated(true): ";
var_dump($sub->activated(true));
echo "[+] namechange(true): ";
var_dump($sub->namechange(true));
try {
echo "[+] subscribe(\"$testEmail\", \"Teszt Elek\"): ";
$subRes = $sub->subscribe($testEmail, 'Teszt Elek');
var_dump($subRes);
echo " Válasz: " . json_encode($sub->data, JSON_UNESCAPED_UNICODE) . "\n";
echo "[+] unsubscribe(\"$testEmail\"): ";
$unsubRes = $sub->unsubscribe($testEmail);
var_dump($unsubRes);
echo " Válasz: " . json_encode($sub->data, JSON_UNESCAPED_UNICODE) . "\n";
} catch (Throwable $e) {
echo "Hiba: " . $e->getMessage() . "\n";
}
// ---------------------------------------------------------------------------
// 4. Hírlevelek
// ---------------------------------------------------------------------------
echo "\n=== 4. ninjaMailNewsletter TESZTELÉSE ===\n";
$nl = new ninjaMailNewsletter($host, $key);
echo "[+] subject(): ";
var_dump($nl->subject('Rendszertesztek 2026 - Hírlevél'));
echo "[+] message(): ";
$longContent = '<h1>Kedves Feliratkozónk!</h1><p>Ez egy hivatalos teszt hírlevél, amely a ninjaMail API funkcionalitását teszteli. A hírlevél tartalma megfelelően hosszú szöveget tartalmaz, hogy teljesítse a rendszer tartalmi és formai követelményeit. További információkért látogasson el weboldalunkra vagy keresse ügyfélszolgálatunkat.</p><p>Üdvözlettel,<br>A rendszer üzemeltetője</p>';
var_dump($nl->message($longContent));
$newsletterId = null;
try {
echo "[+] create(): ";
$newsletterId = $nl->create();
var_dump($newsletterId);
echo " Válasz: " . json_encode($nl->data, JSON_UNESCAPED_UNICODE) . "\n";
echo "[+] newsletter() getter: ";
var_dump($nl->newsletter());
echo "[+] update(): ";
$nl->subject('Rendszertesztek 2026 - Frissített hírlevél tárgy');
$nlUp = $nl->update();
var_dump($nlUp);
echo " Válasz: " . json_encode($nl->data, JSON_UNESCAPED_UNICODE) . "\n";
echo "[+] get(): ";
$allNl = $nl->get();
echo json_encode($allNl, JSON_UNESCAPED_UNICODE) . "\n";
echo "[+] send() (időzítve +1 évre): ";
$sendNl = $nl->send(strtotime('+1 year'));
var_dump($sendNl);
echo " Válasz: " . json_encode($nl->data, JSON_UNESCAPED_UNICODE) . "\n";
} catch (Throwable $e) {
echo "Hiba: " . $e->getMessage() . "\n";
}
// ---------------------------------------------------------------------------
// 5. Kampányok
// ---------------------------------------------------------------------------
echo "\n=== 5. ninjaMailCampaign TESZTELÉSE ===\n";
$camp = new ninjaMailCampaign($host, $key);
$campaignId = null;
try {
echo "[+] create(\"API Teszt Kampány\"): ";
$campaignId = $camp->create('API Teszt Kampány');
var_dump($campaignId);
echo " Válasz: " . json_encode($camp->data, JSON_UNESCAPED_UNICODE) . "\n";
echo "[+] campaign() getter: ";
var_dump($camp->campaign());
echo "[+] update() (lista csatolása): ";
$campUp = $camp->update([(int)$activeListId]);
var_dump($campUp);
echo " Válasz: " . json_encode($camp->data, JSON_UNESCAPED_UNICODE) . "\n";
echo "[+] attach(" . ($newsletterId ?? 1) . ") (hírlevél csatolása): ";
$campAtt = $camp->attach((int)($newsletterId ?? 1));
var_dump($campAtt);
echo " Válasz: " . json_encode($camp->data, JSON_UNESCAPED_UNICODE) . "\n";
echo "[+] remove() (kampány törlése): ";
$campRem = $camp->remove();
var_dump($campRem);
echo " Válasz: " . json_encode($camp->data, JSON_UNESCAPED_UNICODE) . "\n";
} catch (Throwable $e) {
echo "Hiba: " . $e->getMessage() . "\n";
}
// ---------------------------------------------------------------------------
// 6. Egyedi levélküldés
// ---------------------------------------------------------------------------
echo "\n=== 6. ninjaMailSend TESZTELÉSE ===\n";
$sender = new ninjaMailSend($host, $key);
echo "[+] to(\"$sendEmail\"): ";
var_dump($sender->to($sendEmail));
echo "[+] subject(): ";
var_dump($sender->subject('Tranzakciós teszt e-mail'));
echo "[+] message(): ";
var_dump($sender->message('<p>Ez egy egyedi tranzakciós teszt e-mail.</p>'));
try {
echo "[+] send(): ";
$sendRes = $sender->send();
var_dump($sendRes);
echo " Válasz: " . json_encode($sender->data, JSON_UNESCAPED_UNICODE) . "\n";
} catch (Throwable $e) {
echo "Hiba: " . $e->getMessage() . "\n";
}
// ---------------------------------------------------------------------------
// 7. Statisztika
// ---------------------------------------------------------------------------
echo "\n=== 7. ninjaMailStatistics TESZTELÉSE ===\n";
$stat = new ninjaMailStatistics($host, $key);
try {
$statNlId = (int)($newsletterId ?? 1);
echo "[+] get($statNlId): ";
$statRes = $stat->get($statNlId);
echo json_encode($statRes, JSON_UNESCAPED_UNICODE) . "\n";
} catch (Throwable $e) {
echo "Hiba: " . $e->getMessage() . "\n";
}
// ---------------------------------------------------------------------------
// 8. Takarítás (ha hoztunk létre listát)
// ---------------------------------------------------------------------------
if ($listId) {
echo "\n=== 8. TAKARÍTÁS (Teszt lista törlése) ===\n";
try {
echo "[+] remove list $listId: ";
$delList = $base->process('list', ['remove' => true, 'id' => $listId]);
echo json_encode($delList, JSON_UNESCAPED_UNICODE) . "\n";
} catch (Throwable $e) {
echo "Hiba: " . $e->getMessage() . "\n";
}
}
echo "\nTesztelés befejezve.\n";
+160
View File
@@ -0,0 +1,160 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/../ninjamail.class.php';
echo "=== ninjaMail PHP érvényesség és típusvizsgálat ===\n";
$passed = 0;
$failed = 0;
function runTest(string $description, callable $fn): void {
global $passed, $failed;
try {
$fn();
echo " [OK] $description\n";
$passed++;
} catch (Throwable $e) {
echo " [FAIL] $description: " . $e->getMessage() . "\n";
$failed++;
}
}
// 1. ninjaMail alaposztály
runTest("ninjaMail inicializálás és check()", function () {
$api = new ninjaMail('https://example.org', 'test-key');
assert($api->check() === true, "check() igaz kell legyen érvényes adatokkal");
$apiNoKey = new ninjaMail('https://example.org');
assert($apiNoKey->check() === false, "check() hamis kell legyen hiányzó kulccsal");
});
// 2. ninjaMailSend
runTest("ninjaMailSend metódusok és kötelező mezők validációja", function () {
$s = new ninjaMailSend('https://example.org', 'test-key');
assert($s->to('user@example.com') === true);
assert($s->subject('Teszt tárgy') === true);
assert($s->message('<b>HTML</b>', 'Szöveg') === true);
$emptySender = new ninjaMailSend('https://example.org', 'test-key');
try {
$emptySender->send();
throw new Exception("Nem dobott kivételt hiányzó mezők esetén");
} catch (InvalidArgumentException $e) {
// Sikeres teszt, elvárt kivétel
}
});
// 3. ninjaMailSubscription
runTest("ninjaMailSubscription beállítások és lista validáció", function () {
$sub = new ninjaMailSubscription('https://example.org', 'test-key');
assert($sub->list(10) === true);
assert($sub->list(0) === false);
assert($sub->list(-5) === false);
assert($sub->activated(true) === true);
assert($sub->namechange(true) === true);
$emptySub = new ninjaMailSubscription('https://example.org', 'test-key');
try {
$emptySub->subscribe('user@example.com');
throw new Exception("Nem dobott kivételt hiányzó lista esetén");
} catch (InvalidArgumentException $e) {
// Sikeres teszt
}
try {
$emptySub->unsubscribe('user@example.com');
throw new Exception("Nem dobott kivételt hiányzó lista esetén");
} catch (InvalidArgumentException $e) {
// Sikeres teszt
}
});
// 4. ninjaMailNewsletter
runTest("ninjaMailNewsletter hírlevél azonosító és üzenet validáció", function () {
$nl = new ninjaMailNewsletter('https://example.org', 'test-key');
assert($nl->subject('Tárgy') === true);
assert($nl->message('Tartalom') === true);
assert($nl->newsletter(25) === true);
assert($nl->newsletter() === 25);
assert($nl->newsletter(0) === false);
$emptyNl = new ninjaMailNewsletter('https://example.org', 'test-key');
try {
$emptyNl->create();
throw new Exception("Nem dobott kivételt üres üzenetnél");
} catch (InvalidArgumentException $e) {
// Sikeres teszt
}
try {
$emptyNl->update();
throw new Exception("Nem dobott kivételt hírlevél ID nélkül");
} catch (InvalidArgumentException $e) {
// Sikeres teszt
}
try {
$emptyNl->send();
throw new Exception("Nem dobott kivételt hírlevél ID nélkül");
} catch (InvalidArgumentException $e) {
// Sikeres teszt
}
});
// 5. ninjaMailCampaign
runTest("ninjaMailCampaign kampány validáció", function () {
$camp = new ninjaMailCampaign('https://example.org', 'test-key');
assert($camp->campaign(40) === true);
assert($camp->campaign() === 40);
assert($camp->campaign(0) === false);
try {
$camp->create('');
throw new Exception("Nem dobott kivételt üres névnél");
} catch (InvalidArgumentException $e) {
// Sikeres teszt
}
$emptyCamp = new ninjaMailCampaign('https://example.org', 'test-key');
try {
$emptyCamp->remove();
throw new Exception("Nem dobott kivételt kampány ID nélkül");
} catch (InvalidArgumentException $e) {
// Sikeres teszt
}
try {
$camp->update([]);
throw new Exception("Nem dobott kivételt üres listánál");
} catch (InvalidArgumentException $e) {
// Sikeres teszt
}
try {
$camp->attach(0);
throw new Exception("Nem dobott kivételt érvénytelen hírlevél ID-nél");
} catch (InvalidArgumentException $e) {
// Sikeres teszt
}
});
// 6. ninjaMailStatistics
runTest("ninjaMailStatistics azonosító validáció", function () {
$stat = new ninjaMailStatistics('https://example.org', 'test-key');
try {
$stat->get(0);
throw new Exception("Nem dobott kivételt 0 azonosítónál");
} catch (InvalidArgumentException $e) {
// Sikeres teszt
}
});
echo "\nTeszt összefoglaló: $passed sikeres, $failed sikertelen.\n";
if ($failed > 0) {
exit(1);
}
exit(0);