تخطَّ إلى المستندات
PHP

الأعضاء

`members->list` و`listAll` و`iterate` و`get` و`add` و`update` و`remove` و`grantAddress` و`revokeAddress` و`grantDomain` و`revokeDomain`، وتوابع الدعوات إلى جانبها.

كل الدوالّ

members.php
$supportRoleId = 'role_8b1f4c2e9a7d3b60e5f1a2c4';$viewerRoleId = 'role_2c7e9a1f4b8d3e60c5a7f1b9'; $invitation = $client->members->add([    'email' => '[email protected]',    'roleId' => $supportRoleId,    'addressIds' => ['2b81de07-9c3f-4a61-b8e2-5d07f4c19a36'],    'access' => 'member',]);echo $invitation['id'], ' ', $invitation['expiresAt'], PHP_EOL; foreach ($client->members->listAll() as $person) {    echo $person['email'], ' ', $person['userId'], PHP_EOL;} $samId = 'q7Vd3kX9mT2pLw8RzN4bYc6HfJ1sGa5E';$member = $client->members->get($samId);echo $member['role']['name'], $member['implied'] ? ' (implied)' : '', PHP_EOL; $client->members->update($samId, ['roleId' => $viewerRoleId]); $addressId = 'c40a95f2-1e7b-4d38-a6c9-82f05b3d7e14';$client->members->grantAddress($samId, ['addressId' => $addressId, 'access' => 'viewer']);$client->members->revokeAddress($samId, $addressId); $removed = $client->members->remove($samId);echo $removed['addressesRevoked'], PHP_EOL;

منحتان لكل شخص، ولا يجوز دمجهما. فـ role هو ما يجوز له فعله. وaddresses وdomains هما ما يجوز له فعله عليه. وعلى الاثنين أن يتوافقا: دور يحمل emails:send مع ضبط access على viewer على invoices@ يعني شخصًا يجوز له إرسال البريد ولا يجوز له الإرسال من ذلك العنوان. والاستثناء دور يحمل addresses:all، فهو يصل إلى كل عنوان مهما سردت addresses، لأن تلك المصفوفة لا تحمل إلا المنح المباشرة. لذا تحقّق من permissions قبل أن تقرأ addresses على أنها كل ما يصل إليه الشخص.

كل استدعاء يخص شخصًا واحدًا يأخذ userId الخاص به كأول وسيط، لا بريده الإلكتروني، فاقرأه من list أو listAll كما يفعل المثال. وadd هو الاستثناء الوحيد، لأنه يدعو عنوانًا: فلا يكون للشخص userId إلا بعد أن يقبل، ويتابع listInvitations الدعوة حتى ذلك الحين. ومتن add وupdate وgrantAddress وgrantDomain مصفوفة واحدة بأسماء API بصيغة camelCase (roleId وaddressIds وaddressId).

يعيد list صفحة OpenEmail\Result\Page واحدة، ويعيد listAll كل الأعضاء في مصفوفة واحدة، ويعيد iterate كائن Generator يسلّم عضوًا واحدًا في كل مرة. ويعود العضو في صورة مصفوفة مفاتيحها بصيغة camelCase، وrole مصفوفة بداخلها، فيقرأ $member['role']['name'] اسم الدور.

حين تكون implied بقيمة true فهذا يعني أن أحدًا لم يختر الدور. فالشخص يحمل عناوين أو نطاقات ولا يملك صف دور، فاستُنتج الدور من أوسع منحة لديه. عامِله على أنه “لم يُحسم بعد”، وupdate هو ما يحوّل الاستنتاج إلى قرار. وحتى ذلك الحين، فإن توسيع وصوله إلى العناوين يوسّع صامتًا ما يجوز له فعله.

مالك مساحة العمل هو الصف الأول، مع isOwner بقيمة true، بينما يرفضه add وupdate وremove بخطأ member_is_owner، وهو 422 يُرمى في صورة ValidationException. ومساحة العمل غير المشتركة تبلّغ بعضو واحد لا بصفر، فاستبعد isOwner عند عدّ المقاعد: count(array_filter($client->members->listAll(), fn(array $member): bool => !$member['isOwner'])).

يأخذ remove المحورين معًا، الدور وكذلك كل منحة عنوان ونطاق على مساحة العمل هذه، ويبلّغ في addressesRevoked بعدد المنح التي ألغاها، بما فيها منح النطاقات. أما revokeAddress فهو الضيق، لمن انتقل إلى فريق آخر لا لمن غادر، ويفعل revokeDomain الشيء نفسه لنطاق كامل.

تطلب add وupdate وremove واستدعاءات المنح والسحب الأربعة رمز تحقق من رمز وصول OAuth، ولا تطلبه من مفتاح API أبدًا. وإلى أن يحصل الرمز على تحقق، ترمي استثناء PermissionException تكون قيمة isStepUpRequired() فيه true. ويحتاج add وgrantDomain أيضًا إلى خطة تشمل وصول الفريق، وفي خطة لا تشمله يرميان PermissionException مع ضبط errorCode على plan_required.

المعاملات

