joomla 5

فصل چهارم: ایجاد فرم در جوملا

(زمان تقریبی مطالعه: 20 - 39 دقیقه)

بیان خلاصه ای از بحث توسط هوش مصنوعی:

فرم های HTML بخش مهمی از توسعه وب هستند زیرا به شما امکان می دهند اطلاعاتی را از کاربران خود بخواهید. در جوملا می توانیم فرم های خود را با یک فایل XML ساده تعریف کنیم. Joomla Framework TM تقریباً از تمام کارها مراقبت می کند.

در این فصل با نحوه ایجاد فرم های HTML در جوملا آشنا می شویم. ما یاد خواهیم گرفت که چگونه فیلدهای فرم را که قبلاً در جوملا توسعه داده اند اضافه کنیم و چگونه فیلدهای فرم سفارشی را ایجاد کنیم. همچنین یاد خواهیم گرفت که چگونه ورودی کاربران خود را قبل از ارسال فرم تأیید کنیم و چگونه داده های سمت سرور را بررسی کنیم.

موضوعات اصلی این فصل عبارتند از:

  • تعریف فرم ها در جوملا
  • استفاده از فیلدها استاندارد جوملا
  • تعریف انواع فیلد فرم سفارشی
  • با استفاده از فیلد subform
  • اعتبار سنجی ورودی کاربر در سمت مشتری
  • اعتبار سنجی ورودی کاربر در سمت سرور

در پایان این فصل، می توانید فرم های مختلفی را به افزونه های خود اضافه کنید و داده های ارسال شده توسط آنها را بازیابی کنید.

الزامات فنی

در این فصل، ما به بهبود افزونه Simple Project Manager خود ادامه خواهیم داد، بنابراین شما به موارد زیر نیاز دارید :

  • Visual Studio Code (یا ویرایشگر کد دلخواه شما)
  • سایت جوملا که در فصل های قبل نصب کردیم

می توانید فایل های کد این فصل را در GitHub در آدرس زیر بیابید:

 https://github.com/PacktPublishing/Developing-Extensions-for-Joomla-5/tree/chapter04 

تعریف فرم ها در جوملا

کلاس form  جوملا روش ایجاد فرم های HTML را برای پروژه های وب خود ساده و استاندارد می کند. در جوملا 1.5 معرفی شد و از آن زمان بهبود یافته است.

فرم ها در جوملا در یک فایل XML تعریف می شوند که در آن تمام فیلدهایی که فرم شما نیاز دارد و ویژگی های اصلی آنها را اضافه می کنید. جوملا سپس این اطلاعات را پردازش می کند و یک فرم و تعریف فیلد مناسب ایجاد می کند.

این فرآیند شما را از پرداختن به تعریف فیلد ورودی HTML نجات می دهد و روش ایجاد فرم های خود را استاندارد می کند. همچنین به شما این امکان را می دهد که با تلاش بسیار کمی از رابط های پیچیده تر در افزونه های خود استفاده کنید. یک مثال خوب در این زمینه فیلد accessiblemedia  است که در جوملا 4 معرفی شد، که نه تنها به کاربر اجازه می دهد یک تصویر را اضافه کند، بلکه با برخی از ویژگی های دسترسی را همراه است.

اما بهتر از همه، مدیریت فرم ها در جوملا MVC  در افزونه ها در هنگام استفاده مانند جادو است.

سه مورد اصلی برای استفاده از فرم ها در کامپوننت ما در جوملا وجود دارد:

  • افزودن گزینه های کلی به افزونه های ما
  • افزودن قابلیت های جستجو و فیلتر به لیست های ما
  • ویرایش یا اضافه کردن موارد جداگانه

تعریف فرم در همه این موارد یکسان خواهد بود: یک فایل XML با فیلدها و تمام خصوصیات آنها. با این حال، نحوه نمایش فرم ها در هر سناریو متفاوت خواهد بود. این موارد را در بخش های بعدی به تفصیل بررسی خواهیم کرد.

افزودن گزینه های کلی به افزونه های ما

این خیلی معمول است که مجموعه ای از تنظیمات کلی داشته باشیم که برای همه اجزای ما اعمال می شود. در افزونه مدیریت پروژه ساده، می توانیم از این تنظیمات کلی برای ذخیره داده های شرکتمان مانند نام ، آدرس و شماره شناسه استفاده کنیم. برای افزودن این گزینه ها به کامپوننت خود، باید فایل src/component/admin/config.xml  را ایجاد کنیم. این فایل حاوی تعریف XML فرم ما است:

 
<?xml version="1.0" encoding="utf-8"?> 
<config> 
    <fieldset name="company_data" label="COM_SPM_CONFIG_FIELDSET_COMPANY_DATA_LABEL" description="COM_SPM_CONFIG_FIELDSET_COMPANY_DATA_DESCRIPTION" > 
        <field 
            type="text" 
            label="COM_SPM_CONFIG_COMPANY_NAME_LABEL" 
            description="COM_SPM_CONFIG_COMPANY_NAME_DESCRIPTION" 
        /> 
        <field 
            type="text" 
            label="COM_SPM_CONFIG_COMPANY_ADDRESS_LABEL" 
            description="COM_SPM_CONFIG_COMPANY_ADDRESS_DESCRIPTION" 
        /> 
        <field 
            type="text" 
            label="COM_SPM_CONFIG_COMPANY_ID_LABEL" 
            description="COM_SPM_CONFIG_COMPANY_ID_DESCRIPTION" 
        /> 
    </fieldset> 
</config> 
 

این کد با تعریف شروع می شود فرمت سند  XML، مانند فایل مانیفست XML که در فصل 2 ، توسعه Backend یک کامپوننت ساده در جوملا دیدیم و محتوای اصلی فایل بین تگ های config  آمده است. این محتوای اصلی تعریف فرم ما است و جایی است که می توانیم فیلدهای خود را در مجموعه های مختلف گروه بندی کنیم.

ما فیلدها را در مجموعه  های فیلدهای مختلف در XML گروه بندی می کنیم، زیرا هنگام اجرا کردن، هر مجموعه فیلد (field) را در یک تب خاص نشان می دهد. هر مجموعه فیلد ممکن است دارای مشخصات نام (name) ، برچسب (label) و توضیحات (description) باشد.

