الهاكات, الأحداث والقوادح – الفصل الثالث من كتاب : التطوير الاحترافي لدروبال chapeter 3 – Pro drupal 7 development

facebook-group

الهاكات, الأحداث والقوادح          Hooks, Actions, and Triggers   

 

المصطلحات الجديدة ضمن هذا الجزء مع ترجمتها

Action

Trigger

Hook

Object

Context

Type

Operation

ID

Implement

instance

نشاط

قادح

هوك

غرض

سياق

نمط

عملية

معرف

تنجيز- تحقيق

مستنسخ

إن وقوع  حدث ما – وليكن الحدث 1 – غالبا ما يؤدي إلى حصول أشياء أخرى , اعتمد حدوثها على وقوع الحدث 1 .

إن مثل هذا السيناريو :  (وقوع الأحداث وبالتالي تحدث أمور معينة  اعتمادا على هذه الأحداث) … هو دوما ما نتوقعه وننتظره عند العمل مع دروبال.

على سبيل المثال : عندما يتم ارسال رسالة ما (اي حدوث حدث معين ) , فعند ذلك فإن مدير النظام ربما ينتظر وصول رسالة ما (اي كنتيجة للحدث الذي وقع – ارسال الرسالة).

مثال آخر: يجب أن يتم حجب المستخدم blocked (حدوث شيء – نتيجة لحدث ما) وذلك عندما يقوم بإضافة كلمات غير مسموح بها ضمن التعليق comment (حدث معين).

سنقوم ضمن هذا الفصل بشرح كيفية ربط أحداث دروبال مع مجموعة من التعليمات البرمجية , وبذلك فإن هذه التعليمات سوف يتم تنفيذها عند وقوع الحدث الذي تم ربطها به.

فهم الأحداث والقوادح   Understanding Events and Triggers       

يمر دروبال من خلال سلسلة من الأحداث . وذلك من خلال سير عمله.

إن هذه الأحداث الداخلية عبارة عن الفترات الزمنية التي يسمح فيها للوحدات modules  بالتفاعل مع المعالجات التي تجري ضمن دروبال.

يبين لنا لجدول 3-1  عدد من أحداث دروبال.

Type

Event

Node

Creation of a node

Node

Deletion of a node

Node

Viewing of a node

User

Creation of a user account

User

Updating of a user profile

Login User

Logout User

عادة ما يشيير مطوري دروبال إلى هذه الأحداث الداخلية باسم hooks  (هاكات) , وذلك بأنه عند حدوث أحد هذه الأحداث فإن دروبال يسمح عندها للوحدات بالتفاعل مع ذاك الحدث ضمن تلك اللحظة (لحظة حدوث الحدث).

ولقد استخدمنا فعلياً عدد من الهاكات hooks ضمن الفصول السابقة واطلعنا بشكل بسيط جدا عليها. وعادة ما يتضمن التطوير وخاصة تطوير الوحدات ضمن دروبال استخدام الهاكات بشكل كبير , ويتوجب على المبرمج ان يعرف الهوك  hook الذي يتوجب عليه القيام بكتابة الترميز المناسب له (تنجيزه أو تحقيقه implement), وذلك طبعا تبعا للحدث الذي يرغب بالتفاعل معه.

لتفترض بأنك تملك موقع جديد, وكنت تقوم بإدارة الموقع من الكمبيوتر الواقع في الطابق السفلي.  ما إن يصبح الموقع مشهورا, فإنك تخطط عندها لبيعه لأحد الشركات الكبرى وتصبح بذلك ثرياً. وفي هذه الأثناء كنت ترغب في إن يتم اعلامك وتنبيهك في كل مرة يدخل فيها شخص للموقع. لذلك قررت بأن تجعل الكمبيوتر يصدر صوت زمور (بيب beep) مع كل مرة يدخل فيها شخص للموقع.

وبما أن قطتك نائمة , لذلك خشيت ان يزعجها صوت الزمور (بيب ) الصادر عن الكمبيوتر , لذلك قمت باستبدال صوت (بيب ) برسالة ضمن ملف Log. وسارعت لإنجاز ذلك وبدأت بكتابة وحدتك الجديدة beep module وبإنشاء ملف .info الذي سيتوضع ضمن المسار التالي : sites/all/modules/custom/beep/beep.info

والآن حان الوقت لكتابة ملف الوحدة الاساسي sites/all/modules/custom/beep/beep.module

الترميز السابق يقوم بكتابة رسالة “Beep!” ضمن ملف log  الخاص بدروبال.

الآن حان الوقت لاخبار دروبال بأن يقوم ب “بيب ” عند دخول كل مستخدم. بإمكاننا القيام بذلك ببساطة عبر القيام بتنجيز (كتابة الرماز المناسب ) للهوك (الحدث ) hook_user_login() ضمن الوحدة beep:

ولكن ماذا إذا رغبنا بأن تتم ال”بيب” أيضاً عند إضافة محتوى جديد new content ؟ نقوم بذلك ببساطة عبر تنجيز – تحقيق (كتابة الترميز المناسب ) الحدث “هوك” hook_node_insert() ضمن وحدتنا.

ولكن في حال رغبنا بأن تتم ال”بيب” عندما يتم اضافة تعليق ؟ بذلك ببساطة عبر تنجيز – تحقيق (كتابة الترميز المناسب ) الحدث “هوك” hook_comment_insert()   التي تقوم بدورها بالتقاط حدث إضافة تعليق جديد. ولكن …دعونا نفكر لدقيقة…نلاحظ بإننا نقوم بتكرار نفس الامور مرةً تلو أخرى. أليس جميلاً لو أنه كان هنالك واجهة مستخدم تمكننا من ربط حدث ال”بيب ” مع الهوك  hookالتي نريد؟ ولحسن الحظ , فإن ذلك هو ما تقدمه لنا وحدة trigger المدمجة ضمن دروبال.

