الجزء الخامس - البرمجة الموجهة للكائنات و WordPress: مثال على WordPress - التنفيذ: قائمة الإدارة

نشرت: 2022-02-04

في مقالتنا السابقة حول البرمجة الشيئية ، ناقشنا التصميم الذي توصلنا إليه في النهاية من أجل المكون الإضافي الموجه للكائنات.

الآن ، سوف ندخل في الجزء الأكثر إثارة حيث سنتعمق أكثر في كيفية تنفيذنا له!

سنرشدك خلال بعض أجزاء التنفيذ ، خطوة واحدة في كل مرة ، ونتحدث عن أساسيات البرمجة الموجهة للكائنات ، وبناء جملة PHP ، وبعض المفاهيم الأساسية ، وسنلقي نظرة على مبادئ SOLID.

بنهاية هذه المقالة ، نأمل أن يكون لديك فهم أفضل لـ OOP وأن تكون متحمسًا لكتابة المكونات الإضافية الموجهة للكائنات!

ابدء

نفترض أنك على دراية بتطوير مكون WordPress الإضافي بشكل عام ، لذلك سنركز على الجوانب الموجهة للكائنات في المكون الإضافي الخاص بنا. إذا كنت جديدًا في تطوير المكون الإضافي أو كنت بحاجة إلى تحديث ، فيجب أن تتعلم كيفية إنشاء أول مكون إضافي لبرنامج WordPress أولاً.

لنبدأ كما نفعل دائمًا ، من خلال إنشاء ملف prsdm-limit-login-trys.php جديد ، ضمن دليل المكونات الإضافية (ie / wp-content / plugins / prsdm-limit-login-fighters).

سيتضمن ملف المكون الإضافي الرئيسي رأس المكون الإضافي الذي تعرفه بالفعل:

 /** * Plugin Name: PRSDM Limit Login Attempts * Plugin URI: https://pressidium.com * Description: Limit rate of login attempts, including by way of cookies, for each IP. * Author: Pressidium * Author URI: https://pressidium.com * Text Domain: prsdm-limit-login-attempts * License: GPL-2.0+ * Version: 1.0.0 */

وبيان بسيط إذا منع الوصول المباشر إليه.

 if ( ! defined( 'ABSPATH' ) ) { exit; }

هذا كل ما نحتاجه الآن. سنعود إلى هذا الملف لاحقًا!

بناء قائمة الإدارة

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

لذا ، لنبدأ في التفكير في الشكل الذي ستبدو عليه واجهة برمجة التطبيقات الموجهة للكائنات .

من الناحية المثالية ، نرغب في إنشاء مثيل Pressidium_LLA_Settings_Page بنا والانتهاء منها. لإنشاء مثيل لفئة ، يجب استخدام الكلمة الأساسية new .

 new Pressidium_LLA_Settings_Page();

الآن ، دعنا نفكر في الشكل الذي ستبدو عليه فئة Pressidium_LLA_Settings_Page .

سنبدأ بإنشاء فصل دراسي جديد باستخدام الكلمة الأساسية class :

 class Pressidium_LLA_Settings_Page {}

يجب أن يكون اسم الفصل الخاص بنا مسبوقًا بمعرف فريد ، Pressidium_LLA_ لمنع أي تضارب في التسمية مع مكونات WordPress الإضافية الأخرى. تمنع البادئات المكونات الإضافية الأخرى من الكتابة فوق و / أو استدعاء فصولنا عن طريق الخطأ. طالما أن أسماء الفئات الخاصة بنا فريدة - أو نستخدم مساحات الأسماء - فلن يكون هناك أي تعارض مع المكونات الإضافية الأخرى.

المنشئ

الآن ، سنربط admin_menu و admin_init. لتبسيط الأمور ، سنقوم فقط باستدعاء add_action () في المُنشئ (تنبيه المفسد: سنقوم بتغيير هذا لاحقًا).

 class Pressidium_LLA_Settings_Page { /** * Settings_Page constructor. */ public function __construct() { add_action( 'admin_menu', array( $this, 'add_page' ) ); add_action( 'admin_init', array( $this, 'register_sections' ) ); } }

تستدعي الفئات التي لها مُنشئ هذه الطريقة عندما يتم إنشاء مثيل لكائن. لذا ، فإن طريقة __construct() رائعة لأي تهيئة قد نرغب في إجرائها.

دعنا نلقي نظرة فاحصة على add_action() بنا. إذا كنت قد طورت مكونات WordPress الإضافية في الماضي ، فربما تتوقع شيئًا كهذا:

 add_action( 'admin_menu', 'my_plugin_prefix_add_page' );

