الأدوات المساعدة والثوابت
ما تعرّفه الحزمة غير توابع العميل.
التوابع الساكنة
| الطريقة | ما هي |
|---|---|
| OpenEmail::init(), OpenEmail::getClient() | هيّئ العميل المشترك مرة واحدة، ثم صِل إليه من أي مكان. ويبني getClient() عميلًا من بيئة التشغيل إن لم يُنفَّذ init قط. |
| OpenEmail::resetClient() | يتخلّص من العميل المشترك، فيبني getClient() التالي عميلًا جديدًا، وهو ما يريده الاختبار بين الحالات. |
| new OpenEmail(), OpenEmail::createClient() | عميل منفصل. وكلاهما يقرأ من البيئة كل ما تتركه. |
| OpenEmail::createTempMail() | عميل لصناديق البريد المؤقتة لا يحمل أي مفتاح API. |
| OpenEmail::verifyWebhookSignature() | يفحص توقيع التسليم بزمن ثابت، مع نافذة لمنع إعادة التشغيل مدتها خمس دقائق يغيّرها toleranceSeconds:. ويعيد الحدث بعد فكّ ترميزه، ويرمي WebhookSignatureException عند أي إخفاق. |
| OpenEmail::toBase64() | ترميز Base64 لبايتات المرفقات، من سلسلة نصية أو مورد تدفق أو SplFileInfo أو تدفق PSR-7. |
| OpenEmail::isApiKey() | ما إذا كانت القيمة تحمل شكل oe_live_ أو oe_test_. وهو فحص شكل، لا دليل على أن المفتاح ما زال يعمل. |
| OpenEmail::isAccessToken() | ما إذا كانت القيمة تحمل شكل رمز وصول OAuth: من 1 إلى 512 حرفًا، ولا تبدأ بـ oe_. |
| OpenEmail::isSealed() | ما إذا كان متن الرسالة نصًا مشفَّرًا. وتكون القيمة false للصيغتين الموقَّعتين اللتين وصل متنهما مكشوفًا. |
| OpenEmail::resolveLanguage(), OpenEmail::languageByCode(), OpenEmail::isRtlLanguage() | عمليات البحث التي تحتاجها أداة اختيار اللغة، على جدول Languages::ALL المضمَّن. |
| $client->close() | يحرّر مقبض cURL الخاص بالعميل والاتصال الذي خلفه. والعميل الذي لم يعد مُشارًا إليه يفعل الشيء نفسه حين يحرّره PHP. |
الثوابت
كل مجموعة قيم يصدّرها TypeScript SDK هي صنف نهائي (final) في OpenEmail\Constants، فيه ثابت لكل عضو بالأسماء نفسها، فقيمة WebhookEvents::EMAIL_DELIVERED هي email.delivered. ويعيد values() المجموعة كلها، وهو أيضًا طريقة فحص قيمة جاءت من الخارج.
use OpenEmail\Constants\ApiScopes;use OpenEmail\Constants\PageLimits;use OpenEmail\Constants\WebhookEvents; $events = WebhookEvents::values(); $scopes = [ApiScopes::EMAILS_SEND, ApiScopes::THREADS_READ]; $known = in_array('email.delivered', $events, true); echo count($events), ' ', implode(',', $scopes), ' ', PageLimits::MAX_LIMIT, ' ', $known ? 'known' : 'unknown', PHP_EOL;| الثابت | ما يحتويه |
|---|---|
| OpenEmail::VERSION | إصدار الحزمة. |
| ApiScopes | مفردات النطاقات، من أجل شاشة إنشاء مفتاح. |
| WebhookEvents, WebhookSignatureHeaders | الأحداث التي يمكن لنقطة نهاية الاشتراك فيها، وأسماء الترويسات التي يحملها التسليم. |
| ErrorTypes | مفردات الأخطاء التي يأخذها ApiException::$type. |
| PageLimits | أكبر قيمة لـ limit: وقيمتها الافتراضية في معظم القوائم المرقّمة، MAX_LIMIT وDEFAULT_LIMIT: 100 و25. وبعض القوائم تقبل أكثر، ويذكر مرجع كل تابع ذلك. |
| RuleFields, RuleOperators, RuleActions | المفردات التي تُبنى منها شروط القاعدة وإجراءاتها. |
| MessageEncryptionFormats | الأغلفة الخمسة التي يمكن للاستقبال تسميتها. ثلاثة منها مختومة. |
| CredentialKinds, StepUpMethods, StepUpErrorCodes | أي اعتماد يصفه me->get وme->ping، وكيف يُفحص رمز التحقق، والرموز التي قد يفشل بها التحقق. |
| ThreadSorts وPeopleSorts وFileSorts وسائر *Sorts | الترتيبات التي يمكن ترتيب القائمة بها. |
| FormStatuses وBroadcastStatuses وSuppressionReasons وسائر المجموعات | القيم التي يمكن أن يأخذها حقل في مورد. وكل مجموعة مسمّاة باسم ما تحمله. |
| Languages::ALL | كل لغة يقبلها الإرسال المترجَم أو المعاينة، مع رمزها وأسمائها واتجاهها. |
الكائنات
الاستجابة هي JSON بعد فكّ ترميزه في صورة مصفوفة ترابطية. ولا تبني الحزمة كائنًا خاصًا بها إلا حيث تشكّل الجواب، وكل كائن منها يقع في OpenEmail\Result، وهو غير قابل للتغيير، ويطبّق IteratorAggregate وCountable على صفوفه.
| الصنف | ما يحمله |
|---|---|
| Page | items وhasMore وnextCursor، من كل list مرقّم الصفحات. |
| PeoplePage | الحقول نفسها مع seen، من contacts->listPeople. |
| TempMessagesPage | الحقول نفسها مع expiresAt، من tempMail->listMessages. |
| AddressBookPage, AddressBook | unrestricted وaddresses وdomains، من addresses->list (مع hasMore وnextCursor) ومن addresses->listAll. |
| BatchResult | items وsent وfailed، من emails->sendBatch. |
| TemplateSends | items وtotal وpage وpageSize، من templates->listSends. |
| OpenEmail\Http\HttpRequest, OpenEmail\Http\HttpResponse | ما يستقبله httpClient: ويعيده. وتُظهر var_dump() وprint_r() وjson_encode() ترويسة Authorization في الطلب على أنها [redacted]، بينما تُظهرها var_export() وdump() في Symfony كما هي. |
كل استثناء ترميه الحزمة يطبّق OpenEmail\Exception\OpenEmailException: ApiException وأصنافه الفرعية، وNetworkException، وWebhookSignatureException، وInvalidArgumentException الذي يُرمى لخطأ في الاستدعاء نفسه لا لشيء قالته API.
نقطة نهاية لا تغلّفها الحزمة بعد
لا ينبغي أبدًا أن يكون إصدار الحزمة هو ما يقف بينك وبين نقطة نهاية تعمل بالفعل. يأخذ $client->raw->request() مسارًا ووسائط مسمّاة ويعيد المتن بعد فكّ ترميزه، مع تطبيق اعتماد العميل وعنوان URL الأساسي والمهلة وسياسة إعادة المحاولة.
$result = $client->raw->request( '/labels', method: 'POST', query: ['dryRun' => true], body: ['name' => 'Invoices'], repeatable: true,); var_dump($result);تُعاد محاولة GET كأي قراءة أخرى. وأي طريقة HTTP أخرى تُرسل مرة واحدة ما لم تمرّر repeatable: true، وهو تأكيدك أنه يجوز إرسالها مرتين. ويتخطى query: القيم null أو الفارغة، ويعمل apiKey: كما يعمل في كل تابع آخر.
ما لا تفعله عن قصد
- لا يتحقق من أي متن طلب. فمخطط الخادم هو النسخة الوحيدة من القواعد، ونسخة ثانية هنا سترفض في النهاية عنوانًا يقبله خادم أحدث، في إصدار ثبّته أحدهم قبل عامين.
- ليس له تبعيات وقت التشغيل غير الإضافتين curl وjson. وعميل PSR-18 خيار، لا شرط أبدًا.
- يعيد تشكيل الاستجابة بطريقة واحدة فقط: تُستخرج مصفوفة
dataالخاصة بالمجموعة من غلافها إلى أحد الكائنات أعلاه. وكل استجابة أخرى تعود كما أرسلتها API، بمفاتيح API بصيغة camelCase.
يُبقي فحص التكافؤ في الحزمة هذا صادقًا. فهو يُفشل البناء حين لا يكون لتابع TypeScript توأم في PHP، أو حين يأخذ وسائط مختلفة، أو يرسل طلبًا مختلفًا.