از label به عنوان نام برگه هنگام رندر کردن فرم استفاده می شود.

در این کد از فیلدهای نوع متن استفاده کرده ایم. در ادامه در بخش استفاده از انواع فیلدهای استاندارد فرم، در مورد انواع فیلدهایی که می توانیم استفاده کنیم بیشتر خواهیم آموخت.

پس از افزودن این فایل جدید، باید آن را در مانیفست کامپوننت قرار دهید تا جوملا آن در پوشه صحیح قرار دهد. بنابراین، فایل src/component/spm.xml  خود را ویرایش کنید و فایل config.xml  را به صورت زیر در تگ file  قسمت مدیریت قرار دهید:

 
<files folder="admin"> 
    <folder>forms</folder> 
    <folder>services</folder> 
    <folder>src</folder> 
    <folder>tmpl</folder> 
    <file>access.xml</file> 
    <file>config.xml</file> 
</files> 
 

 ما فایل را با استفاده از تگ file  در XML  گنجانده ایم.

نمایش گزینه های فرم در کامپوننت ما

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

برای اینکه فرم خود را در عمل ببینیم، فقط باید به backend  جوملا خود برویم و روی System Global Configuration  کلیک کنید، در سمت چپ صفحه، لیستی با تمام اجزای نصب شده مشاهده می کنیم و برای دیدن گزینه های خود، روی COM_SPM  کلیک می کنیم.

از طرف دیگر، می توانید به آدرس زیر بروید:

yoursite.com/administrator/index.php?option=com_config&view=component&component=com_spm 

افزودن قابلیت های جستجو و فیلتر به لیست های ما

کلاس ListModel جوملا با یک روش استاندارد برای افزودن فیلتر به لیست های ما ارائه می شود. اگر تعریف کلاس ListModel را در نصب جوملا خود بررسی کنید (در libraries/MVC/Model/ListModel.php)، ممکن است متد getFilterForm را بیابید.

این متد، فایلی به نام filter_ModelName.xml  را بررسی می کند و یک فرم جوملا برای فیلتر کردن ایجاد می کند. بیایید یک فیلتر اساسی به لیست پروژه های خود اضافه کنیم.

فایلی به نام src/component/admin/forms/filter_projects.xml ایجاد کنید که حاوی کد زیر باشد:

 
<?xml version="1.0" encoding="UTF-8"?> 
<form> 
    <fields name="filter"> 
        <field 
            name="search" 
            type="text" 
            label="COM_SPM_PROJECTS_FILTER_SEARCH" 
            /> 
    </fields> 
</form> 
 

 این فرم یک فیلد متنی خواهد بود که در آن مدیر، نام پروژه ها یا هر کلمه ای را در توضیحات پروژه تایپ می کند. باید فیلد را داخل تگ fields قرار دهیم تا به جوملا بگوییم که یک فرم فیلتر است. پس از افزودن فرم، باید به view دستور دهیم که فرم را از مدل بازیابی کند.

بنابراین، باید کد برجسته شده را به متد display  خود در آدرس  src/component/admin/src/View/HtmlView.php  اضافه کنیم.

 
public $filterForm; 
public function display($tpl=null): void 
{ 
    ... 
    $this->filterForm    = $this->get('FilterForm'); 
    $this->activeFilters = $this->get('ActiveFilters'); 
    ... 
} 

 در این کد، ویژگی filterForm  را اعلام می کنیم که در آن داده های فرم را ذخیره می کنیم.

هنگام استفاده از this-&gt;get('FilterForm')  ، کاری که ما انجام می دهیم فراخوانی متد getFilterForm  از مدل است. همانطور که ما در حال گسترش کلاسListModel  برای پروژه خود هستیم، جوملا مراقب دریافت فرم فیلتر از فایل XML است.

ما همچنین ویژگی activeFilters  را تنظیم کردیم تا از فیلترهایی که روی داده های ما اعمال می شود آگاه باشیم.

در نهایت باید فیلتر را با استفاده از ویژگی filterForm  در فایل قالب خود قرار دهیم. در مرحله بعد، ما می خواهیم به روش جوملا برای نشان دادن این فیلتر نگاه کنیم.

نمایش فرم فیلتر در لیست پروژه ها

برای نمایش فیلتر در لیست خود، باید از ویژگی filterForm  برای بازیابی تمام اطلاعات فیلد استفاده کنیم.

ویژگیform  حاوی یک آبجکت از کلاس Form  است. این آبجکت شامل تمام فیلدهای تعریف شده در فایل XML ما است. این فیلدها در فیلد fields property آبجکت ذخیره می شوند.

API جوملا یک راه آسان برای نمایش این فیلتر فراهم می کند. استفاده از جوملا برای نمایش فیلترها نیز تجربه کاربری ثابت تری را به کاربران شما ارائه می دهد.

برای نشان دادن فرم فیلتر در لیست پروژه هایمان، باید چیدمان خود را ویرایش کنیم و کد برجسته شده ی زیر را در ابتدای کار خود قرار دهیم. فرم در آدرس src/component/admin/tmpl/projects/default.php ، درست زیر تگ form  قرار میگیرد.

از Joomla\CMS\Layout\LayoutHelper استفاده کنید.

 
<form action="<?php echo Route::_('index.php?option=com_spm&view=projects'); ?>" method="post" name="adminForm" id="adminForm"> 
… 
<div class="row"> 
    <div class="col-md-12"> 
        <?php echo LayoutHelper::render('joomla.searchtools.default',         ['view' => $this]); ?> 
    </div> 
</div> 

در این کد، ما از کلاس های Bootstrap 5 برای ارائه یک استایل طراحی شده به view استفاده کردیم. سپس از کلاس LayoutHelper  برای رندر کردن چیدمان تعریف شده در سایت جوملا در /layouts/joomla/searchtools/default.php استفاده می کنیم. با این کار تمام فیلدها در فرم ما نمایش داده می شوند، از جمله دکمه ارسال.

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

دریافت اطلاعات فیلدها در مدل

ما نه تنها نیاز به تعریف و نمایش فرم ها به کاربران خود داریم، بلکه باید از این اطلاعات در مدل خود برای فیلتر کردن داده ها مطابق با انتخاب کاربران خود استفاده کنیم.