emailstringمطلوب
من تدعوه، بعد اقتطاع الفراغ وتحويله إلى أحرف صغيرة. ولا يلزم أن يملك حسابًا بعد: الجميع يُدعَون، ويحطّ الدور والمنح عند القبول. أما من هو في مساحة العمل أصلًا فيعطي `member_is_owner` (422). والعنوان الذي يسجّل الدخول بكلمة مرور خاصة به لا يمكن دعوته ويعود بـ `mailbox_login` (403)، فادعُ البريد الإلكتروني الخاص بالشخص نفسه بدلًا منه.
roleIdstringمطلوب
الدور الذي سيحمله، من 1 إلى 128 حرفًا، ويجب أن يكون دورًا على مساحة العمل هذه: فالمعرّف المجهول يعطي `role_not_found` (404)، يُرمى في صورة `NotFoundException`. ولا يمكن منح دور المالك ويعود بـ `role_immutable` (409)، لأن جعل شخص مالكًا هو نقل لمساحة العمل ولا استدعاء لذلك هنا.
addressIdsarray
العناوين التي تحملها الدعوة، بحد أقصى 64 معرّفًا طول كل منها من 1 إلى 128 حرفًا، وتُمنح عند قبولها. ويُفحص كل معرّف قبل كتابة أي شيء، فالمعرّف الذي ليس عنوانًا على مساحة العمل هذه يرفض النداء كله بـ422 `member_not_found` ولا يُرسل شيء. ودعوة العنوان نفسه مجددًا خلال عشر دقائق تعطي 409 `invitation_too_soon`.
domainIdsarray
النطاقات الكاملة التي تحملها الدعوة، بحد أقصى 64 معرّفًا، وتُمنح عند قبولها. ومنحة النطاق تصل إلى كل عنوان على ذلك النطاق، بما فيها العناوين التي تُنشأ لاحقًا. والمعرّف الذي ليس نطاقًا على مساحة العمل هذه يعطي 422 `member_not_found`، كما في العنوان.
accessstring
ما يجوز له فعله بكل معرّف في `addressIds` و`domainIds`: `member` يقرأ العنوان ويرسل باسمه، و`viewer` يقرأه فقط. والافتراضي `member`، وهو المستوى الذي استخدمته لوحة التحكم ومسار المشاركة الأقدم دائمًا، فيعني الاستدعاء نفسه الشيء نفسه من سكربت ومن شاشة. وامنح مزيجًا باستدعاء `grantAddress` بعد ذلك للعناوين المختلفة.

الاستجابة

