نوشتن ماژول در دروپال 7 - بخش چهار

By کوشا حسینی, 26 سپتامبر, 2013

ماژول نویسی دروپال بخش یک
ماژول نویسی دروپال بخش دو
ماژول نویسی دروپال بخش سه
ماژول نویسی دروپال بخش پنج
ماژول نویسی دروپال بخش شش
ماژول نویسی دروپال بخش هفت
ماژول نویسی دروپال بخش هشت

چند راه برای ذخیره‌ی داده‌ها در پایگاه داده وجود داره. استفاده از موجودیت‌ها (entity) و افزودن فیلد به اون‌ها یک راه و راه دیگر، ساخت جداولی (Table) در پایگاه داده و وارد کردن داده‌ها به صورت دستی در این جداول هست. تعریف موجودیت‌ها در ماژول مزیت‌هایی از جمله برخورداری از پشتیبانی ماژول‌های Rules، Views، Entity، Features ، تولید خودکار فرم برای ورود داده و ... هست. اما تعریف موجودیت‌ها رو در مقاله‌های بعدی توضیح می‌دم و در این بخش روش دستی رو بررسی می‌کنیم.

در دروپال، در حد امکان، از ارتباط مستقیم با پایگاه داده خودداری می‌کنیم. به ندرت (و شاید هیچ وقت!) در کدهای ماژول‌های موجود، ساخت PDO که در PHP وظیفه‌ی ارتباط با پایگاه داده رو داره نمی‌بینیم. در عوض، دروپال ابزاری به نام Database abstraction layer یا لایه‌ی تجرد پایگاه داده که ما برای راحتی کار! اون رو لایه‌ی جدا کننده‌ی پایگاه داده می‌نامیم در اختیار توسعه‌دهندگان می‌زاره. از مزیت‌های وجود چنین لایه‌ای، عدم نیاز به نوشتن کدهای SQL هست چرا که در نهایت باعث وابستگی به یک پایگاه داده‌ی مشخص می‌شه. همچنین به علت عوض شدن زمینه‌ی کاری (در حینی که روی کدهای PHP کار می‌کنیم باید ذهن‌مون رو برای کدهای SQL آماده کنیم) اشکال‌زدایی و توسعه کدها هم کار مشکل‌تری خواهد بود. بحث بیشتر در مورد مزیت‌های وجود چنین ابزاری (در هر فریم‌ورکی) رو با کمی جست‌وجو می‌تونید پیدا کنید.

مثل همیشه برای تعریف جداول (یا در آینده entityها) باید آرایه‌ی توصیف کننده‌ی ساختارشون رو بنویسیم. این آرایه رو در هوک MODULE_schema قرار می‌دیم (با سیستم هوک‌ها و نحوه‌ی پیاده‌سازی در ماژول قبلا آشنا شدیم). خود این هوک، در فایلی با قالب MODULE.install قرار می‌گیره. در زمان نصب ماژول، این فایل توسط دروپال پیدا و بارگذاری می‌شه و از هوک مربوطه ساختار جدول دریافت و در پایگاه داده ایجاد می‌شه. اما این نکته رو برای جلوگیری از سردرگمی‌های بعدی بهتره بدونیم که نصب ماژول، فقط در اولین فعال شدنش صورت می‌گیره، و در غیرفعال-فعال کردن‌های بعدی، هوک schema از فایل .install صدا زده نمی‌شه. پس ما برای اضافه کردن schema به ماژول my_calculator، لازمه اون رو حتما uninstall و مجددا نصب کنیم. عمل uninstall هم باعث پاک شدن هر جدولی که فبلا به خاطر install ایجاد شده می‌شه (به شرطی که از hook_schema استفاده کرده باشیم).

کاری که در این بخش برای ماژول my_calculator انجام می‌دیم، ایجاد امکان ذخیره‌ی نتیجه‌ی محاسبه در پایگاه داده خواهد بود، تا کاربر در مراجعات بعدی، نتیجه‌ی آخرین محاسبه‌ی خودش رو ببینه. برای ذخیره‌ی نتیجه به چند فیلد در جدول احتیاج داریم: یک فیلد عدد اعشاری، برای ذخیره‌ی نتیجه‌ی محاسبه، یک فیلد عدد صحیح برای ذخیره‌ی شناسه‌ی کاربری که نتیجه‌ی محاسبه رو به دست آورده و یک فیلد سریال (فیلد عددی که به صورت خود کار از ۱ شروع به شمارش می‌کنه) به عنوان کلید اصلی جدول. البته از شناسه‌ی کاربر هم می‌تونیم استفاده کنیم ولی در توسعه ماژول برای ذخیره‌ی چندین نتیجه‌ی برای یک کاربر به مشکل برمی‌خوریم. اما این انواع داده که در هر پایگاه داده‌ای متفاوتند، در توصیف جداول پایگاه داده‌ی دروپال به چه صورت تعریف می‌شه؟ بهتره نگاهی به انواع داده‌ی پشتیبانی شده‌ی API مربوط بع تعریف schema در صفحه‌ی مرجع بندازید.
افزودن هر فیلد به ساختار جدول با مشخص کردن نوع داده‌ی اون، تعریف خصیصه‌های مربوطه (مثل حداکثر اندازه) و نامش صورت می‌گیره. فایل .install برای ماژول my_calculator به این شکل خواهد بود:

<?php
/**
 * @file
 * Install file for my_calculator.
 */