تمكننا وحدة Trigger  من من ربط بعض النشاطات actions مع حدث ما( سنتابع ذلك ونشرحه بالتفصيل فيما بعد).

ضمن الترميز code  فإننا نعرف الحدث على شكل تركيبة فريدة من الشكل (هوك – عملية ) hook-operation . مثل :

  • “user-hook, login operation” (هوك المستخدم , عملية الدخول للموقع)
  • “node hook, insert operation” (هوك العقدة , عملية إدخال عقدة جديدة)

عندما تحدث أي من هذه العمليات , فإن وحدة Trigger  تمكنك من قدح حدث ما.

حتى نزيل التشويش والارتباك عنك , دعونا نوضح معاني المصطلحات التي نقوم باستخدامها:

  1. الحدث Event : وهو مصطلح له معنى حسي عام بالبرمجة, فهذا المصطلح يفهم على شكل رسالة مرسلة من قبل أحد مكونات النظام إلى مكونات أخرى ضمن النظام.
  2. الهوك Hook : عبارة عن تقنية برمجية مستخدمة ضمن دروبال, تمكن هذه التقنية الوحدات Modules  من التفاعل مع سير تنفيذ أمور معينة. هنالك عدد من الهوك الفريدة لكل عملية تنفذ على غرض “hookable”(على سبيل المثال : hook_node_insert)
  3. القادح Trigger : ويشير إلى تركيبة خاصة من الهوك مع عملية operation  مع واحد أو أكثر من النشاطات Actions  المرافقة لهم. يعني (hook +operation +Actions). على سبيل المثال : نشاط ال”بيب” beep action  الذي يترافق مع عملية الدخول للموقع login التابع لهوك المتسخدم user hook

ملاحظة : سمي قادح , لانه يقدح النشاط , اي يشرع بتنفيذه. (من مشتقات كلمة قادح : قداحة فهي عندما تنقدح تصدر الشرر ) J

 

فهم النشاطات   Understanding Actions

النشاط عبارة عن شيء يقوم به دروبال . وفيما يلي أمثلة على بعض النشاطات:

  1. ترقية عقدة ما لتظهر في الصفحة الرئيسية
  2. تغير حالة عقدة من “منشور” إلى “غير منشور”
  3. حذف مستخدم ما
  4. إرسال رسالة عبر الإيميل

كل حالة من الحالات السابقة بحد ذاتها تمثل مهمة واضحة ومحددة.

سيلاحظ المبرمجون التشابه بين مفهوم النشاطات actions  وبين توابع PHP. على سبيل المثال : بإمكانك ارسال بريد الكتروني عبر استدعاء تابع drupal_mail() الموجود ضمن includes/mail.inc .

يعزى هذا التشابه بين النشاطات Actions و التوابع functions , لأن النشاطات Actions فعلياً هي عبارة عن توابعfunctions .

واجهة المستخدم الخاصة بالقادح     The Trigger User Interface    

انقر على رابط الوحدات Modules الواقع ضمن القائمة في أعلى الصفحة, ومن ثم ومن صفحة الوحدات فعّل وحدة القادح Trigger . بعد ذلك انقر على رابط Structure  ضمن القائمة في أعلى الصفحة , وضمن صفحة Structure  انقر على رابط القوادح Triggers link .بإمكانك بعد الخطوات التالية أن ترى واجهة مشابهه للواجهة ادناه بالشكل 3-1.

لاحظ التبويبات في أعلى هذه الصفحة . تعود هذه التبويبات إلى هاكات دروبال Drupal’s Hooks .

ضمن الشكل 3-1  تظهر لنا العمليات operations  الخاصة بهوك العقدة node hook. العمليات بشكل عام هي التالية : (عملية حفظ واضافة عقدة جديدة new node , عملية تعديل عقدة ما , عملية حذف عقدة ما , عملية استعراض عقدة), وقد تم تسمية هذه العمليات بأسماء لطيفة J ,على سبيل المثال : بالنسبة لعملية الحذف الخاصة بهوك(حدث) العقدة , تم عنونتها ب “Trigger :After deleting content”.

إذن , وكما نلاحظ من الشكل , فإن من الممكن ربط كل عملية من عمليات ال”هوك” مع نشاط ما. مثلاً : ربط هوك حذف عقدة مع تنفيذ نشاط “بيب” الذي قمنا بكتابته فيما سبق.وبالتالي , فإنه عند حذف عقدة ما سوف ينقدح (يشرع بالعمل) نشاط “بيب”.

ملاحظة : ليست كل النشاطات actions متاحة أمام كل انواع القوادح, لأن بعض النشاطات لا يكون لها معنى ضمن بعض السياقات. على سبيل المثال , لن نقوم بإسناد النشاط “ترقية عقدة لتظهر في الصفحة الأولى” ‘Promote post to front page’ مع القادح “بعد حذف المحتوى ” ‘after deleting content’ !!!فهذا كلام ليس له معنى.

ملاحظة : اعتمادا على طريقة تثبيت دروبال , قد تعرض بعض القوادح عبارة “لا يوجد نشاطات متاحة لهذا القادح” ‘No actions available for this trigger’.

فيما يلي أدناه بعض اسماء القوادح مع الهاكات Hooks والعمليات موضحة في الجدول 3-2.

Table 3-2. How Hooks and Triggers Relate in Drupal 7

Trigger Name

Hook

After saving a new comment

comment_insert

After saving an updated comment

comment_update

After deleting a comment

comment_delete

When a comment is being viewed by an authenticated user

comment_vew

When cron runs

cron

When either saving a new post or updating an existing post

node_presave

After saving a new post

node_insert

After saving an updated post

node_update