دریافت این داده ها در مدل ما منطقی است. این به ما کمک می کند تا فرآیند بازیابی داده های خود را بهینه کنیم، زیرا پایگاه داده خود را با تمام محدودیت های فیلتر، پرس و جو می کنیم.

ما می خواهیم این فیلترها، در هر درخواستی که کاربران ما می کنند، وجود داشته باشد. تصور کنید که کاربری فهرست چند صفحه ای ما را بر اساس دسته بندی، فیلتر می کند و روی صفحه دوم کلیک می کند. ما می خواهیم مدل ما زمینه را به خاطر بسپارد و نتایج بعدی را برای فهرست آن دسته ارائه دهد. همچنین، فیلترهای ما باید در هر جلسه در سایت خاص باشند، بنابراین منطقی است که تمام اطلاعات فیلترها را در مدل و متد populateState  اضافه کنیم.

اگر متد ()populateState فعلی خود را بررسی کنیم، می توانیم برخی از فیلترها مانند همه متغیرهای صفحه بندی (list.limit، list.start و غیره) را مشاهده کنیم که اعمال می شوند. بیایید درخواست برای دریافت فیلتر جستجو را اضافه کنیم.

 فایل src/component/admin/src/Model/ProjectsModel  را ویرایش کنید و در بالای فراخوانی متد والد ()populateState ، خطوط برجسته زیر را اضافه کنید :

 
protected function populateState($ordering = 'name', $direction = 'ASC') 
{ 
    … 
    $search = $this->getUserStateFromRequest( 
        $this->context 
        . '.filter.search', 'filter_search' 
    ); 
    $this->setState('filter.search', $search); 
    Parent::populateState($ordering, $direction); 
} 

 با این کار، ورودی کادر جستجو را از درخواست دریافت می کنیم و آن را با نام filter.search به وضعیت فعلی خود اضافه می کنیم.

هنگامی که این کار را انجام دادیم، می توانیم وضعیت موجود در متد getListQuery()  مدل خود را بازیابی کنیم و از آن برای اصلاح کوئری خود استفاده کنیم. ما آن را قبل از تعریف دستور متغیر $orderCol  متد getListQuery()  با استفاده از آن اضافه می کنیم این کد:

 
protected function getListQuery() 
{ 
    … 
    $search = $this->getState('filter.search'); 
    if (!empty($search)) 
    { 
        $search = $db->escape(trim($search), true); 
        $search = str_replace(' ', '%', $search); 
        $search = $db->quote('%' . $search . '%')); 
        $query->where('(a.name LIKE ' . $search . ')'); 
    } 
    $orderCol = 
        $this->state->get('list.ordering', 'a.name'); 
    … 
} 

 در اینجا، متغیر filter.search را از فرم درخواست می کنیم و بررسی می کنیم که آیا مقداری دارد یا خیر.

در داخل بلوک  if ، باید مقدار جستجو را پردازش کنیم تا بهترین نتایج را ارائه دهیم:

  1. ابتدا باید تمام فضاهای سفید شروع و پایان را حذف کنیم و مقدار را از طریق متد  escape() از کلاس $db  خود عبور دهیم. این امر ضروری است، زیرا ورودی ارائه شده توسط کاربر است و ما نمی  خواهیم حمله نفوذ SQL را به خطر بیندازیم. (در فصل 13 بیشتر در مورد اقدامات امنیتی یاد خواهیم گرفت.)
  2. در مرحله بعد، برای انجام یک جستجوی MySQL LIKE ، باید فضاهای خالی در پرس و جوی متنی خود را با نماد %  جایگزین کنیم. این زمانی مفید است که مقدار جستجو شده یک رشته چند کلمه ای باشد، زیرا به دنبال تمام کلمات موجود در متن و نه تنها رشته مورد نظر می گردد.
  3. آخرین تغییری که روی مقدار  $search انجام دادیم ، اضافه کردن نقل قول های مناسب برای پایگاه داده برای جستجوی رشته در پایگاه داده است. با آن، ما به سادگی جست و جوی نهایی را به آن اضافه می کنیم تا متن داخل نام پروژه ها را جست و جو کنیم.

اکنون می توانیم فیلدهای بیشتری را به فرم فیلتر اضافه کنیم و یک ابزار جستجوی عالی برای کاربران خود فراهم کنیم. اما کارهای زیادی وجود دارد که می توانیم با فرم ها در جوملا انجام دهیم. در بخش بعدی، خواهیم دید که چگونه می توانیم صفحات ویرایش افزونه خود را با استفاده از  فرم های جوملا تقویت کنیم.

ویرایش یا اضافه کردن آیتم های فردی

در فصل 2 (توسعه Backend کامپوننت جوملا)، ما فرم ویرایش پروژه خود را ایجاد کردیم. آنجا، ما هر فیلد را مستقیماً در طرح خود با استفاده از آبجکت Form  مدل ارائه شده، نمایش دادیم.

این امر به ما کنترل کامل ترتیب فیلدها را داد. به عنوان مثال، ممکن است کد HTML را در اطراف فیلدها تغییر دهیم، یا ممکن است برخی از فیلدهای فرم خود را حذف کنیم، فقط آنها را در فایل چیدمان خود لحاظ نکنیم. بنابراین، به عنوان مثال، اگر ما نمی خواهیم اجازه دهیم مهلت پروژه ویرایش شود، می توانیم فقط فیلد را از فایل TPL خود حذف کنیم.

اما اگر شما هم مثل من تنبل هستید، راه سریع تری برای نمایش تمام فیلدهای فرم در جوملا وجود دارد:

می توانیم متدهای رندر Form  را فراخوانی کنیم تا فرم را برای ما نمایش دهد. در فایل  src/component/admin/tmpl/project/edit.php  ، فراخوانی های $this-&gt;form-renderField()  را که در فصل 2 اضافه کردیم ، با کد زیر جایگزین کنید:

 
<?php foreach ($this->form->getFieldset() as $field) :?> 
    <?php echo $field->renderField(); ?> 
<?php endforeach;?> 
 

این کد تمام فیلدهای فرم ما را مطابق با تعریف XML در فایل فرم ما نشان می دهد:

 src/component/admin/forms/project.xml