/**
 * Implements hook_schema().
 *
 * Defines a table in database so users can store result of calculation.
 */
function my_calculator_schema() {
  $schema['my_calculator_result'] = array(
    'description' => 'Stores result of calculations by my_calculator module',
    'fields' => array(
      'rid' => array(
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'uid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
      ),
      'result' => array(
        'type' => 'float',
        'unsigned' => FALSE,
        'not null' => FALSE,
        'size' => 'big',
      ),
    ),
  );

  return $schema;
}

توضیحات:

  • در صورتی که به بیش از یک جدول در پایگاه داده احتیاج داشتیم، می‌تونیم اون‌ها رو به آرایه‌ی $schema اضافه کنیم. در اینجا ما فقط جدولی به نام my_calculator_result ساختیم.
  • نام جدول ما، دارای پیشوندی یکسان با نام ماژول است. این کار اصل خیلی مهمی در دروپال حساب می‌شه: هرچیزی که از طرف ماژول در فضای عمومی در میان اطلاعات سایر ماژول‌ها تعریف می‌شه، باید با نام ماژول شروع بشه. یعنی نام توابع، نام انواع جدید فیلدهایی که در ماژول خودمون تعریف می‌کنیم، نام جداولی که در پایگاه داده خواهیم ساخت و .....
    همچنین این موضوع من رو به یاد مطلبی به نام Convention over configuration می‌ندازه. به شما پیشنهاد می‌کنم جست‌وجویی در اینترنت در رابطه با اون داشته باشید.
  • تمام فیلدهای جدول، در کلید 'fields' تعریف می‌شن، هر فیلد هم باز آرایه‌ایست که فیلد رو توصیف می‌کنه. تعیین نوع داده برای هر فیلد اجباریه اما سایر خصیصه‌ها می‌تونن اختیاری باشن.
  • خصیصه‌های اختیاری در زمان ساخت جدول دروپال برای اون‌ها پیش‌فرض‌هایی داره. اگر این مقدار پیش‌فرض مناسب نیست حتما باید توی ساختار ذکر بشه (مثل not null).

اما کلید اصلی جدول و شاخص‌ها (index) چطور؟ لازمه که حتما کلید اصلی رو در اعلان ساختار جدول تعیین کنیم. برای اینکار فیلد rid مخفف result_id رو در جدول در نظر گرفتیم، و کافیه به عنوان کلید اصلی معرفیش کنیم. اندیس‌ها هم به طور مشابهی معرفی می‌شوند، برای اطلاعات جامع‌تر به drupal.org مراجعه کنید.

    'fields' => array(
        // Defination of fields removed, to make code more readable, see code snippet above.
        .......
    ),

    'primary key' => array('rid'),
    'indexes' => array(
      'uid' => array('uid'),
      'uid_and_rid' => array('uid', 'rid'),
    ),
  );
  
   return $schema;
}

توضیحات:

  • برای تعریف کلید اصلی می‌تونستیم از ترکیب چندین فیلد تعریف شده، مثلا uid و rid استفاده کنیم، اما برای جدول ما ازاونجایی که rid صرفا برای کلید اصلی قرار داده شده استفاده از کلید اصلی ترکیبی لازم نبود.
  • در شاخص‌ها (index)، دو شاخص تعریف کردیم، یک شاخص تکی، و یکی ترکیبی. نام شاخص‌ها (در اینجا uid و uid_and_rid) دو نام دلخواه بودن که برای خوانایی بیشتر بر اساس فیلدهایی که شاخص به اون‌ها تعلق می‌گیره انتخابشون کردیم. شاخص ترکیبی تعریف شده فقط جنبه‌ی آموزشی برای تعریف شاخص ترکیبی داره و در ماژول ما هیچ فایده‌ای نداره. فیلدهایی که شاخص به اون‌ها تعلق می‌گیره همیشه در آرایه قرار می‌گیرن، حتی اگر فقط یک فیلد وجود داشته باشه.

دروپال امکان تعریف کلیدهای یکتا (unique keys) و همچنین کلیدهای خارجی (foreign keys) رو هم میده. در مورد کلیدهای خارجی، foreign keys، باید بدونید که فقط جنبه‌ی Documention یا راهنما رو دارند و واقعا توسط دروپال ایجاد نمی‌شن. اگر حتما لازمه که این کلیدهارو ایجاد کنید، این کار باید در هوکی به نام hook_install در همین فایل انجام بشه که متاسفانه دردسرهای خودشو داره.

با اتمام تعریف ساختار جدول، باید ماژول رو از اول نصب کنیم تا جدول ما ساخته بشه. به جای اجرای سه دستور غیرفعال کردن، حذف کردن، و فعال کردن مجدد، Drush دستور خلاصه‌ای (فقط اگر ماژول devel نصب باشه) برای اینکار داره:

bash~> drush dre MODULE_NAME
bash~> drush dre my_calculator

اگر با ابزار پایشگر پایگاه داده، به پایگاه داده‌ی دروپال وصل بشید، خواهید دید که جدول مورد نظر با ساختار تعریف شده و نام my_calculator_results ساخته شده.

در این مقاله، ایجاد جداول در پایگاه داده رو بررسی کردیم و در مقاله‌ی بعدی، ذخیره‌ی داده‌ها در اون رو بررسی می‌کنیم.

ماژول آماده شده با فایل .install در فایل ضمیمه موجود است.
شاد و موفق باشید.

تگ های مطلب
دسته بندی مطلب