لكن بدلاً من ذلك ، لدينا:

 add_action( 'admin_menu', array( $this, 'add_page' ) );

قد تكون مرتبكًا بشأن استخدام المصفوفة هنا. عندما نرغب في تمرير طريقة كائن تم إنشاء مثيل له باعتباره رد نداء / قابل للاستدعاء ، يمكننا استخدام مصفوفة تحتوي على كائن في الفهرس 0 ، واسم طريقة في الفهرس 1.

ما هو $ this؟

إنه متغير زائف متاح عندما يتم استدعاء طريقة من داخل سياق كائن. $this هي قيمة الكائن المستدعي. في هذه الحالة ، $this هو مثيل Pressidium_LLA_Settings_Page .

بالإضافة إلى ذلك ، فإن جميع "وظائفنا" هي الآن توابع ، ملفوفة في فصل دراسي ، لذلك ليست هناك حاجة إلى إضافة بادئة إلى أسماء الطرق الخاصة بنا.

مساحات الأسماء

تسمح لنا مساحات الأسماء في PHP بتجميع الفئات والواجهات والوظائف ذات الصلة وما إلى ذلك ، مما يمنع تضارب الأسماء بين التعليمات البرمجية الخاصة بنا وفئات / وظائف PHP الداخلية أو الخاصة بالجهات الخارجية.

دعنا نمضي قدمًا ونستخدمها ، لذلك لا يتعين علينا أن نبدأ أيًا من فصولنا للمضي قدمًا.

سنعلن عن مساحة الاسم باستخدام الكلمة الأساسية namespace .

 namespace Pressidium;

يمكن تحديد مساحات الأسماء بمستويات فرعية.

 namespace Pressidium\Limit_Login_Attempts;

نظرًا لأننا نبني صفحة إعدادات ، فسوف نعلن عن مساحة اسم فرعية "صفحات" لتجميع أي شيء متعلق بصفحات الإدارة معًا.

 namespace Pressidium\Limit_Login_Attempts\Pages;