objectstring
دائمًا `member`. وتجيب عملية الإزالة بالقيمة نفسها، مع `userId` الخاص به و`deleted` بقيمة true و`addressesRevoked`، دون أي من الحقول الأخرى أدناه.
userIdstring
معرّف حساب الشخص، وهو المقبض الذي يأخذه كل استدعاء آخر للأعضاء كأول وسيط: `get` و`update` و`remove` واستدعاءات المنح والسحب الأربعة. وإضافة شخص هي الاستدعاء الوحيد الذي يعمل انطلاقًا من بريد إلكتروني بدل ذلك، لأن من يضيف زميلًا يعرف عنوانه لا معرّفه.
emailstring
البريد الإلكتروني في حسابه، مُعادًا كما يخزّنه ذلك الصف. ولا يكتبه هذا المورد أبدًا، وتحويل الأحرف إلى صغيرة في `add` يسري على العنوان الذي ترسله للبحث لا على ما يعود. وبعد المالك، تُرتَّب قائمة الأعضاء بحسبه لا بحسب وقت الانضمام، لأن القائمة تُقرأ للعثور على شخص بعينه لا لرؤية ما تغيّر.
namestring or null
اسمه المعروض، مأخوذًا من حسابه حيث يحمل العمود قيمة دائمًا. وقيمة null في النوع دفاعية لا حالة شوهدت هذه الواجهة تنتجها. وهو يخصّه هو لا مساحة العمل، فلا شيء في هذا المورد يمكنه ضبطه.
imagestring or null
صورته الرمزية، مأخوذة من حسابه، وتكون null حين لم يضبط واحدة.
role.idstring or null
معرّف الدور الذي يحمله، يُقرأ بوصفه `$member['role']['id']`، أو null حين لم يختره أحد. انظر `implied`. وnull هنا هي الحالة الوحيدة التي يبلّغ فيها `role` عن استنتاج لا عن قرار اتخذه أحد.
role.namestring
اسم الدور. وبالنسبة إلى عضو ضمني فهو اسم القالب المدمج الذي يقابل وصوله، لا صف في مساحة العمل هذه.
role.builtinstring or null
أي دور مدمج هو الدور، `owner` أو `admin` أو `member` أو `viewer` أو `developer` أو `billing`، أو null لدور مخصص. ولا يظهر `owner` إلا في صف المالك نفسه، إلى جانب `isOwner` بقيمة true. وإسناد ذلك الدور لأي شخص يُرفض بـ `role_immutable` (409).
isOwnerbool
تكون true على صف واحد بالضبط، وهو الحساب الذي تُفهرَس عليه مساحة العمل. وهو يحمل كل صلاحية مهما قال صف دوره، ويتصدّر الترتيب، ويرفضه `add` و`update` و`remove` جميعًا بـ`member_is_owner`. استبعده عند عدّ المقاعد.
impliedbool
تكون true حين يملك هذا الشخص منح عناوين أو نطاقات ولا يملك صف عضوية، فيكون دوره مستنتَجًا لا مختارًا: فأي منحة `member` تجعله دور Member المدمج، وإلا فـ Viewer. ولا تكون true للمالك أبدًا. اعرضها بوصفها «مستنتَج من الوصول». وإلى أن يحوّل `update` الاستنتاج إلى قرار، فإن توسيع وصوله إلى العناوين يوسّع صامتًا ما يجوز له فعله.
permissionsarray
صلاحيات الدور مسطَّحةً على العضو، فتجيب قراءة واحدة عن سؤال «هل يجوز له؟» دون جلب الدور. وبالنسبة إلى عضو ضمني تأتي الصلاحيات من القالب المدمج لا من صف الدور في مساحة العمل هذه، فتحرير دور Member المدمج لا يغيّر ما يحمله عضو ضمني.
addressesarray
العناوين التي أُعطيت له، مرتَّبةً بحسب العنوان، مصفوفة لكل عنوان بمستوى وصوله الخاص. وتكون فارغة لمن يحمل دورًا بلا منح، وهو شكل العضو الجديد إلى أن يُمنح عنوانًا، وهو الإخفاق الصحيح ما دمت لم تحسم بعد ما ينبغي له أن يراه.
addresses[].addressIdstring
معرّف العنوان، وهو ما يأخذه `grantAddress` و`revokeAddress`. ويُرفض في كليهما معرّف ليس عنوانًا على مساحة العمل هذه، بدل الإبلاغ عن سحب لم يحدث.
addresses[].addressstring
العنوان الكامل، بأحرف صغيرة، مُعاد بناؤه من جزئه المحلي ونطاقه.
addresses[].accessstring
ما يجوز له فعله بهذا العنوان وحده: `member` يقرأه ويرسل باسمه، و`viewer` يقرأه فقط. وعلى هذا والدور معًا أن يسمحا بالإرسال قبل أن يحدث، فدور يحمل `emails:send` فوق منحة `viewer` لا يرسل من أي عنوان. والعمود المخزَّن اسمه `role`، وقد أُعيدت تسميته هنا كي لا تحمل مصفوفة واحدة مفتاحَي `role` مأخوذين من مفردتين مختلفتين.
domainsarray
النطاقات الكاملة التي أُعطيت له، ولكل منها `domainId` و`domain` و`access`. ومنحة النطاق تصل إلى كل عنوان عليه، بما فيها العناوين التي تُنشأ لاحقًا، فاقرأها إلى جانب `addresses` قبل أن تقرر أن شخصًا لا يصل إلى عنوان ما. ويأخذ `grantDomain` و`revokeDomain` المعرّف `domainId`.
createdAtstring or null
وقت كتابة صف العضوية الخاص به، في صورة سلسلة نصية بصيغة ISO 8601، ويكون null حين لا يوجد صف عضوية أصلًا. وذلك الـ null يصف الفئة نفسها التي تصفها `implied` بقيمة true: أشخاص يحملون منحًا من قبل وجود الأدوار ولم يمنحهم أحد دورًا منذ ذلك الحين.

الدعوات

invitations.php
$waiting = $client->members->listAllInvitations(); foreach ($waiting as $invitation) {    if ($invitation['expired']) {        $client->members->resendInvitation($invitation['id']);    }} $client->members->revokeInvitation('winv_6bb640f5b99e47deb758f1f5');

يجيب add بدعوة، وهذه هي الاستدعاءات التي تتابعها. يعيد listInvitations صفحة OpenEmail\Result\Page واحدة من الدعوات التي لم يقبلها أحد بعد، ويعيدها listAllInvitations كلها في مصفوفة واحدة، ويعيد iterateInvitations كائن Generator يسلّم دعوة واحدة في كل مرة. ويعيد resendInvitation إرسال إحداها برابط جديد وأربعة عشر يومًا إضافية، ويسحبها revokeInvitation. والدعوة المنتظرة لا تمنح شيئًا حتى تُقبل.

الدعوة مصفوفة فيها id وemail وrole وaddresses وdomains وexpiresAt وexpired وlastSentAt وcreatedAt. ويبلّغ delivered وdeliveryError عن مصير آخر رسالة دعوة، فيستطيع السكربت أن يميّز دعوة كُتبت من دعوة وصلت إلى أحد.

يرفض resendInvitation العنوان نفسه مرتين خلال عشر دقائق بـ 409 invitation_too_soon، ويرفض revokeInvitation الدعوة التي قُبلت أولًا بـ 409 invitation_accepted. ويُرمى كلاهما في صورة ConflictException، فتكون قيمة isConflict() هي true ويميّز errorCode بينهما.