Add ng/ninjamail.class.php
This commit is contained in:
@@ -0,0 +1,612 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user