تا کنون فرم های مختلفی را به کامپوننت اضافه کرده ایم اما فقط از فیلدهای متنی برای آن ها استفاده می کنیم. در بخش بعدی، انواع دیگری از فیلد ها را که می توانیم برای بهتر کردن فرم خود استفاده کنیم، بررسی خواهیم کرد.

استفاده از فیلدهای فرم استاندارد جوملا

فقط استفاده از فیلدهای ورودی متن برای همه پروژه های شما کار می کند، زیرا راهی جهانی برای دریافت ورودی کاربر در وب است. با این حال، تجربه کاربری بسیار بدی ایجاد می کند زیرا طراحی با داده های شما تطبیق داده نمی شود و کاربران شما درد را احساس می کنند.

در جوملا، می توانیم فرم های خود را با استفاده از چندین نوع فیلد که رابط  های متفاوتی را ارائه می دهند، خوشمزه تر کنیم. این کار فرم های ما را آسان تر می کند و اجزای ما را کاربر پسندتر می کند.

می توانید پیوندی با تمام فیلدهای فرم استاندارد فعلی جوملا و دستورالعمل ها در اسناد رسمی جوملا پیدا کنید:

  https://docs.joomla.org/Standard_form_field_types

در این کتاب ما قرار است انواع رشته های جالب تر را پوشش دهد.

در جوملا، تمام تعاریف فیلدها یک ساختار مشترک دارند، بنابراین یک فیلد عمومی در جوملا ممکن است این ویژگی ها را داشته باشد:

  • name :  این نامی است که به صورت داخلی برای اشاره به فیلد استفاده می کنیم. باید برای این فرم منحصر به فرد باشد و باید تعریف شود.
  • type :  این یکی از انواع فیلدهایی است که می توانیم برای فیلد خود استفاده کنیم. اجباری است. اگر جوملا نوع فیلد را تشخیص ندهد، نوع فیلد متنی را نشان می دهد.
  • label :  این نام فیلدی است که به کاربر نشان داده می شود. شما باید آن را تعریف کنید و از سیستم ترجمه جوملا پشتیبانی می کند (همانطور که در فصل های بعدی خواهیم دید).
  • Description: این راهنمای ابزار یا متن راهنما است که به تعریف فیلد اضافه می شود. همچنین از سیستم ترجمه جوملا پشتیبانی می کند. ممکن است آن را حذف کنید.
  • class :  این کلاس CSS است که فیلد در هنگام نمایش آن خواهد داشت. این یک ویژگی اختیاری است.
  • labelclass :  این کلاس CSS است که می توانیم به برچسب فیلد اضافه کنیم. اضافه کردن آن ضروری نیست.
  • showon :  این ویژگی اختیاری نام فیلد دیگری از فرم فعلی و مقدار ممکن را می پذیرد. به این ترتیب، یک فیلد با ویژگی  showon  تنها در صورتی نشان داده می شود که فیلد ارجاع شده حاوی مقدار مشخص شده باشد. این برای پنهان کردن فیلدها با توجه به گزینه های کاربر مفید است.
  • filter :  این ویژگی سطح فیلتر را برای متن معرفی شده توسط کاربر تعیین می کند. ما می توانیم از safehtml استفاده کنیم تا فقط تگ  های HTML ایمن یا خام را مجاز کنیم اگر هیچ نوع فیلتری نمی  خواهیم.

اکنون که کمی بیشتر در مورد ویژگی های عمومی فیلدهای خود می دانیم، اجازه دهید برخی از فیلدهای استاندارد را بررسی کنیم و آنها را به پروژه خود اضافه کنیم.

استفاده از ویرایشگر فیلد فرم

هنگام افزودن متن به افزونه ، ما می خواهیم یک تجربه ویرایش غنی را برای کاربران خود فراهم کنیم. اضافه کردن ویژگی هایی مثل پررنگ کردن (bold)، کج کردن (italics) متن یا چیزهای فانتزی مانند رنگ آمیزی متن یا انتخاب تایپوگرافی، تجربه کاربری بهتری را ایجاد می کند.

در جوملا، سه ویرایشگر متن استاندارد وجود دارد:  TinyMCE  - CodeMirror  - No Editor

هر کدام از اینها یک پلاگین از نوع Editor  هستند و در صورت نیاز می توانیم ویرایشگر های بیشتری را نصب کنیم.

برای استفاده از ویرایشگر به جای فیلد  &lt;textarea&gt; معمولی در کامپوننت خود، می توانیم از فیلد Editor  استفاده کنیم. این قسمت به شما امکان می دهد یکی از ویرایشگرهای نصب شده در سایت جوملا خود را نشان دهید.

در پروژه خود، فیلد متنی (که برای توضیحات پروژه استفاده می کنیم) را حذف می کنیم و از فیلد Editor  استفاده می کنیم. بنابراین، فایل src/component/administrator/com_spm/forms/project.xml  را ویرایش کرده و فایل descriptions را با این کد جایگزین می کنیم:

 
<field 
    type="editor" 
    name="description" 
    buttons="image" 
    hide="readmore, pagebreak" 
    editor="tinymce|none" 
    filter="safehtml" 
   label="COM_SPM_PROJECT_DESCRIPTION" 
   /> 
    
 

در کد قبلی، برخی از ویژگی های منحصر به فرد این فیلد را برجسته کرده ایم:

  • buttons :  این ویژگی نشان می دهد که کدام یک از دکمه های Editors-Extended را می خواهیم به کاربر نشان دهیم. می توانید پیوندی درباره این دکمه های Editors-Extended در بخش خواندن بیشتر پیدا کنید.
  •  hide : این ویژگی نشان می دهد که کدام یک از دکمه های Editors-Extended را می خواهیم از کاربر مخفی کنیم.
  •  editor : با استفاده از این ویژگی می توانیم ویرایشگری را که می خواهیم برای فیلد خود استفاده کنیم را مشخص کنیم. سینتکس desired editor / alternative editor است، به این معنی که در مورد ما، به دنبال ویرایشگر TinyMCE می گردد که به طور پیش فرض با جوملا می آید، و اگر نتواند آن را پیدا کند، هیچ ویرایشگری را نشان نخواهد داد. اگر هیچ یک از گزینه ها پیدا نشد، جوملا از ویرایشگر پیش فرض جهانی که در تنظیمات پیکربندی جهانی پیکربندی شده است استفاده می کند.