After deleting a post

node_delete

When content is viewed by an authenticated user

node_view

After saving a new term to the database

taxonomy_term_insert

After saving an updated term to the database

taxonomy_term_update

After deleting a term

taxonomy_term_delete

After a user account has been created

user_insert

After a user’s profile has been updated

user_update

After a user has been deleted

user_delete

After a user has logged in

user_login

After a user has logged out

user_logout

When a user’s profile is being viewed

user_view

 

كتابة أول نشاط                 Your First Action    

مالذي يتوجب علينا فعله حتى يعمل تابع “بيب” حتى يمنهج كنشاط ويعمل بشكل كامل ؟ حتى نقوم بذالك يجب علينا اتباع الخطوات التالية :

  1. ان نخبر دروبال عن القوادح التي يدعمها هذا النشاط action.
  2. إنشاء تابع نشاط action function .

يتم تنفيذ الخطوة الأولى عبر تنجيز –تحقيق- الهوك hook_action_info() . وفيما يلي يتبين الشكل النهائي لهذه الهوك ضمن وحدة beep.

اسم التابع beep_action_info() , وكما تعودنا عندما نريد تنجيز هوك ما(اي كتابة الترميز اللازم لها) , فإن الاسم يتشكل كالتالي : اسم الوحدة “beep” مضافاً إليها اسم الهوك “action_info”. وسوف تعيد هذه الهوك مصفوفة تحوي على عدة مداخل , كل مدخل منها عبارة عن نشاط action  ضمن وحدتنا. وبما أننا نقوم بكتابة نشاط وحيد , لذلك فإن لدينا مدخل وحيد ضمن المصفوفة, اي مفتاح وحيد key , ويسمى هذا المفتاح باسم النشاط الذي نريد تنفيذه : وفي مثالنا اسم المفتاح beep_beep_action.

من المفيد أن نكون قادرين على التمييز فيما إذا كان التابع هو تابع نشاط action function  وذلك فقد من خلال قراءتنا للترميز, لذلك قمنا بإضافة اللاحقة _action لاسم تابع beep_beep() ليصبح الاسم النهائي للتابع beep_beep_action().

دعونا ننظر نظرة عن قرب للمفاتيح keys  الموجودة ضمن المصفوفة.

المفتاح “type”: يمثل نوع النشاط الذي نقوم بكتابته. يقوم دروبال باستخدام هذه المعلومات ليصنف النشاطات على اساسها ضمن قائمة منسدلة متواجدة في واجهة القوادح trigger interface  , في المكان الذي يمكن المستخدم من اسناد النشاط إلى هوك ما. كما في الشكل 3-2   , حيث يظهر ضمن القائمة المنسدلة تصنيف باسم  system , الذي يمثل النمط الذي حددناه ضمن المفتاح type , ومن ثم يندرج تحته النشاط الذي نقوم بتعريفه.

بعض الأنماط types  المحتملة تتضمن ما يلي : system, node , user, comment and taxonomy.

وحتى نستطيع ان نحدد نمط هذا النشاط action type , يتوجب علينا ان نسأل أنفسنا الأسئلة التالية :

  • ماهونوع النشاط الذي نقوم بكتابته  the type of the action ,؟
  • وما هو الغرض object  اللذي يتعامل معه النشاط الذي نقوم بكتابته ؟

في حال لم تكن الاجابة واضحة على تلك الأسئلة الهادفة لتحديد نوع النشاط action type , او في حال كان هنالك عدد من الأجوبة المختلفة , عندها نضع نمط system.

المفتاح “label”: عبارة عن الاسم السهل الخاص بذلك النشاط friendly name  وسيظهر هذا الاسم ضمن قائمة منسدلة متواجدة في واجهة القوادح trigger interface , في المكان الذي يمكن المستخدم من اسناد النشاط إلى هوك ما. كما في الشكل 3-2

المفتاح “configurable”: يحدد فيما إذا كان يوجد لهذا الحدث معاملات (parameters).

المفتاح “triggers”: عبارة عن مصفوفة من الهوك , وكل مدخل يعبر عن العملية التي يدعمها هذا النشاط على الهوك. يستخدم دروبال هذه المعلومات ليحدد فيما إذا كان سيقوم بإدراج هذا النشاط ضمن القائمة المنسدلة ل(هوك + عملية ) في واجهة القوادح.

وبذلك نكون قد شرحنا بما يكفي عن نشاطنا our action  لدروبال, وذلك من خلال التابع hook_action_info() ,لذا دعونا الآن نكتب النشاط.

.

 

 اسناد النشاط (ربطه مع الهوك المناسب)                         Assigning the action    

ننقر الآن على رابط Structure  في أعلى الصفحة , ومن ثم من صفحة Structure  ننقر على رابط Trigger.

إذا كنت قد قمت بكل شيء على الشكل الصحيح , سيكون عندها النشاط ” الذي قمت بكتابته , متاحاً الآن ضمن واجهة المستخدم , كما هو موضح ضمن الشكل أدناه 3-2.

الآن , اسند النشاط action  للقادح المرافق لحفظ محتويات جديدة saving new content  , وذلك عبر اختيار “Beep annoyingly” من القائمة المنسدلة , ومن ثم انقر على زر الإسناد  Assign button .

الآن , قم بإنشاء عقدة جديدة new node , ولتكن من نمط article  وقم بتعبئتها بالمحتويات المناسبة , ومن ثم احفظها.

بعد القيام بحفظها انقر على رابط Reports  في أعلى الصفحة , ومن ثم قم باختيار الخيار ” Recent log entries report” سوف يظهر لك جدول (الشكل أدناه). في حال كنت قد قمت بكل الخطوات السابقة بشكل صحيح ودقيق , عندها يجب ان ترى النتائج مشابهه للنتائج التي تظهر ضمن الشكل  3-3, حيث يمثل الجدول اوقات انقداح الأحداث مع البيانات المناسبة.

