ماژول نویسی دروپال بخش یک
ماژول نویسی دروپال بخش سه
ماژول نویسی دروپال بخش چهار
ماژول نویسی دروپال بخش پنج
ماژول نویسی دروپال بخش شش
ماژول نویسی دروپال بخش هفت
ماژول نویسی دروپال بخش هشت
در بخش اول با ساختار کلی یک ماژول، نحوهی کار هوکها (قلابها)، سیستم منو و استانداردهای کد نویسی آشنا شدیم. در این مقاله در مورد ساختار فرمها صحبت میکنیم.
تا اینجا، آیتمهای منوی ماژول رو به این صورت به دروپال معرفی کردیم:
/** * Implements hook_menu() */ function drupalion_menu() { // Administration page. $items['admin/drupalion'] = array( 'title' => 'Drupalion module', 'page callback' => 'drupal_get_form', 'page arguments' => '_drupaion_get_form', 'access argument' => array('access administrative pages'), 'type' => MENU_LOCAL_TASK, ); return $items; }
با مراجعه به مسیر معرفی شده (admin/drupalion) تابع drupal_get_form صدا زده خواهد شد. این تابع، آرگومان _drupal_get_form را دریافت میکند و انتظار دارد نام تابعی باشد که ساختار فرمی را برمیگرداند.
صحبتی در مورد فرمها:
برای نوشتن Applicationهای تحت وب، یکی از چیزهایی که به طور مکرر به آن احتیاج پیدا میکنیم، ورود اطلاعات از طرف کاربر است. این کار مستلزم رعایت نکات مهمیست، مثل اعتبارسنجی اطلاعات وارد شده تا به سایت و اطلاعات ذخیره شده آسیبی وارد نکند. باید از ورود دادههای مخربی که خود باعث اجرا شدن و آسیبپذیر شدن وبسایت میشود نیز جلوگیری شود. از آنجایی که مقدار زیادی از کارهایی که باید انجام دهیم برای هر فرم ورود داده یکسان و تکراریست، میتوان بخشی را برای مدیریت اختصاصی آن توسعه داد. تولید کدهای HTML برای نمایش فرمها، به خصوص اگر بخواهیم کدهای جاوااسکریپتی را نیز در نظر بگیریم، کار فوقالعاده طاقتفرساییست. دروپال، مثل بسیاری از فرمورکهای دیگر، دارای API اختصاصی برای مدیریت فرمها به نام Form API یا به اختصار FAPI هست. FAPI کارها را آسان، زندگی را شاد و همه را خوشحال میکنه!
هر فرم، داری دو آرایه مجزاست، یکی برای تعریف ساختار فرم، و دیگری برای ذخیره دادههای ورودی و اعمال انجام شده توسط کاربر. بر اساس یک قانون کلی، در PHP آرایهی اول رو همیشه $form و دومی رو $form_state (وضعیت فرم) نامگذاری میکنیم. این دو آرایه بین توابع محتلف منتقل میشه تا ساختار نهایی فرم شکل بگیره و به کاربر نشان داده بشه. برای ماژول ما، تعریف این دو آرایه در drupal_get_form صورت میگیره و از صرف این تابع، به تابع ما ارسال میشه. پس باید تابع خودمون رو متناسب با نحوهی فراخوانیش تعریف کنیم. به علامت & قبل از form_state توجه کنید:
function _drupalion_get_form($form, &$form_state) { // Do some form processing here; return $form; }
یک سوال: $form و $form_state که به این تابع فرستاده شدند، حاوی چه اطلاعاتی هستند؟
جادوی DEVEL
از قابلیتهای مهمی که «هرچیزی» در صنعت کامپیوتر باید داشته باشه، قابلیتهای اشکالزدایی هست. یک المان سختافزاری، یک سیستم جامع سختافزاری، سیستمعامل و یک فریمورک تحت وب، بدون این قابلیت درواقع هیچ ارزشی ندارند. در دروپال، برای رفع این نیاز، ماژول Devel وجود داره. ابزار جالی میشه توی این ماژول پیدا کرد: DNA - Devel Node Access برای اشکالزدایی دسترسیهای تعیین شده برای هر محتوا، Query Logs برای نمایش درخواستهای ارسال شده به پایگاه داده و ابزار مورد نیاز ما در این بخش: توابع dpm() و dargs(). توابع دیگری هم مثل dd برای زمانی که استفاده از dpm و dargs ممکن نیست و ddebug_backtrace برای backtrace هر تابع هم وجود دارند، لیست کامل این توابع رو با کمی جستوجوی گوگلی میتونید پیدا کنید. توجه کنید که با وجود قدرت بسیار زیاد و انعطافپذیریشون، یک مشکل امنیتی بزرگ برای هر سایتی حساب میشن! پس تا حد امکان نباید روی سرورهای اصلی استفاده شوند (اگرچه کاربران بدون مجوز view debug information چیزی نخواهند دید).
با استفاده از devel به این صورت:
function _drupalion_get_form($form, &$form_state) { dpm($form, 'form'); dpm($form_state, 'form_state); dargs(FALSE); }
خروجیهای جالبی خواهید گرفت. $form_state حاوی اطلاعات اولیه هر فرم و $form خالیست! توضیح بیشتر در مورد این ابزار از حوصلهی این مقاله خارجه پس وقت بیشتری رو به devel اختصاص نمیدیم.
برمیگردیم به تعریف ساختار فرم:
function _drupalion_get_form($form, &$form_state) { $form['drupalion_info'] = array( '#type' => 'item', '#markup' => t('Hello World!!!'); ); // Remove comment from line below to see what's happening. // dpm($form, 'Our generated form'); return $form; }
تا اینجا، فرم ما دارای یک آیتم به نام drupalion_info هست، که ساختار این آیتم هم توی یک آرایهی مجزا تعریف میشه. هر کلیدی که با علامت # شروع شده باشه، اعلانی به FAPI در مورد یکی از خصیصههای المان تعریف شده است. #type که در ۹۹درصد مواقع! برای هر المانی مورد نیازه، تعیین کنندهی نوع المان (متنی، فیلد متنی، کادر، فهرست انتخاب، و ...) هست. نوع المان ما، 'item' قرار داده شده، یعنی المانی ساده حاوی یک متن - که میتوانید HTML هم باشد. برای هرنوع المان، تعریف یکسری از خصیصهها اجباری و یکسری اختیاریست. برای المانهای نوع item، خصیصه اجباری #markup هست که تعیین کنندهی متن اونهاست.
نکتهی مهم امنیتی: اگر متنی به فرم وارد میشود که منبع اون مشخص نیست، حتما باید از توابع کنترل متن دروپال عبور کند تا حروف غیر مجاز اون حذف شود. بر حسب سطوح دسترسی متفاوت توابع مختلفی برای اینکار وجود دارد مثل check_plain، filter_xss و ... که با مراجعه به راهنمای توسعه دروپال میتوانید اطلاعات بیشتری کسب کنید.
حالا اگر به صفحهی ماژول سر بزنیم، متن خودمون رو میبینیم. به همین سادگی!
در قسمت بعدی مقاله در مورد تابع t که در قطعه کد بالا استفاده کردیم و توضیحات بیشتر در مورد ساختار فرمها و نحوهی ورود داده میپردازیم.
شاد و موفق باشید