با استفاده از فیلد ویرایشگر برای داشتن افزونه ی زیبا، بیشتر عالی است و کاربران می توانند از آن برای اضافه کردن تصاویر استفاده کنند. با این حال، اگر بخواهیم از فیلدهای تصویری استفاده کنیم، باید کمی جلوتر برویم و از یک نوع فیلد تصویری خاص استفاده کنیم، همانطور که در قسمت بعدی خواهیم دید.

استفاده از فیلد  accessiblemedia

هنگام اضافه کردن تصاویر به افزونه، ممکن است بخواهیم این تصاویر را در محتوای خود ادغام کنیم. برای رعایت استانداردهای دسترس  پذیری، هر زمان که تصویری در محتوای ما آپلود می شود، باید یک توضیح متنی از این تصویر ارائه دهیم. این معمولاً به معنای تعریف یک ورودی فایل برای آپلود تصویر و یک فیلد متنی برای توضیحات است.

در جوملا، با استفاده از فیلد accessiblemedia می توانیم هر دو فیلد HTML را به صورت معنادار داشته باشیم.

این نوع فیلد از تمام قدرت مدیریت رسانه جوملا جدید استفاده می کند و یک پنجره پاپ آپ ایجاد می کند که در آن ویرایشگر می تواند تصویر را بکشد و رها کند یا فقط آن را از تصاویر بارگذاری شده از قبل انتخاب کند. همچنین یک فیلد متنی را فراهم می کند که ویرایشگر می تواند توضیحات تصویر را اضافه کند.

استفاده از این نوع فیلد ساده است و ما قصد داریم آن را به موارد پروژه در کامپوننت خود اضافه کنیم. ما می توانیم این کار را با افزودن کد زیر به فایل project.xml خود انجام دهیم:

 
<field 
    name="logo" 
    type="accessiblemedia" 
    directory="projects" 
    label="COM_PROJECT_LOGO" 
/> 
    

 در تعریف این فیلد، از ویژگی directory استفاده می کنیم که منحصر به این فیلد است. این دایرکتوری است که تصاویر ما در آن ذخیره خواهند شد. مسیر مربوط به پوشه Images در جوملا است. همچنین، کاربران ما می توانند تصاویر را از این پوشه دریافت کنند.

اکنون، ما می توانیم به کاربران خود راهی برای آپلود تصاویر خود به روشی در قابل دسترس ارائه دهیم.

ایجاد گزینه های انتخابی از جداول پایگاه داده

یکی از فیلدهای فرم استاندارد جوملا که مورد علاقه من است، نوع فیلد sql است. این فیلد به شما اجازه می دهد تا یک منوی کشویی نشان دهید که در آن گزینه ها با داده های پایگاه داده شما ایجاد می شوند. این بسیار مفید است زمانی که شما نهادهای مرتبط دارید. به عنوان مثال، وظایف ما متعلق به یک پروژه است و می خواهیم آنها را بر اساس پروژه گروه بندی کنیم. بنابراین، بسیار عالی خواهد بود که کاربر بتوانید لیستی از پروژه ها را هنگام ویرایش، انتخاب کند، نشان دهد.

در فرم وظیفه ما در src/component/admin/forms/task.xml ، می توانیم فیلد زیر را اضافه کنیم:

 
<field 
    name="id_project" 
    type="sql" 
    label="COM_SPM_TASK_PROJECT" 
    sql_select="p.*" 
    sql_from="#__spm_projects AS p" 
    sql_group="name" 
    sql_order="p.id ASC" 
    key_field="id" 
    value_field="name" 
    /> 
    

 این کد یک فیلد انتخابی HTML را در فرم ما ارائه می دهد که در آن مقدار گزینه برای انتخاب HTML مقدار فیلد مشخص شده در key_field  و گزینه نشان دادن مقدار مشخص شده برای ستون value_field  جدول spm_projects  ما خواهد بود.

البته برای نمایش این فیلد در فرم خود، باید مطمئن باشیم که به فایل src/component/admin/tmpl/task/edit.php اضافه شده است. بنابراین، اجازه دهید فایل را ویرایش کنیم و فیلد را اضافه کنیم:

 
$this->form->field('id_project')->render(); 
    

 هنگام بررسی اسناد فیلدsql  ، ممکن است دریابید که راهی برای اضافه کردن مستقیم SQL شما با استفاده از ویژگی query  وجود دارد. این یک روش قدیمی برای استفاده از این فیلد است و توصیه نمی شود زیرا جست و جو را مستقیماً به پایگاه داده شما ارسال می کند، به این معنی که ممکن است سازگاری با PostgreSQL یا سایر پایگاه های داده پشتیبانی شده توسط جوملا را از دست بدهید.

فیلد  sql برای نمایش فیلدهای فرم مخصوص داده های فعلی پایگاه داده ما عالی است. اما در برخی شرایط، ما باید زمینه هایی را توسعه دهیم که متناسب با پروژه هایمان باشد. در بخش بعدی قصد داریم نحوه ی توسعه ی فیلدهای فرم سفارشی را یاد بگیریم.

تعریف انواع فیلد فرم سفارشی

ما تعداد زیادی فیلد فرم استاندارد جوملا داریم و آنها باید برای اکثر پروژه ها کافی باشند، اما در برخی مواقع، ممکن است لازم باشد فیلدهای فرم خود را ایجاد کنید تا برخی از عملکردهای فرم خود را گسترش دهید. در جوملا، این کار به آسانی گسترش کلاس FormField است.

برای یادگیری نحوه انجام این کار، انتخاب گر پروژه خود را از قسمت قبل با استفاده از یک فیلد فرم سفارشی دوباره ایجاد می کنیم. این فیلد، یک منوی کشویی خواهد بود که در آن کاربر می تواند یک پروژه را از یک لیست انتخاب کند.