تغيير القوادح التي يدعما نشاط ما                             Changing witch Trigger an action support    

في حال قمت بتغيير القيم الخاصة بالعمليات التي يدعمها نشاط ما – القيم الموجودة من خلال مفتاح ‘trigger’ ضمن تابع hook_action_info() – فإنه بإمكانك ملاحظة التغيرات بشكل مباشر ضمن واجهة المستخدم.

على سبيل المثال : في حال غيرنا ضمن التابع مفتاح ‘triggers’ ليصبح على كما في الشكل ادناه, فإن نشاط “بيب” ‘Beep’ action  سوف يكون متاحا فقط لقادح “After deleting a node”

 

 

النشاطات التي تدعم أي قادح                            Actions that support any trigger    

في حال لم تكن ترغب في ان تحد نمط القوادح التي يدعمها نشاطك , عندها بإمكانك ان تصرح بأن هذا النشاط يدعم اي نوع من انواع القوادح, كما في الشكل التالي :

النشاطات المتقدمة                            Advanced Actions            

هنالك بشكل اساسي نوعين من النشاطات actions

النشاطات التي لا تحتاج إلى اي معاملات تمرر لتابع النشاط no parameters, وخير مثال عليها نشاط “Beep” الذي قد عملنا عليه سابقا, ولا حظنا بأنه لم يستخدم ولم يمرر للتابع اية معاملات parameters. فعندما ينفذ النشاط , فإنه ينفذ ال “Beep” لمرة واحدة , وهذا هو كل المطلوب منه.

 ولكن هنالك حالات عديدة يكون مطلوب من النشاطات أن تكون اكثر تعقيدا , وليس بالبساطة السابقة. على سبيل المثال , نشاط ارسال بريد الكتروني  ‘Send e-mail’ action , يحتاج مثل هذا النشاط لأن يعلم لمن يتوجب ارسال الرسالة , وما هو عنوان الرسالة ومحتواها. إن نشاط من هذا النمط يتطلب بعض الإعدادات يتم تحديدها ضمن نموذج خاص بها , وتدعى مثل هذه النشاطات بالنشاطات المتقدمة ‘Advanced Actions’  أو ‘configurable action’ .

النشاطات البسيطة , وكما لاحظنا لا تتطلب اي معاملات no parameters , ولا تحتاج إلى نموذج إعدادات configurable form. وكما انها تتميز بأنها تكون متاحة بشكل اوتوماتيكي للنظام.

نقوم بإعلام دروبال , بأننا نكتب نشاط متقدم advanced action  وذلك بواسطة ما يلي :

  • وضع قيمة المفتاح  configurable  إلى TRUE وذلك ضمن تابع hook_action_info(),
  • توفير نموج form  لوضع اعدادات النشاط
  • توفير تابع للتحقق من صحة القيم المدخلة (هذا التابع خياري )
  • توفير تابع لمعالجة مدخلات نموذج الاعدادات

تم تلخيص الفوارق بين النشاطات البسيطة simple actions  والنشاطات المتقدمة advanced actions  في الجدول 3-3.

Advanced Actions

Simple Actions

Required

Parameter No*

Required

No

Configurable form

Must create instance of action using actions

administration page

Automatic

Availability

True

FALSE

Value of configure key in

hook_action_info()

ملاحظة * إن كل من معاملي $object, $context متاحين لكلا التابعين في حال تمت الحاجة لهم , اي انهم معاملات افتراضية.

دعونا الآن نقوم بكتابة نشاط متطور advanced action  والذي سيقوم ب”بيب” beep لأكثر من مرة. حيث سنبرمجة بحيث نكون قادرين على تحديد عدد المرات التي يقوم النشاط خلالها بتنفيذ “بيب” , وذلك من خلال استخدام نموذج الاعدادات configuration form.

في البداية , نحن بحاجة لأن نخبر دروبال , بأننا نريد بناء نشاط متقدم advanced action  وذلك من خلال وضع الخاصية configurable  بقيمة TRUE.

سنقوم الآن بإضافة مدخل جديد ضمن التابع hook_action_info() ويمثل هذا المدخل معلومات النشاط المتقدم الجديد,

سوف نقوم الآن بالتحقق بسرعة فيما إذا كنا قد قمنا بالتنجيز بالشكل الصحيح . نذهب إلى Structure->Triggers  .

يجب ان يظهر النشاط ضمن القائمة المنسدلة كما في الشكل 3-4.

يتوجب علينا الآن ان نوفر نموذج يستطيع من خلاله المدير ان يحدد عدد ال”beep” المطلوبة. نقوم بذلك عبر تعريف حقل أو أكثر باستخدام واجهة النماذج ضمن دروبال Drupal’s form API. وايضا سنقوم بكتابة تابع من اجل التحقق من الادخال validation function  , وتابع من ارسال الادخال submission function .

يعتمد تشكيل الاسماء – اسماء التوابع – على معرف النشاط  action’s ID, والذي تم تعريفه ضمن hook_action_info , المعرف –action ID- الذي يهمنا الآن هو beep_multiple_beep_action, وبحسب معايير التسمية , فإن اسم النموذج يتشكل من إضافة لاحقة “_form ” إلى معرف النشاط, وبالتالي سوف يكون اسم تابع النموذج هو التالي : beep_multiple_beep_action_form.  .

وبشكل مشابه , فإن اسم تابع التحقق يحقق كما يلي : اسم معرف النشاط  action ID مضافاً إليها كلمة “_validate” وبالتالي يصبح اسم تابع التحقق beep_multiple_beep_action_validate .