يمكننا التخلص أخيرًا من البادئة Pressidium_LLA_ !

 namespace Pressidium\Limit_Login_Attempts\Pages; class Settings_Page { // ...

ملحق WordPress آخر يحتوي على فئة Settings_Page لم يعد يمثل مشكلة ، نظرًا لأن فئته وفصلنا لن يعيشان في نفس مساحة الاسم.

عند إنشاء مثيل لصفحة Settings_Page الخاصة بنا داخل نفس مساحة الاسم ، يمكننا حذفها:

 namespace Pressidium\Limit_Login_Attempts\Pages; $settings_page = new Settings_Page();

عند إنشاء مثيل لصفحة Settings_Page الخاصة بنا خارج مساحة الاسم الخاصة بها ، يتعين علينا تحديدها على النحو التالي:

 namespace Another\Namespace; $settings_page = new \Pressidium\Limit_Login_Attempts\Pages\Settings_Page();

بدلاً من ذلك ، يمكننا استيراد صنفنا use عامل التشغيل:

 use Pressidium\Limit_Login_Attempts\Pages\Settings_Page; $settings_page = new Settings_Page();

إضافة هوك نداء

الآن ، دعنا نعلن عن هاتين add_page() و register_sections() .

 class Settings_Page { /** * Settings_Page constructor. */ public function __construct() { add_action( 'admin_menu', array( $this, 'add_page' ) ); add_action( 'admin_init', array( $this, 'register_sections' ) ); } /** * Add this page as a top-level menu page. */ public function add_page() { // TODO: Implement this method. } /** * Register sections. */ public function register_sections() { // TODO: Implement this method. } }

ستستدعي طريقة add_page () وظيفة add_menu_page () WordPress.

 public function add_page() { add_menu_page( __( 'Limit Login Attempts Settings', 'prsdm-limit-login-attempts' ), __( 'Limit Login Attempts', 'prsdm-limit-login-attempts' ), 'manage_options', 'prsdm_limit_login_attempts_settings', array( $this, 'render' ), 'dashicons-shield-alt', null ); }

يبدو أن هذه طريقة معقدة لتطوير مكونات WordPress الإضافية. إنها ببساطة تستدعي وظائف WordPress ، بخطوات إضافية.

حسنًا ، هذا ليس "قابلاً لإعادة الاستخدام" تمامًا ، فلا يزال يتعين علينا كتابة كل هذا الرمز الإضافي لكل قائمة / صفحة إدارية نريد إضافتها.

إعادة بناء التعليمات البرمجية

دعنا نمضي قدمًا ونعيد تشكيل الكود الخاص بنا قليلاً للاستفادة من البرمجة الموجهة للكائنات ولجعل الكود الخاص بنا قابلاً لإعادة الاستخدام . سنبدأ باستبدال قيمنا المشفرة في add_page() بعدة طرق ، مثل:

 public function add_page() { add_menu_page( $this->get_page_title(), // page_title $this->get_menu_title(), // menu_title $this->get_capability(), // capability $this->get_slug(), // menu_slug array( $this, 'render' ), // callback function $this->get_icon_url(), // icon_url $this->get_position() // position ); }

سنقوم بتعريف هذه الطرق على أنها protected ، بحيث يمكن الوصول إليها فقط داخل الفصل نفسه ومن خلال فصول الطفل / الوالدين.

 protected function get_page_title() { /* ... */ } protected function get_menu_title() { /* ... */ } protected function get_capability() { /* ... */ } protected function get_slug() { /* ... */ } protected function get_icon_url() { /* ... */ } protected function get_position() { /* ... */ }

رائعة! يمكننا الآن استخدام هذه الفئة كفئة عامة قابلة لإعادة الاستخدام لتمتد منها.

إعادة التصميم

قلنا لك أن هذا سيحدث على الأرجح في النهاية. ها نحن نعيد التفكير في تصميم صفنا أثناء بنائه.

نظرًا لأن هذه ستكون الفئة الأساسية الخاصة بنا ، فسنقوم بإعادة تسميتها إلى اسم أكثر عمومية ، مثل Admin_Page . حتى الآن ، يبدو الأمر كما يلي:

 class Admin_Page { /** * Admin_Page constructor. */ public function __construct() { add_action( 'admin_menu', array( $this, 'add_page' ) ); add_action( 'admin_init', array( $this, 'register_sections' ) ); } /** * Add this page as a top-level menu page. */ public function add_page() { add_menu_page( $this->get_page_title(), // page_title $this->get_menu_title(), // menu_title $this->get_capability(), // capability $this->get_slug(), // menu_slug array( $this, 'render' ), // callback function $this->get_icon_url(), // icon_url $this->get_position() // position ); } /** * Register sections. */ public function register_sections() { // TODO: Implement this method. } protected function get_page_title() { /* ... */ } protected function get_menu_title() { /* ... */ } protected function get_capability() { /* ... */ } protected function get_slug() { /* ... */ } protected function get_icon_url() { /* ... */ } protected function get_position() { /* ... */ } }

يمكننا الآن إنشاء Settings_Page منفصلة Admin_Page الأساسية .

 class Settings_Page extends Admin_Page { // ... }

هذا مثال رائع على الوراثة ، أحد المفاهيم الأساسية للبرمجة الشيئية. عند توسيع فئة ، ترث الفئة الفرعية - Settings_Page ، في هذه الحالة - جميع الأساليب والخصائص والثوابت العامة والمحمية من الفئة الرئيسية.

يمكننا الاستفادة من هذا وتعيين بعض القيم الافتراضية. على سبيل المثال ، سنقوم بتعيين رمز عام لجميع صفحات القائمة ، من خلال تحديد طريقة get_icon_url() بنا على النحو التالي:

 class Admin_Page { // ... /** * Return the menu icon to be used for this menu. * * @link https://developer.wordpress.org/resource/dashicons/ * * @return string */ protected function get_icon_url() { return 'dashicons-admin-generic'; } }

ما لم يتجاوز الفصل تلك الطرق ، سيحتفظون بوظائفهم الأصلية. لذلك ، بشكل افتراضي ، ستستخدم جميع الفئات الفرعية هذا الرمز العام.

ومع ذلك ، إذا أردنا تعيين رمز آخر لصفحة قائمة معينة ، فيمكننا ببساطة تجاوز طريقة get_icon_url() في الفصل الدراسي التابع لنا ، مثل:

 class Settings_Page extends Admin_Page { protected function get_icon_url() { return 'dashicons-shield-alt'; } }

ومع ذلك ، هناك بعض القيم التي يجب أن تكون مختلفة لكل فئة فرعية. على سبيل المثال ، يجب أن تكون قيمة القائمة - الوسيطة الرابعة لـ add_menu_page() - فريدة لكل صفحة قائمة.

إذا حددنا هذه الطريقة في فئة Admin_Page الأساسية الخاصة بنا ، فسنحتاج إلى طريقة للتأكد من أن كل فئة فرعية تتجاوز هذه الطريقة. حسنًا ، يمكننا أن نفعل شيئًا أفضل. يمكننا الإعلان عن توقيع الطريقة وتخطي تنفيذها تمامًا.

أدخل الأساليب المجردة!

فئات وطرق مجردة

الطرق المعرفة على أنها مجردة تعلن ببساطة عن توقيع الطريقة ولا يمكنها تحديد تنفيذها.

 /** * Return page slug. * * @return string */ abstract protected function get_slug();

يجب أيضًا أن تكون أي فئة تحتوي على طريقة مجردة واحدة على الأقل مجردة. هذا يعني أنه يجب تعريف فئة Admin_Page لدينا على أنها مجردة أيضًا.

 abstract class Admin_Page { // ...

من المهم أيضًا الإشارة هنا إلى أنه لا يمكن إنشاء مثيل للفئات المعرفة على أنها مجردة. لذلك ، لم يعد بإمكاننا إنشاء مثيل Admin_Page مباشرة.

إليك أيضًا تصورًا للفصل الدراسي:

عند التوريث من فئة مجردة ، يجب أن تحدد الفئة الفرعية جميع الطرق التي تم تمييزها بأنها مجردة في إعلان صنفها الأصلي. بمعنى أن صفحة Settings_Page لدينا يجب أن تنفذ طريقة get_slug() .

 class Settings_Page extends Admin_Page { // ... protected function get_slug() { return 'prsdm_limit_login_attempts_settings'; } // ... }

بنفس الطريقة ، يجب علينا تنفيذ باقي الطرق المحمية التي add_page() .

قبل الشروع في كيفية تسجيل أقسام وحقول صفحة المسؤول وعرض محتواها ، دعنا نتحدث قليلاً عن الإعدادات في WordPress.

إعدادات API

سنفترض أنك معتاد بالفعل على الإعدادات API. ولكن ، في حالة حدوث ذلك ، فإليك جوهر ذلك:

  • settings_fields () - إخراج الحقول nonce و action و option_page لصفحة الإعدادات. في الأساس ، حقول النموذج المخفية.
  • do_settings_sections () - يطبع جميع أقسام الإعدادات (وحقولها) المضافة إلى صفحة إعدادات معينة.
  • add_settings_section () - يضيف قسمًا جديدًا إلى صفحة الإعدادات.
  • add_settings_field () - يضيف حقلاً جديدًا إلى قسم من صفحة الإعدادات.
  • register_setting () - تسجل أحد الإعدادات وبياناتها.

إذا لم تكن معتادًا على هذا بالفعل ، يمكنك التوقف مؤقتًا عن قراءة هذه المقالة والتحقق من مقالتنا ذات الصلة حول كيفية إنشاء صفحة الإعدادات لمكوِّن إضافي مخصص.

الآن بعد أن أصبحنا في نفس الصفحة ، دعنا نعود إلى طريقة register_sections() الخاصة بنا. مرة أخرى ، علينا أن نتراجع ونفكر في API الخاص بنا.

نظرًا لأننا حددنا طريقة add_page() في فئة Admin_Page ، فسنقوم أيضًا بتعريف طريقة العرض render() هناك أيضًا. سنقوم بتمرير قيم الإرجاع لطرقنا الأخرى كوسيطات إلى وظائف WordPress.

 abstract class Admin_Page { // ... /** * Render this admin page. */ public function render() { ?> <div class="wrap"> <form action="options.php" method="post"> <h1><?php echo esc_html( $this->get_page_title() ); ?></h1> <?php settings_fields( $this->get_slug() ); do_settings_sections( $this->get_slug() ); submit_button( __( 'Change Options', 'prsdm-limit-login-attempts' ) ); ?> </form> </div> <?php } }

بهذه الطريقة ، لن نضطر إلى الاهتمام مباشرة بوظائف WordPress هذه مرة أخرى. ذلك لأن أي صفحة مسؤول قد نضيفها في المستقبل سيتم بناؤها من خلال فئة فرعية تمامًا مثل Settings_Page ، وسيتم عرضها من خلال طريقة العرض render() الموروثة للفئة الرئيسية Admin_Page .

استنتاج

رائعة! أنشأنا الفئات المسؤولة عن تسجيل قائمة الإدارة وإضافة صفحة إعدادات.

في المقالة التالية من السلسلة ، سنستمر في بناء صفحة الإعدادات الخاصة بنا ونسجل أقسامها وحقولها وعناصرها.

انقر هنا لقراءة الجزء 6 في سلسلة البرمجة الشيئية

أنظر أيضا

  • WordPress and Object-Oriented Programming - نظرة عامة
  • الجزء 2 - WordPress والبرمجة الموجهة للكائنات: مثال من العالم الحقيقي
  • الجزء 3 - WordPress والبرمجة الموجهة للكائنات: مثال WordPress - تحديد النطاق
  • الجزء 4 - WordPress والبرمجة الموجهة للكائنات: مثال على WordPress - التصميم