ابتدا باید کلاس FormField  را گسترش دهیم. این کلاس کلاسی است که تمام فیلدهای جوملا از آن ایجاد می شوند و تمام متدهای مورد نیاز را فراهم می کند که به جوملا اجازه می دهد فیلدهای تعریف شده در فرم های XML را نشان دهد.

بنابراین، بیایید شروع به ایجاد فیلد جدید خود کنیم.  فیلد src/component/admin/src/Fields/ProjectField.php را با محتوای زیر ایجاد کنید:

 
<?php 
namespace Piedpiper\Component\Spm\Administrator\Fields; 
use Joomla\CMS\Form\Field\ListField; 
class PiedpiperFormFieldProject extends ListField { 
    protected $type = 'piedpiper.project'; 
} 
    

 در این کد ویژگی $type  را تعریف می کنیم که نام فیلد جدید ما خواهد بود. ما پیشوند نام رشته خود را با نام شرکت خود قرار داده ایم. این به جلوگیری از برخورد با انواع فیلدهای تعریف شده توسط توسعه دهندگان دیگر کمک می کند. این پیشوند باید به ویژگی type  اضافه شود. همچنین برای تعریف فیلد به نام کلاس اضافه می شود.

ما کلاس ListField  را گسترش می دهیم، زیرا فیلد لیست مانند رفتار فیلد ما است، اما می توانیم هر نوع فیلد دیگری را که انتخاب می کنیم، گسترش دهیم.

برای ایجاد کادر انتخاب با لیست پروژه های خود، باید یک override برای متد getOptions() ایجاد کنیم. این روش فقط در فیلدهای توسعه یافته از کلاس ListField  وجود دارد و ما از آن برای بازیابی لیستی از پروژه ها از پایگاه داده استفاده می کنیم:

 
public function getOptions() 
{ 
    $db = Factory::getContainer()->get('DatabaseDriver'); 
    $query = $db->getQuery(true); 
    $query->select('ip.id, p.name') 
          ->from('#__spm_projects') 
        ->order('p.name', 'asc'); 
    $db->setQuery($query); 
    $options = $db->loadAssocList('id', 'name'); 
    return $options; 
} 
    

 در این کد، از متد loadAssocList() استفاده می کنیم تا یک آرایه نمایه شده با ویژگی id  پروژه ها به عنوان شاخص و Name به عنوان مقدار به دست آوریم.

این یک انتخابselect) ) استاندارد HTML با تمام پروژه های ما نشان می دهد. می توانیم این را با نادیده گرفتن متد getInput  از کلاس FormField  سفارشی کنیم. بیایید select با لیستی از دکمه های رادیویی با کد زیر در فایل src/component/admin/src/Fields/ProjectField.php  جایگزین کنیم:

 
public function getInput() 
{ 
} 
    

 هنگامی که نوع فیلد جدید خود را تعریف کردیم، می توانیم از آن در فرم های خود استفاده کنیم.

نحوه استفاده از نوع فیلد subform

علاوه بر توسعه فیلدهای خود در جوملا، می توانیم با ترکیب فیلدهای فرم استاندارد ارائه شده، فیلدهای پیچیده ایجاد کنیم. این یک ویژگی قدرتمند است که ما از استفاده از فیلد subform در فرم های خود دریافت می کنیم. فیلد subform  به ما اجازه می دهد تا فرم ها را به عنوان فیلدهای فرم دیگری قرار دهیم.

در مورد ما، می توانیم از فیلد subform برای افزودن اسناد به پروژه های خود با نام و شرح افزونه برای مدیریت پروژه افزونه ی خود استفاده کنیم.

بیایید با افزودن این کد، تعریف subform را به فایل src/component/admin/forms/forms.xml اضافه کنیم:

 
<field 
    name="attachments" 
    type="subform" 
    label="COM_SPM_PROJECT_ATTACHMENTS" 
    multiple="true" 
    layout="joomla.form.field.subform.repeatable" 
    > 
    <form> 
        <field 
            name="attachment_file" 
            type="file" 
            label="COM_SPM_PROJECT_ATTACHMENTS_FILE" 
            /> 
        <field 
            name="attachment_name" 
            type="text" 
            label="COM_SPM_PROJECT_ATTACHMENTS_NAME" 
            /> 
        <field 
            name="attachment_description" 
            type="textarea" 
            label="COM_SPM_PROJECT_ATTACHMENTS_DESCRIPTION" 
            /> 
    </form> 
</field> 
    

 در اینجا یک فیلد جدید از نوع subform ایجاد می کنیم و فیلدهایی را که قرار است در داخل این subform قرار گیرند، بین تگ هایform  تعریف می کنیم. همچنین، از آنجایی که می خواهیم چندین پیوست را برای پروژه های خود مجاز کنیم (می توانیم یک پیوست با پیشنهادی که برای مشتری ارسال می کنیم، سند دیگری با نقل قول برای پروژه، و دیگری با برخی اسناد مورد نیاز و...)، ویژگی چندگانه (multiple attribute) را به فیلد فرم اضافه می کنیم.

در قسمت subform ، ما همچنین چیدمان را برای نمایش فیلدهای subform مشخص میکنیم. جوملا، سه چیدمان را ارائه می دهد که ممکن است برای این کار استفاده کنیم:

  • joomla.form.field.subform.default :  این ساده ترین طرح است و برای فیلدهای قابل تکرار آماده نیست، بنابراین زمانی که ویژگی چندگانه روی true  تنظیم شده است از استفاده از آن خودداری کنید.
  • joomla.form.field.subform.repeatable :  این طرح برای فیلدهای تکرار پذیر مناسب است و فیلدهای مختلف را با استفاده از div ها نمایش می دهد.
  •  joomla.form.field.subform.repeatable-table : این چیدمان برای فیلدهای تکرار پذیر نیز مناسب است اما subform را با استفاده از جدول HTML نمایش می دهد.

می توانیم با اضافه کردن تعریف فرم در یک فایل دیگر، مرتب تر است. این همچنین به ما این امکان را می دهد که در صورت نیاز از فرم در قسمت subform دیگری یا به عنوان یک فرم خاص استفاده مجدد کنیم.

برای انجام این کار، باید فایل src/component/admin/forms/attachment.xml  را ایجاد کنیم و موارد زیر را در تعریف فرم خود قرار دهیم:

 
<form> 
    <field 
        name="attachment_file" 
        type="file" 
        label="COM_SPM_PROJECT_ATTACHMENTS_FILE" 
       /> 
    <field 
        name="attachment_name" 
        type="text" 
        label="COM_SPM_PROJECT_ATTACHMENTS_NAME" 
        /> 
    <field 
        name="attachment_description" 
        type="textarea" 
       label="COM_SPM_PROJECT_ATTACHMENTS_DESCRIPTION" 
        /> 
</form> 
  

 همچنین باید تعریف subform را با کد زیر جایگزین کنیم:

 
<field 
    name="attachments" 
    type="subform" 
    label="COM_SPM_PROJECT_ATTACHMENTS" 
    multiple="true"    formsource="administrator/components/com_spm/forms/attachment.xml" 
    layout="joomla.form.field.subform.repeatable" 
/> 
    

 این باعث می شود خواندن تعریف subform بسیار ساده تر است. ما کل تعریف فرم را با ویژگی formsource  جایگزین کرده ایم که مسیر نسبی را از پوشه ریشه جوملا تا تعریف subform فایل XML ما را نشان می دهد.

ما می توانیم هر فرم ورودی که برای برنامه خود نیاز داریم ایجاد کنیم و مناسب ترین رابط کاربری را برای ارائه داده های مناسب برای کاربران خود ارائه دهیم. اما ما همچنین باید تأیید کنیم که ورودی معتبر است و می تواند در افزونه ما استفاده شود. در بخش بعدی، نحوه تشخیص داده های نا معتبر و جلوگیری از اشتباهات انسانی را یاد خواهیم گرفت.

اعتبار سنجی ورودی کاربر در سمت مشتری

ما باید مطمئن باشیم که کاربران ما هنگام پر کردن فرم، اطلاعات درستی را ارائه می دهند. هرچه زودتر مشکلی را در داده ها با کاربر در میان بگذاریم، تجربه کاربری بهتری خواهد داشت. به همین دلیل است که می خواهیم حتی قبل از ارسال فرم توسط کاربر به جوملا، خطاها را بررسی کنیم.  به همین دلیل است که ما از اعتبار سنجی سمت مشتری برای فرم های خود استفاده می کنیم.

هنگام استفاده از فیلدهای فرم استاندارد جوملا، برخی از ویژگی  هایی وجود دارد که می توانیم در فیلدهای خود از آنها استفاده کنیم که اعتبار سنجی فرم  های ما را خارج از فرم اضافه می کنند. به عنوان مثال، هنگامی که ویژگی مورد نیاز را در تعریف XML برای فیلد فرم خود تنظیم می کنیم، کاربر باید داده هایی را برای ارسال فرم اضافه کند.

بیایید مقداری اعتبار به فرم ویرایش مشتری خود اضافه کنیم. بنابراین در فایل src/component/admin/forms/client.xml ، تعریف فیلد ایمیل را با این کد جایگزین کنید:

 
<field 
    name="email" 
    type="email" 
    required="true" 
    /> 
    

 این به جوملا می گوید که کاربر باید فیلد را پر کند. همچنین از آنجایی که از نوع فیلد ایمیل استفاده می کنیم، ورودی HTML فیلد از نوع ایمیل خواهد بود. این کار اعتبار سنجی مرورگر را برای فیلد فعال می کند، بنابراین کاربر نمی تواند چیزی متفاوت از یک فیلد ایمیل را پر کند. این همچنین برای فیلدهای فرم استاندارد برای url و tel (که برای شماره تلفن استفاده می شود) اتفاق می افتد.

اما برای اعتبار سنجی بهتر سمت مشتری، باید از جاوا اسکریپت استفاده کنیم. در جوملا، انجام این کار با استفاده از کتابخانه هسته اعتبار سنجی بسیار آسان است.

برای افزودن آن به فرم خود، باید فایل/src/component/admin/tmpl/client/edit.php  را ویرایش کنیم و کد زیر را در زیر آخرین اعلان use اضافه کنیم :

 
use Joomla\CMS\HTML\HTMLHelper; 
HTMLHelper::_('behavior.formvalidator'); 
    

 این کد کتابخانه جاوا اسکریپت را که برای اعتبارسنجی فیلدها قبل از ارسال فرم لازم است، بارگیری می کند. این کتابخانه از جاوا اسکریپت برای جستجوی ویژگی مورد نیاز استفاده می کند. همچنین به دنبال کلاس های CSS زیر در فیلدهای ما می گردد: (نام کاربری / رمز عبور / شماره / ایمیل)

  • validate-username
  • validate-password
  • validate-numeric
  • validate-email

 علاوه بر این اعتبارسنجی، می توانیم اعتبارسنجی سفارشی خود را با مقداری کد جاوا اسکریپت ایجاد کنیم. برای نشان دادن این موضوع، اجازه دهید نمای ویرایش عنصر فاکتور هایمان را بررسی کنیم. فایل src/component/admin/forms/invoice.xml  را ویرایش کنید و قسمت (مقدار) amount  را به این تعریف تغییر دهید:

 
<field 
    name="amount" 
    type="text" 
    inputmode="decimal" 
    label="COM_SPM_INVOICES_FORM_AMOUNT" 
    class="validate-notzero" 
    required="true" 
    pattern="[0-9]{1,}(\.[0-9]{1,2})?" 
/> 
    

 این تعریف اعتبار سنجی های زیر را اضافه می کند به قسمت (مقدار) amount  :

  • required : بررسی می کند که آیا فیلد دارای مقداری هست یا خیر
  • pattern  : این ویژگی یک اعتبارسنجی را راه اندازی می کند که داده های وارد شده را در برابر الگوی RegEx  که در اینجا نشان می دهیم، بررسی می کند.
  • validate-notzero  : افزودن کلاس  validate-notzero ما را قادر می سازد تا به دنبال اعتبارسنجی سفارشی باشیم که باید به جاوا اسکریپت اضافه کنیم.

پس از این، ما فقط باید اعتبار سنجی سفارشی جاوا اسکریپت خود را به فرم اضافه کنیم. برای این کار باید فایل validation-scripts.js  را با محتوای زیر ایجاد کنیم:

 
window.addEventListener('DOMContentLoaded', function () { 
    document.formvalidator.setHandler('notzero', function (value) { 
        return value != 0; 
    }); 
} 
    

 این کد جاوا اسکریپت قبل از ارسال فرم توسط اعتبارسنجی فرم جوملا فراخوانی می شود و بررسی می کند که مقدار آن بیشتر از صفر باشد.

برای گنجاندن این فایل در فرم، باید از Web Assets Manager استفاده کنیم(فصل 3). برای این کار فایل joomla.asset.json  را ویرایش کنید و فایل را با کد زیر اضافه کنید:

 
… 
    { 
       "name": "com_spm.validation", 
        "type": "script", 
        "uri": "com_spm/validation-scripts.js", 
        "attributes": { 
            "defer": true 
        } 
    } 
… 
    

 در نهایت باید کد زیر در ابتدا src/component/admin/tmpl/invoice/edit.php اضافه کنیم:

 
$document = Factory::getApplication()->getDocument(); 
$wam = $document->getWebAssetManager(); 
$wam->useScript('com_spm.validation'); 
    

با این کد، WebAssetsManager را فرا می  خوانیم و از آن برای گنجاندن فایل جاوا اسکریپت خود استفاده می کنیم.

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

اعتبار سنجی ورودی کاربر در سمت سرور

اعتبار سنجی مشتری معمولاً اکثر خطاهای ورودی کاربر را در یک برنامه وب شناسایی کرده و به رفع آنها کمک می کند. اما برای تأیید اعتبار مشتری، ما کاملاً به مرورگر کاربر خود متکی هستیم. اعتبار سنجی مشتری در جوملا با استفاده از ویژگی های جدید در استاندارد HTML5 و برخی از کتابخانه های جاوا اسکریپت انجام می شود و این احتمال وجود دارد که کاربران ما با یک مرورگر قدیمی کار کنند یا جاوا اسکریپت را در پیکربندی مرورگر خود غیرفعال کرده باشند. در هر یک از این شرایط، اعتبار سنجی مشتری آن طور که انتظار می رود کار نخواهد کرد و ما باید روش اعتبارسنجی دیگری را تنظیم کنیم که به مرورگر کاربر بستگی ندارد.

در جوملا، می توانیم اعتبارسنجی سمت سرور را مستقیماً در تعریف فرم خود اضافه کنیم، همانطور که برای اعتبارسنجی سمت مشتری انجام دادیم.

به فرم ویرایش مشتری یا client خود برگردیم، می توانیم فایل src/component/admin/forms/client.xml  را ویرایش کنیم و تعریف فیلد ایمیل را با کد زیر جایگزین کنیم:

 
<field 
    name="email" 
    type="email" 
    required="true" 
    validate="email" 
    /> 
    

در این کد، ویژگی validate را با مقدار ایمیل اضافه کرده ایم. این کد اعتبار سنجی سمت سرور را در مدل ما راه اندازی می کند و دو جنبه را بررسی می کند:

  • require="true"  بررسی می کند که فیلد دارای یک مقدار باشد
  • validate="email"  بررسی می کند که مقدار فیلد یک ایمیل معتبر است

در بخش مطالعه بیشتر این فصل، پیوندی را خواهید یافت که تمام قوانین اعتبارسنجی را که می توانیم در سمت سرور استفاده کنیم، مشخص می کند. در آن لیست، قوانین جالبی مانند قانون برابر یا equals  وجود دارد که بررسی می کند که فیلد ما همان مقدار فیلد فرم دیگر را داشته باشد. اما به طور کلی تر، ما می خواهیم قوانین خودمان را نیز لحاظ کنیم. در جوملا، ما می توانیم قوانین سفارشی خود را برای اعتبار سنجی تعریف کنیم.

بیایید یک اعتبارسنجی سمت سرور سفارشی برای فیلد مقدار خود ایجاد کنیم تا با اعتبار سنجی سمت مشتری که در بخش قبلی اضافه کردیم مطابقت داشته باشد.

ابتدا باید به جوملا بگوییم که قوانین سفارشی خود را کجا جستجو کنیم. بنابراین، ما باید ویژگی addrulepath  را به تعریف فرم خود اضافه کنیم. لطفاً فایل src/component/admin/forms/invoice.xml  را ویرایش کنید و ویژگی addrulepath را به تگ fieldset  اضافه کنید ، همانطور که در اینجا نشان داده شده است:

 
<fieldset name="invoice" addrulepath="administrator/components/com_spm/rules"> 
</fieldset> 
    

ویژگی addrulepath  مسیر نسبی از پوشه اصلی جوملا تا تعریف قوانین ما را بیان می کند. اکنون باید فایل src/component/administrator/components/com_spm/rules/notzero.php  را با محتوای زیر ایجاد کنیم:

 
<?php 
use Joomla\CMS\Form\FormRule; 
class NotzeroRule extends FormRule 
{ 
    protected $regex = '[0-9]{1,}(\.[0-9]{1,2})?'; 
} 
    

در اینجا، ما کلاس FormRule  را گسترش می دهیم. در این مورد ساده، ما فقط عبارت منظمی را تعریف می کنیم که مقدار فیلد ما باید آن را برآورده کند تا معتبر باشد، و از همان الگویی که قبلاً در تعریف فیلد استفاده کرده بودیم، استفاده می کنیم.

اگر نمی خواهید با regex مقابله کنید یا اگر سناریوی پیچیده تری دارید باید بررسی کنید، به جای استفاده از الگوی  regex، می توانید متد test را گسترش دهید ، همانطور که در کد زیر نشان داده شده است:

 
public function test(SimpleXMLElement $element, $value, $group = null, JRegistry $input = null, Form $form = null) 
{ 
    if ($value > 0) { 
        return true; 
    } 
    return false; 
} 
    

 زمانی که ما متد test را گسترش دهید ، باید مقدار Boolean (یا منطقی) که در آن true  به این معنی است که مقدار فیلد معتبر است و false  به معنای غیر آن است. در این متد می توانیم متدهای دیگری را در کد خود یا هر عملیاتی را که برای بررسی کد نیاز داریم انجام دهیم.

منابع فصل

در ادامه مطلب

فصل های دیگر کتاب

نوشتن دیدگاه

ارسال