والموضوع مشابه بالنسبة لتابع تسجيل المعلومات , حيث تتم اضافة اللاحقة ‘_submit’ لمعرف النشاط action ID فيكون اسم التابع هو التالي : (beep_multiple_beep_action_submit

 

يوصف التابع الأول النموذج(نموذج الاعدادات) لدروبال. ولقد احتجنا ضمن النموذج إلى ان نعرف حقل وحيد , وبذلك يستطيع مدير النظام من خلال هذا الحقل ان يقوم بإدخال عدد ال”بيب”.

من أجل الوصول لهذا النموذج (نموذج الاعدادات) , انقر على رابط Configuration  في أعلى الصفحة , وضمن صفحة Configuration  , انقر على رابط Actions, ضمن صفحة Actions, انزل إلى اسفل الصفحة , ومن خلال قائمة إنشاء نشاط متقدم , انقر على عنصر “Beep multiple times”. وبعد اختيار العنصر , سيقوم دروبال بعرض نموذج النشاط المتقدم كما في الشكل 3-5.

وكما نلاحظ, فإن دروبال قد قام بإضافة حقل توصيفي إلى نموذج الإعدادات الخاص بالنشاط. ونلاحظ ايضا بأن قيمة هذا الحقل قابلة للتعديل , وسوف يتم استخدامها بدلاً عن الشرح الافتراضي الذي تم تعريفه ضمن هوك “action_info”. وتعبر هذه الميزة مهمة جداً, لأننا قد نرغب بإنشاء نشاط متقدم اخر باسم “beep two times” عبر هذه الواجهة وهدفه القيام ب”بيب” لمرتين , وفي حال قمنا ايضا بإنشاء نشاط متقدم اخر نريد منه القيام ب”بيب” لثلاث مرات , عندها يتيح لنا هذا الحقل بإعطاء تسمية مختلفة لهذا النشاط مثلا “Beep three times” لنميزه عن النشاط السابق.

ملاحظة : ندعوا كلاً من النشاطين : “beep two times “ and “Beep three times” بمستنسخات instances  من النشاط الأصلي “Beep multiple Times”.

أما بالنسبة لتابع التحقق validation function  , فإنه كأي تابع تحقق اخر ضمن دروبال ( انظر إلى الجزء 11 حول المزيد من form validation). ضمن حالتنا, فإننا نقوم بالتحقق من إدخال المستخدم لقيمة عددية ليست كبيرة جدا.

أما بالنسبة لتابع التسجيل submit function  فإنه يعيد قيمة تعد مميزة بالنسبة لنموذج الاعدادات.

حيث يتوجب في هذه القيمة ان تكون على شكل مصفوفة , مفاتيحها عبارة عن الحقول الموجودة ضمن النموذج.

ستكون قيم هذه المصفوفة متاحة للنشاط عندما يعمل.(القيمة التي تهمنا هي عدد ال”بيب” وستكون ضمن قيم المصفوفة).

واخيراً لقد حان الوقت لكتابة النشاط المتقدم advanced action.

نلاحظ بأن النشاط يحتمل معاملين $object, $context بخلاف النشاط البسيط الذي عرفناه من قبل.

ملاحظة : إن النشاطات البسيطة simple action تاخذ نفس معاملات النشاطات المتقدمة advanced action , ولكن ضمن النشاطات البسيطة تقوم PHP بتجاهل المعاملات في حال عدم تمريرها للتابع .

 استخدام معامل ‘Context’ ضمن النشاطات                                Using the Context in

كما نرى من المثال السابق , نلاحظ بأن توقيع التابع function signature  كان على الشكل التالي example_action($object, $context). دعونا نفحص المعاملات الممررة إلى التابع بشكل مفصل:

$object: يعمل العديد من النشاطات على الأغراض المدمجة مع دروبالDrupal’s built-in object  , مثال على هذه الأغراض : العقد nodes  , المستخدمين users  , …الخ. لذلك فإن عند تنفيذ نشاط ما action  بواسطة trigger.module , فإنه يتم تمرير الغرض object  الذي يتم العمل عليه إلى النشاط , وذلك عبر معامل $object ضمن توقيع التابع.

على سبيل المثال , في حال تم وضع نشاط ما action  ليتم تنفيذه عندما يتم انشاء عقدة جديدة, عندها فإن معامل $object  سوف يحتوي على غرض العقدة the node object.

$context : يمكن ان يستدعى نشاط ما ضمن سياقات مختلفة different context. تقوم النشاطاتactions  بالتصريح عن القوادح التي تدعمها من خلال مفتاح triggers ضمن تابع hook_action_info(). ولكن في الحالة التي يكون فيها النشاط يدعم أكثر من قادح , عندها فهذه النشاطات بحاجة لطريقة تعرف من خلالها ضمن اي سياق context تم استدعائها. وبهذه الطريقة يستطيع النشاط ان يتصرف بشكل مختلف تبعاً للسياق الذي استدعي من أجله. على سبيل المثال : استدعي ضمن سياق تعديل عقدة ما , او ضمن سياق حذف عقدة ما …

آلية تحضير وحدة ‘Trigger’ للسياق           How the Trigger Module Prepare the Context       

دعونا ننشأ الآن سيناريو. افترض بأن تشغل موقع يدعم القضايا المثيرة للجدل. وليكن لدينا وحدة العمل business module  بالشكل التالي : يقوم المستخدمين بالدفع من اجل التسجيل بالموقع , وبإمكانهم فقد ترك ملاحظة أو تعليق وحيد على الموقع. ما إن يرسلوا تعليقاتهم حتى يتم حجبهم , ويتوجب عليهم ان يدفعوا مرة أخرى حتى يتم  إزالة الحجب عنهم.

لنتجاهل الأبعاد الاقتصادية لمثل هذا الموقع, ولنركز كيف بإمكاننا ان ننفذ ونحقق ذلك عبر استخدام القوادح والنشاطات.

سوف نحتاج إلى نشاط action  وظيفته القيام بحجب المستخدم الحالي. وبتفحص وحدة user.moudle  نكتشف بأن دروبال قد وفر لنا للتو نشاطاً يقوم بما نريد.

ونلاحظ بأن هذا النشاط يظهر ضمن واجهة القوادح structure ->Triggers  . ولنقم الآن بالتعديل التالي فقط على سبيل المثال ( لا ينصح ابدا التعديل على الوحدات الموجودة ضمن مجلد modules  الواقع تحت root مباشرة)

بعد التعديل يصبح الترميز على الشكل التالي :

 

اي قمنا بالتعديل على مفتاح triggers حيث اصبحت القيمة المسندة لهذه المفتاح عبارة عن مصفوفة خالية تماما.

نعود إلى واجهة المستخدم الخاصة بالقوادح , نلاحظ اختفاء هذا النشاط “block current user” من واجهة القوادح , في مثل هذه الحالات نتمنى لو كان بإمكاننا إجراء تعديل بسيط على هذا النشاط. ولكن لحسن الحظ يمكننا ذلك كما سنرى في المقطع التالي.

 تغير نشاطات موجودة باستخدام تابع        Changing Existing Actions with  action_info_alter()

عندما يديردروبال هوك action_info , تعلن كل وحدة عن النشاطات التي تقدمها.

يعطي دروبال الوحدات فرصة لتقوم بتعديل تلك المعلومات (معلومات النشاطات ) بما في ذلك من المعلومات المزودة من قبل الوحدات الآخرى.

وهذا يشرح كيف يمكن بالامكان تعديل النشاطات , وعلى سبيل المثال , سنقوم بتعديل نشاط “block current user” ليكون متاحا ضمن واجهة المستخدم الخاصة بالقوادح , وفيما يلي ادناه ترميز التعديل.

وبالتالي بعد التعديل , تصبح “block current user action” متاحة ضمن واجهة المستخدم للقوادح كما في الشكل 3-6.

إنشاء سياق        Establishing the Context         

 وبحسب المثال السابق, وعند اسناد النشاط “حجب المستخدم الحالي ” للقادح “اضافة تعليق جديد” , كما في الشكل 3-6 , عندها سيتم حجب المستخدم الذي يقوم بإضافة تعليق , فورا بعد عملية الاضافة. دعونا نلقي نظرة قريبة لمعرفة كيف يتم ذلك.

نعلم بأن اسلوب وطريقة دروبال في تنبيه الوحدات modules  حول حدوث بعض النشاطات تتم عبر قدح هوك.

في هذه الحالة سيتم قدح هوك التعليق comment hook. وبشكل دقيق , فإن العملية التي تتم هي عملية الاضافة insert operation – اضافة إلى قاعدة المعطيات, وذلك لانه فعليا يتم اضافة تعليق جديد. وتقوم وحدة القادح trigger module  بتنفيذ هوك التعليق comment hook.

ضمن هذه الهوك , يتم مسائلة قاعدة المعطيات فيما إذا كانت هنالك اي نشاطات تم اسنادها لهذا القادح. عندها تقوم قاعدة المعطيات بإعطاء المعلومات الخاصة بنشاط “Block current usr” الذي قمنا بإسناده فيما سبق.

تصبح الآن وحدة القادح trigger module جاهزة لتنفذ النشاط, الذي يملك توقيع التابع التالي : example_action($object, $context) .

ولكن لا يزال لدينا مشكلة , النشاط الذي على وشك التنفيذ عبارة عن نشاط من نمط مستخدم action of type user  , وليس من نمط تعليق action of type comment .

إذا , فإن التابع يتوقع ان يتلقى غرض Object  من نمط غرض مستخدم user object  ! ,ولكن هنا , يتم استدعاء النشاط الخاص بالمستخدم ضمن سياق هوك خاص بتعليق comment hook. وقد تم تمرير المعلومات الخاصة بالتعليق للهوك , لو لم يتم تمرير المعلومات الخاصة بالمستخدم. مالذي يتوجب علينا فعله؟

الذي يتم فعليا , بان وحدة القادح trigger module  تحدد بأن النشاط الذي تم هو عبارة عن نشاط مستخدم user action  وتقوم بتحميل غرض المستخدم $user object  , ذاك الغرض الذي يتوقعه نشاط المستخدم user action.

فيما يلي ترميز code  من modules/trigger/trigger.module يوضح كيف يتم ذلك.

عندما يتم تنفيذ الترميز السابق بالنسبة  user action , فإن الحالة الثانية ستتطابق , وبالتالي فإنه سيتم تحميل غرض المستخدم user object  ومن ثم يتم تنفيذ نشاط المستخدم.  اما بالنسبة للمعلومات الموجودة لدى هوك التعليق comment hook (على سبيل المثال , عنوان التعليق ) فإنها تمرر إلى النشاط عبر معامل السياق $context parameter.

لاحظ – في الترميز ادناه – كيف يبحث النشاط في البداية عن معرف المستخدم user’s ID ضمن الغرض الممرر للتابع , ومن ثم ضمن السياق, وفي حال لم يجده يبحث عنه ضمن المتحول العام الخاص بالمستخدم global $user.

يتوجب على النشاطات actions  ان تكون ذكية بشكل ما, لانها – النشاطات – لا تعمل الكثير عما يحدث عندما يتم استدعائها.

تقوم وحدة القادح trigger module  دوما بتمرير الهوك الحالية مع العملية عبر متحول السياق  context parameter. حيث تكون القيم مخزنة ضمن $context[‘hook’] and $context[‘op’]. وتعتبر هذه طريقة معيارية لتزويد النشاط بالمعلومات.

 

كيف يتم تخزين النشاطات          How Actions Are Stored             

 النشاطات Actions : عبارة عن توابع تعمل في وقت محدد.

لا تملك النشاطات البسيطة معاملات خاصة بإعداداتها configurable parameters. على سبيل المثال , نشاط “Beep” الذي انشأناه سابقا , يقوم ببساطة بإنشاء “بيب” بسيطة. ولا يحتاج إلى اي معلومات أخرى (طبعا لاننسى بأن كل من معاملي object and $context  متاحين دوما عند الحاجة).

وعلى عكس النشاط البسيط simple action  لدينا النشاط المتقدم advanced action  ,وقد قمنا فيما سبق بإنشاء نشاط متقدم. فنشاط “beep multiple times” المتقدم الذي انشأناه من قبل , يحتاج ان يعلم كم مرة يتوجب عليه أن يقوم ب “بيب”.

وهنالك عدة نشاطات متقدمة اخرى , مثل نشاط ارسال بريد الكتروني ‘Send e-mail’  , الذي قد يحتاج إلى المزيد من المعلومات , مثل : لمن يرسل الرسالة ؟ موضوع الرسالة ؟ … يتوجب تخزين مثل هذه المعاملات ضمن قاعدة المعطيات

جدول النشاطات          The actions table             

 عندما يتم إنشاء مستنسخ instance  من نشاط متقدم advanced action  من قبل مدير الموقع, يتم سلسلة المعلومات serialized  المدخلة عبر نموذج الاعداداتconfiguration form  ويتم حفظها ضمن حقل يدعى parameter  ضمن جدول يدعى actions ضمن قاعدة المعطيات. مثلاً فإن السجل الخاص بنشاط “بيب” البسيط يبدو على الشكل التالي:

وفي حال كان سيتم تنفيذ نشاط متقدم advanced action  , يتم استعادة محتويات حقل parameters والقيام بفك سلسلة المعلومات unserialized وتضمينهم ضمن معامل السياق $context parameter, وتمريرها للنشاط.

وبالتالي فإن عدد ال”بيب” ضمن مستنسخ من نشاط “Beep multiple times”  سوف يكون متاحا للتابع beep_multiple_beep_action() عبر المتحول $context[‘beeps’].

معرفات النشاط          Action IDs             

 لاحظ الاختلاف بين معرفات النشاط action IDs ضمن سجلين مختلفين ضمن قاعدة المعطيات. إن معرف النشاط action ID الخاص بالنشاط البسيط عبارة عن اسم تابع النشاط بحد ذاته.

ولكن وضوحاً , لا يمكننا استخدام اسم التابع كمعرف بالنسبة للنشاطات المتقدمة. لاننا ضمن النشاطات المتقدمة يكون لدينا عدة مستنسخات من النشاط نفسه مخزنة ضمن قاعدة المعطيات. وبالتالي يتم استخدام المعرفات الرقمية numeric action ID بدلا من اسم التابع.(بإمكانك تتبع جدول actions_aid ضمن قاعدة المعطيات).

يحدد محرك تنفيذ النشاطات فيما إذا كان يتوجب عليه استعادة معاملات هذا النشاط , وذلك اعتمادا على كون معرف هذا النشاط عبارة عن معرف رقمي numeric ID. وفي حال لم يكن المعرف رقمي , عندها يتم ببساطة تنفيذ النشاط . يعتبر هذا اسلوب سريع في اتخاذ القرار, ويستخدم دروبال نفس المقاربة ضمن صفحة inxex.php ليميز بين المحتوى وثوابت القائمةmenu constants .

الاستدعاء المباشر للنشاط عبر استخدام التابع actions_do()        Calling an Action Directly with actions_do()

 تعتبر وحدة القوادح trigger module  احد الوسائل لاستدعاء النشاطات.

ولكن بإمكانك كتابة وحدة منفصلة تقوم باستدعاء النشاطات actions وتقوم ايضا بإعداد المعاملات التي ستمررها لهذه النشاطات بنفسك.

في حال كنت ترغب بإنشاء هكذا وحدة , فان استخدام التابع actions_do() يعتبر الوسيلة المثلى لاستدعاء النشاطات.

إن توقيع التابع هو التالي :

actions_do($action_ids, $object = NULL, $context = NULL, $a1 = NULL, $a2 = NULL)

الآن دعونا نمحص النظر بمعاملات هذا التابع :

$action_ids : النشاطات المطلوب تنفيذها , إما يكون على شكل معرف وحيد لنشاط single action ID  , او عبارة عن مصفوفة من معرفات النشاطات.

$object : الغرض الذي يجري عليه النشاط , مثل : عقدة , مستخدم , تعليق …

$context: عبارة عن مصفوفة من الشكل (مفتاح –قيمة ) تحوي على معلومات قد يرغب الحدث في استخدامها , بما فيها من معاملات الاعدادات configuration parameter وذلك في حالة النشاطات المتقدمة

$a1 and $a2: معاملات اختيارية , والتي – في حال تمريرها للتابع actions_do() سوف يتم تمريرها للنشاط.

هنا فيما يلي مثال عن استدعاء النشاط “Beep” البسيط باستخدام التابع actions_do() :

 

$object = NULL; // $object is a required parameter but unused in this case

actions_do(‘beep_beep_action’, $object);

هنا فيما يلي مثال عن استدعاء النشاط “Beep multiple times ” المتقدم باستخدام التابع actions_do() :

$object = NULL;

actions_do(2, $object);

أو بإمكاننا استدعائه ونمرر له المعلومات المطلوبة :

Or, we could call it and bypass the retrieval of stored parameters like this:

$object = NULL;

$context[‘beeps’] = 5;

actions_do(‘beep_multiple_beep_action’, $object, $context);

ملاحظة : ربما يتسائل مطوري PHP المتشددين : “لماذا اصلا نستخدم مثل هذه النشاطات؟ لماذا لا نقوم باستدعاء التابع مباشرة او ببساطة نقوم بتنجيز هوك ما؟ لماذا نبذل هذا الجهد لاخفاء المعلومات ضمن السياق , فقط بهدف استعادتهم مرة اخرى , وكان بإمكاننا استخدام معاملات PHP التقليدية؟

تكمن الاجابة بان الهدف هو كتابة نشاطات ضمن تابع توقيعه عام جدا , وبالتالي نتمكن من اعادة الاستخدام.

 

تعريف القادح الخاص بك باستخدام hook_trigger_info()             Defining Your Own Triggers with hook_trigger_info()

 كيف يعرف دروبال ماهي القوادح المتوفرة حتى يتم عرضها ضمن واجهة المستخدم الخاصة بالقوادح؟

يتيح دروبال للوحدات ان تقوم بتعريف الهاكات hooks التي تصرح عن انواع القوادح الموجودة أو المدعومة ضمن هذه الوحدات. على سبيل المثال : فيما يلي تنجيز هوك hook_trigger_info() من وحدة القوادح triggers module , والتي تُعرّف كل القوادح المعيارية المتاحة بعد تثبيت نواة دروبال 7.

وكما ترى من هيكلية التابع , فإن كل تصنيف قادح ( على سبيل المثال : عقدة , تعليق , نظام , مستخدم ) يعيد مصفوفة من الخيارات التي بدورها تظهر ضمن صفحة اعدادات القوادح (واجهة المستخدم الخاصة بالقوادح). وضمن كل مصفوفة خاصة بتصنيف قادح ما , بإمكانك تعريف قادح ووضع تسمية مناسبة له يتم عرضها في صفحة اعدادات القادح.

مثلاً , نجد عند node_insert يمثل اسم القادح , اما القيمة المرفقة مع label هذا القادح تمثل القيمة التي تظهر في واجهة المستخدم الخاصة بالقوادح , حيث يظهر هناك :”after saving new content” .

إذا قمنا بتعديل وحدة الملاحظات annotations module  التي قمنا بإنشائها في الجزء الثاني لتتضمن الhooks , فإنها قد تبدو كما يلي :

بعد تفريغ الكاش , سيقوم عندها دروبال بالتقاط التنجيز الجديد الخاص بهوك hook_trigger_info() ويقوم بالتالي بتعديل صفحة القوادح لتتضمن تبويب جديد منفصل خاص بهوك الملاحظات الجديد الذي انشأناه منذ قليل, كما هو واضح ضمن الشكل 3-7.

بالتأكيد , لاتزال الوحدة مسؤولة عن قدح هذه الhooks باستخدام تابع module_invoke() أو باستخدام التابع module_invoke_all() , وكذلك الوحدة مسؤولة عن قدح النشاطات.

ضمن هذا المثال , فإن الوحدة بحاجة لاستدعاء

module_invoke_all(‘annotate_insert’, ‘annotate_update’, ‘annotate_delete’, ‘annotate_view’).

أما من اجل قدح النشاطات actions  فيتم باستخدام actions_do().

 

الخلاصة     Summary   

 بعد قراءة هذا الجزء اصبحت قادرا على

  • معرفة كيفية اسناد نشاطات actions إلى قوادح triggers
  • كتابة نشاط بسيط simple action
  • كتابة نشاط متقدم advanced action  وربطه مع نموذج اعدادات configuration form
  • إنشاء واعادة تسمية مستنسخات instances  من النشاطات المتقدمة advanced actions  وذلك باستخدام صفحة إدارة النشاطات.
  • فهم ومعرفة معنى متحول السياق context
  • فهم كيفية استخدام النشاطات للسياق لتغير سلوكها
  • فهم كيفية تخزين النشاطات واستعادتها وتنفيذها.

انقر هنا للحصول على ملف : الهاكات , الاحداث والقوادح hooks , events and triggers

في حال وجود اي استفسارات , او ملاحظات , لا تترددوا في مراسلتنا

مع تمنياتي لكم بالتوفيق

المصطلح

الترجمة

الشرح

core modules

وحدات النوة

contributed  modules

الوحدات المساهمة

Polls

استطلاعات الرأي

Node

عقدة

Annotation

شرح

Taxonomy

نظام التصنيف

Implement

تنجيز – تحقيق

تنجيز أو تحقيق تابع ما , اي كتابة محتوى هذا التابع

To implement a function it means to write the body of this function

taxonomy term

مصطلح او تصنيف

Context

سياق

object

غرض

function

وظيفة أو تابع بحسب السياق

Configuration

الإعدادات

Action

فعل

Event

حدث

Function signature

توقيع التابع

يقصد بها اسم التابع مع المتحولات التي تمرر له والمذكورة في تعريف التابع :مثال :

example_action($object, $context)

Hook

حدث أو هوك ( اي تركنا الكلمة كما هي في بعض الأحيان)

Advertisements

, , , , , , , , , , , , , ,

  1. #1 by Yosf Ada on يونيو 2, 2014 - 1:11 م

    جزاك الله خيرا

اترك رد

Please log in using one of these methods to post your comment:

WordPress.com Logo

أنت تعلق بإستخدام حساب WordPress.com. تسجيل خروج   / تغيير )

صورة تويتر

أنت تعلق بإستخدام حساب Twitter. تسجيل خروج   / تغيير )

Facebook photo

أنت تعلق بإستخدام حساب Facebook. تسجيل خروج   / تغيير )

Google+ photo

أنت تعلق بإستخدام حساب Google+. تسجيل خروج   / تغيير )

Connecting to %s

%d مدونون معجبون بهذه: