بیان خلاصه ای از بحث توسط هوش مصنوعی:
یکی از مزایای استفاده از جوملا این است که در واقع دو محیط کاربردی دارد (جوملا frontend و جوملا backend.) backend جوملا برای پیکربندی سایت و مدیریت داده ها استفاده می شود و کامپوننت های آن منعکس کننده این معماری هستند. این جداسازی به برنامه های امن تر و دامنه دارتر اجازه می دهد، که در آن مدیریت داده ها را در backend مدیریت کرد، در حالی که تعامل کاربر را برای قسمت frontend باقی می گذارد.
به همین دلیل است که یک منطقه اختصاصی در backend جوملا برای مدیریت وجود دارد. در این قسمت، کاربران می توانند داده های خصوصی را ببینند و رفتار یک کامپوننت را پیکربندی کنند. یک کامپوننت، تمام نهادهای داده ای را که در طرح مسئله ی خود در فصل قبل توضیح دادیم، پوشش می دهد.
هر نهاد معمولاً با یک نمای فهرست و یک نمای ویرایش ارائه می شود. علاوه بر این، در backend، صفحه پیکربندی کامپوننت را نیز پیدا می کنیم.
در این فصل، ما با حداقل کد، برای ایجاد کامپوننت جوملا کار خواهیم کرد. ما معماری فایل مورد نیاز برای ایجاد یک کامپوننت استاندارد جوملا را کشف خواهیم کرد. هنگامی که کد خود را دریافت کردیم، نحوه ایجاد یک فایل مانیفست برای کامپوننت خود را خواهیم دید و آن را در سایت جوملا نصب خواهیم کرد. در نهایت، ما مقداری کد برای افزودن نمای لیست و نمای ویرایش آیتم به کامپوننت خود اضافه می کنیم که به ما امکان می دهد داده ها را تغییر داده و به پایگاه داده خود اضافه کنیم.
در این فصل به موضوعات زیر می پردازیم :
- معماری فایل کامپوننت
- ایجاد یک فایل مانیفست برای کامپوننت ما
- در حال توسعه یک نمای لیست برای کامپوننت ما
- در حال ایجاد نمای ویرایش آیتم برای کامپوننت ما
الزامات فنی
برای گذراندن این فصل، باید کد را ویرایش کرده و آن را در سایت جوملا آزمایش کنیم. بنابراین، به موارد زیر نیاز خواهید داشت :
- کد ویژوال استودیو (یا ویرایشگر کد دلخواه شما)
- سایتی جوملایی که در فصل های قبل نصب کردیم
می توانید تمام فایل های کد مورد استفاده در این فصل را در GitHub پیدا کنید:
https://github.com/PacktPublishing/Developing-Extensions-for-Joomla-5/tree/chapter02
معماری فایل کامپوننت
ما می توانیم یک کامپوننت جوملا را با استفاده از تقریباً هر معماری پوشه ای که می توانید تصور کنید ایجاد کنیم. با این حال، اگر بخواهیم از کتابخانه های جوملا استفاده کنیم، باید قوانینی را رعایت کنیم. در این قسمت ساختار فایل و پوشه ای ایجاد می کنیم تا از استانداردهای جوملا پیروی کرده و از آن به نفع خود استفاده کنیم.
هنگام نصب یک کامپوننت در سایت جوملا، جوملا به طور خودکار تمام قسمت های مختلف کامپوننت شما را به مکان مناسب منتقل می کند. یک کامپوننت ساده حداقل یک پوشه مدیریت و یک پوشه سایت خواهد داشت. این پوشه ها به ترتیب میزبان فایل های backend و frontend کامپوننت ما هستند. بیایید به کار در پوشه توسعه خود ادامه دهیم و دو پوشه ایجاد کنیم admin وsite :
- admin: این پوشه حاوی تمام فایل ها و پوشه هایی است که به backend کامپوننت ما تعلق دارند. مسئول تعامل کامپوننت در جوملا خواهد بود.
- site: این پوشه حاوی تمام فایل ها و پوشه هایی است که با قسمت frontend کامپوننت ما ارتباط دارند.
محتویات پوشه سایت را در فصل بعدی خواهیم دید. در حال حاضر، ما شروع به یادگیری آنچه در داخل پوشه مدیریت برای یک کامپوننت ساده با حداقل کد است، خواهیم کرد.
ساخت backend یک کامپوننت
پوشه اصلی backend کامپوننت ما شامل تمام منطقی است که برای کار در backend سایت جوملا نیاز دارد. همچنین حاوی برخی از فایل های مورد استفاده در نصب کامپوننت است.
برای شروع کدنویسی کامپوننت خود، باید یک ساختار پوشه اصلی برای backend ایجاد کنیم. ما با حداقل کد شروع می کنیم و ما در ادامه آن را توسعه خواهیم داد. به عنوان نقطه شروع، اجازه دهید پوشه های زیر را ایجاد کنیم:
- services
- src
- tmpl
پوشه services
پوشه services هدف میزبانی فایل provider.php است – این پوشه تمام خدماتی که کامپوننت ما استفاده خواهد کرد را ثبت میکند. با این حال، کامپوننت ما نیز باید خدماتی را که از جوملا استفاده می کنند، تعریف کنند. جوملا برای اینکه این کار را برای ما راحت تر کند، Dependency Injection Container (تزریق وابستگی) را معرفی کرد. این یک الگوی طراحی است که هدف آن ساده کردن مدیریت وابستگی و ایجاد یک پلتفرم قوی تر است. و اجزای یک برنامه را میتواند از هم جدا کند.
برای افزودن پوشه services به Backend کامپوننت خود، فایل services/provider.php را با موارد زیر اضافه می کنیم.
<?php use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInter face; use Joomla\CMS\Extension\ComponentInterface; use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory; use Joomla\CMS\Extension\Service\Provider\MVCFactory; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Piedpiper\Component\Spm\Administrator\Extension\SpmComponent; return new class implements ServiceProviderInterface { public function register(Container $container) { $container->registerServiceProvider(new MVCFactory('\\Piedpiper\\Component\\Spm')); $container->registerServiceProvider(new ComponentDispatcherFactory('\\Piedpiper\\ Component\\Spm')); $container->set( ComponentInterface::class, function (Container $container) { $component = new SpmComponent($container-> get(ComponentDispatcherFactoryInter face::class)); $component->setMVCFactory($container-> get(MVCFactoryInterface::class)); return $component; } ); } };
هر چند این ممکن است کمی شبیه کد boilerplate (کد های اولیه برای اجرای بهتر برنامه) به نظر برسد، هدف از آن پیاده سازی الگوی ظرف تزریق وابستگی است. را بخش جالب این کد بلوک برجسته شده است. در این بلوک، ما شروع به ثبت خدماتی می کنیم که کامپوننت ما در شرف استفاده است.
بخش جالب این کد Bold شده است. در این بلوک، ما شروع به ثبت خدماتی می کنیم که کامپوننت ما در شرف استفاده است.
یکی از این خدمات MVCFactory است. در جوملا، پیاده سازی Model-View-Controller ( MVC ) به عنوان یک سرویس ارائه می شود. یعنی باید سرویس MVCFactory را در این فایل فراخوانی کنیم.
سرویس دیگری که باید آن را فراخوانی کنیم ComponentDispatcherFactory است. مسئول ارسال دستورات کامپوننت ما است و باید در هر کامپوننت استفاده شود.
در بلوک Bold شده می بینید که ما کلاس Spm را صدا می زنیم که بعداً در قسمت های بعدی آن را تعریف خواهیم کرد. سرویس های دیگری که در فصل های آینده اضافه خواهیم کرد RouterFactory و CategoryFactory هستند ، اما در حال حاضر، ما آن را ساده نگه میداریم.
پوشه src
هنگامی که وابستگی های ما تنظیم شدند، ما می توانیم پوشه src را کاوش کنیم. این پوشه حاوی مدل اصلی MVC برای کامپوننت ما است. همچنین حاوی زیر پوشه های زیر است:
- Controller
- Extension
- Model
- Table
- View
اگر با توسعه در جوملا 3 آشنایی دارید، ممکن است تمام این زیر پوشه ها را بشناسید، به جز پوشه Extension. در واقع، این پوشه ها میزبان کلاس هایی هستند که مدل MVC کامپوننت ما را تکمیل می کنند.
فضای نام در جوملا
در جوملا، هر کتابخانه ای یک فضای نام دارد و ما از فضای نام برای بارگذاری کلاس ها در کامپوننت خود استفاده می کنیم. بنابراین، کامپوننت ما نیز باید یک فضای نام داشته باشد. این فضای نام به شکل ROOT_NAMESPACE\TYPE_OF_EXTENSION\ALIAS است که ROOT_NAMESPACE یک نام شروع منحصر به فرد است. این می تواند نام شرکت شما، نام شما یا هر کلمه ای باشد که برای شما معنی دارد. سپس، نوع افزونه را اضافه می کنیم - در این مورد، Component است. در نهایت، ما ALIAS را اضافه می کنیم، که نام یا نام مستعاری است که شما برای کامپوننت خود انتخاب کرده اید - در این مورد، ما از Spm به عنوان نام مستعار خود (مخفف Simple Project Manager ) استفاده می کنیم. بنابراین، ما فضای نام نهایی خود را به عنوان Piedpiper\Component\Spm دریافت کنید.
هر زیر پوشه داخل پوشه src با یک حرف بزرگ شروع می شود. این به autoloader کمک می کند تا کلاس های مختلف را با استفاده از فضای نام آنها پیدا کند. برای پوشه های خارج از src، از حروف کوچک استفاده می کنیم، زیرا جوملا به دنبال نام فایل ها در این قالب می گردد.
پوشه Extension
پوشه Extension فایل بوت را نگه می دارد. این نقطه ورود برای Bachend خواهد بود. این فایل به عنوان کامپوننت ما به شکل COMPONENT_ALIAS_Component نامگذاری می شود. بنابراین، در پوشه admin/src/Extension/ فایل SpmComponent.php را برای کامپوننت ما ایجاد کنیم. بلوک کد زیر برای این فایل است:
<?php
namespace Piedpiper\Component\Spm\Administrator\Extension;
use Joomla\CMS\Extension\BootableExtensionInterface;
use Joomla\CMS\Extension\MVCComponent;
use Psr\Container\ContainerInterface;
class SpmComponent extends MVCComponent implements
BootableExtensionInterface
{
public function boot(ContainerInterface $container)
{
}
}
در این لحظه، این فایل خیلی چشمگیر نیست. ما فقط متد boot() را با ظرفی از تزریق وابستگی که در فایل providers.php پیکربندی شده است، فراخوانی می کنیم. با این حال، این فایل نقطه شروع برای کامپوننت ما است، بنابراین باید آنجا باشد.
در هر صورت در فصل های آینده مقداری کد اضافی به این فایل اضافه خواهیم کرد.
پوشه Controller
در این پوشه، ما تمام کنترلرها را برای backend کامپوننت خود قرار می دهیم. اولین کنترلر ما DisplayController.php خواهد بود. این فایل اولین فایلی است که جوملا MVC پس از راه اندازی کامپوننت بررسی می کند. در این فایل، نمای پیش فرض کامپوننت خود را در backend تعریف می کنیم.
بیایید این فایل را در داخل این پوشه Controller ایجاد کنیم :
<?php
namespace Piedpiper\Component\Spm\Administrator\Controller;
use Joomla\CMS\MVC\Controller\BaseController;
class DisplayController extends BaseController
{
protected $default_view = 'cpanel';
}
در این بلوک کد، DisplayController کلاس BaseController جوملا را گسترش می دهد و ما نمای پیش فرض را برای کامپوننت خود تعریف می کنیم که به نام نمای cpanel است. در بخش بعدی آن را ایجاد خواهیم کرد.
در کامپوننت spm ، ما یک نمای کنترل پنل ایجاد می کند که در آن کاربران ما به راحتی به تمام نهادهای موجود در کامپوننت ما دسترسی خواهند داشت، بنابراین منطقی است که از آن را به عنوان نمای پیش فرض استفاده کنیم. در هر صورت، می توانید هر نما دیگری از کامپوننت خود را نیز به عنوان نمای پیش فرض اختصاص دهید.
پوشه View
در پوشه View ، ما تمام نماهای کامپوننت خود را ذخیره میکنیم. در کامپوننت، اول ما شروع به اضافه کردن نمای کنترل پنل می کنیم تا بتوانیم در اسرع وقت کامپوننت را نصب کنیم.
هر View باید در پوشه خود نصب شود، بنابراین ما فایل admin/src/View/Cpanel/HtmlView.php را در بلوک کد زیر ایجاد می کنیم:
<?php
namespace Piedpiper\Component\Spm\Administrator\View\Cpanel;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
class HtmlView extends BaseHtmlView
{
public function display($tpl=null): void
{
parent::display($tpl);
}
}
در این بلوک کد، کلاس HtmlView جوملا را گسترش می دهد و برای جلوگیری از برخورد نام، باید هنگام استفاده از فضای نام ، نام مستعار ( BaseHtmlView ) برای آن تعیین کنیم.
برای این کلاس، ما فقط متد display() را تعریف می کنیم که tmpl را با محتوای ما فراخوانی می کند.
پوشه tmpl
View های ما یک فایل قالب با کد HTML مورد نیاز برای نمایش داده های ما فراخوانی میکند. این فایل ها در داخل پوشه tmpl ذخیره می شوند. برای تمایز بین قالب ها از نماهای مختلف، باید یک پوشه برای هر view ایجاد کنیم.
بنابراین، ما فایل default.php را در داخل پوشه tmpl/cpanel با محتوای بسیار ساده ایجاد خواهیم کرد:
<?php
echo 'Simple Project Manager Control panel'
این کد فقط پیام Simple Project Manager Control panel را بر روی صفحه نمایش ما نشان می دهد.
تا کنون، ما تمام فایل های مورد نیاز برای یک کامپوننت کاربردی را در backend ایجاد کرده ایم. ما کد اصلی را برای پیروی از استانداردهای جوملا تنظیم کرده ایم و حتی یک نمای ساده ایجاد کرده ایم که پیامی را نشان می دهد. در قسمت های بعدی نحوه ایجاد پکیج با این کد برای نصب آن در سایت جوملا را خواهیم دید.
ایجاد ساختار مخزن کامپوننت ما
ما داریم از طریق فایل های اولیه و معماری پوشه های پشتیبان کامپوننت خود را گذراندیم، بنابراین اکنون زمان خوبی است که ساختار فایل را در رایانه خود ایجاد کنیم تا این پروژه را گسترش دهیم و یک مخزن برای آن ایجاد کنیم.
هنگام ایجاد ساختار مخزن برای نگهداری کد Extension، باید مواردی را در نظر بگیریم:
- ساختار مخزن باید ساختار نهایی کامپوننت ما را منعکس کند. این به ما کمک می کند تا در هر زمان بسته نصبی را برای Extension خود ایجاد کنیم.
- باید تمام کدهای مربوط به پروژه را در خود داشته باشد.
- در طول این کتاب، ما همچنین یک ماژول و چند پلاگین برای پروژه خود توسعه خواهیم داد، بنابراین بیایید یک مخزن ایجاد کنیم که بتوانیم بعدا به افزودن چیزهایی به پروژه ادامه دهیم.
- در فصل های بعدی، برخی از تکنیک های تست را نیز پوشش خواهیم داد، بنابراین ایجاد یک مخزن برای این تکنیک ها را در ذهن نگه داشته باشید.
با این اوصاف، بیایید ایجاد مخزن محلی خود را با دو پوشه زیر شروع کنیم:
- پوشه src :این پوشه تمام فایل های کامپوننت ما را نگه می دارد
- پوشه scripts : این پوشه هر اسکریپت پشتیبان پروژه ما را در خود نگه می دارد - به عنوان مثال، ایجاد کننده داده های ساختگی که در فصل 1 در کامپوننت خود ایجاد کردیم.
ایجاد فایل manifest مانیفست
برای نصب یک افزونه، جوملا دستورالعمل های موجود در فایل مانیفست کامپوننت را دنبال می کند. فایل مانیفست یک فایل xml با اطلاعات اولیه در مورد Extension شما است. در این فایل باید مقصد نهایی هر فایل را مشخص کنیم. همچنین، باید با نام مستعار کامپوننت شما یکسان باشد. بنابراین، در مورد کامپوننت ما چون com_spm است، فایل مانیفست spm.xml خواهد بود.
به صورت محلی، باید فایل مانیفست را در پوشه اصلی کامپوننت خود قرار دهیم.
بنابراین، ما شروع به نوشتن فایل مانیفست خود می کنیم:
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" method="upgrade">
<name>COM_SPM</name>
<author><![CDATA[Carlos Cámara]]></author>
<authorEmail>
اول از همه شما ممکن است متوجه شوید که سینتکس XML سند را با نسخه xml و رمز گذاری فایل اعلام کرده ایم.
بلافاصله پس از آن، در خط 2 ، اعلامیه مانیفست خود را شروع می کنیم که نشان می دهد در حال نصب یک Extension هستیم. ما همچنین نوع Extension (در این مورد کامپوننت) و روش نصب آن را نشان می دهیم. روش می تواند نصب یا ارتقا باشد. اگر روش نصب را انتخاب کنید ، می توانید این نسخه Extension را فقط در سایت هایی نصب کنید که هنوز نصب نشده است. اگر روش ارتقا را انتخاب کنید، می توانید همان نسخه را هر چند بار که بخواهید نصب کنید و هر بار فایل های Extension قبلی را رونویسی کنید.
خطوط 3 تا 9 متادیتا Extension هستند. ما نام و ایمیل خود را تعریف می کنیم و می توانیم مجوز استفاده از آن را مشخص کنیم.
پس از آن، ما می توانیم کمی لذت واقعی داشته باشیم، جایی که ما برخی از جنبه های فنی توسعه خود را تعریف می کنیم. بیایید زیر بخش های زیر را مرور کنیم.
- version این نسخه Extension ما را تعریف می کند. جوملا از آن استفاده می کند تا بداند آیا نیاز به ردیابی بروز رسانی های Extension دارد یا خیر، و ممکن است هنگام نصب Extension برای انجام تغییرات سفارشی از آن استفاده کنیم.
در جوملا، پیروی از Semantic Versioning Specification (https://semver.org)، که در آن از سه عدد برای مشخص کردن نسخه هر جزء استفاده می کنید، یک روش معمول است.
- description در این تگ، توضیحی از افزونه خود اضافه می کنیم. در این مورد، از یک رشته کلید برای تعیین توضیحات استفاده می کنیم COM_SPM_DESCRIPTION. این به ما کمک می کند تا در نسخه های ترجمه شده، توضیحات خود را ارائه دهیم.
استفاده از کاراکترهای غیر ASCII در XML
اگر با سینتکس XML آشنا نیستید، دیدن رشته کلید در تعریف [CDATA[]] ممکن است عجیب به نظر برسد. این یک دستور جایگزین است که به ما اجازه می دهد از کاراکترهای غیر ASCII و سایر کاراکترهای ممنوعه در XML استفاده کنیم.
- namespace این تگ فضای نام است که در فصل اول باهاش آشنا شدیم.
- administration این بخش فایل XML به ما این امکان را می دهد که برخی از موارد را از افزونه ی خود برای backend جوملا تعریف کنیم. در اینجا، فایل ها و پوشه هایی را که به backend کامپوننت منتقل می شوند، تعریف می کنیم. همچنین می توانیم منوهایی را که می خواهیم در backend سایت دیده شود را تعریف کنیم.
- files داخل بخش administration ، بخش files را تعریف می کنیم که به جوملا می گوید در کجای backend فایل های بسته ای را که نصب می کنیم ذخیره کند.
بخش files را می توان خارج از بخش administration استفاده کرد و اگر چنین است، نشان دهنده محل فایل هایی است که باید در قسمت frontend کامپوننت نصب شوند.
در فایل مانیفست ما، بخش files یک ویژگی پوشه نیز دارد. این ویژگی برای تعیین نام پوشه ای در بسته ما استفاده می شود که حاوی فایل ها و پوشه هایی است که می خواهیم آموزش دهیم. بخش files به دو تگ اجازه می دهد folder و filename
اولی نشان دهنده یک پوشه کامل است که باید قرار گیرد، همانطور که در پوشه backend کامپوننت است، و دومی نشان دهنده فایل های جداگانه ای است که می خواهیم اضافه کنیم.
- Menu در این بخش، پیوندی را که به منوی اصلی جوملا برای کامپوننت خود اضافه می کنیم، تعریف می کنیم. برای تعریف منو، برخی از ویژگی ها را به صورت زیر پر می کنیم:
- Link در اینجا، URL هدف کامپوننت خود را تنظیم می کنیم. در واقع جوملا URL را مشخص خواهد کرد. فقط باید پارامترهای آن را اضافه کنیم. در مورد ما، پارامتر option=com_spm است.
- img می توانیم از این برای اضافه کردن یک تصویر به ورودی منوی خود در backend استفاده کنیم. با این وجود، در قالب پیش فرض Joomla Administrator، این تصویر نشان داده نمی شود.
نمایش نمادها برای منوها در backend
در قالب پیش فرض backend جوملا، نمادهای موجود در آیتم های منو نشان داده نمی شوند. در این مورد، شما می خواهید برای کاربرانی که از یک قالب متفاوت استفاده می کنند یک تصویر ارائه دهید. بهترین گزینه این است که آن را با استفاده از CSS انجام دهید. روش استاندارد این است که این ویژگی را با کلاس css آیکون با پیشوند class: پر کنید.
بنابراین، در کد خود، می توانیم از
<menu link="option=com_spm" img="class:book">COM_SPM_MENU_BACKEND</menu>
استفاده کنیم. این یک نماد کتاب را در قالب های backend نشان می دهد.
برای نمایش این آیکون ها در جوملا از کتابخانه رایگان FontAwesome ( https://fontawesome.com ) استفاده می کنیم.
این حداقل فایل مانیفست ما را پوشش می دهد و اکنون می توانیم و اکنون می توانیم یک بسته کوچک کامپوننت جوملا برای خود ایجاد کنیم و سعی کنیم آن را در یک سایت جوملا نصب کنیم.
تست کامپوننت کوچک در جوملا
ما اکنون آماده ایم تا کامپوننت کوچک خود را در یک سایت جوملا نصب کنیم. اگر قبلاً وب سایت جوملا خود را ایجاد نکرده اید، اکنون زمان آن رسیده است که این کار را انجام دهید.
گزینه های زیادی برای راه اندازی سایت جوملا وجود دارد و برای این کتاب از سرویس راه اندازی جوملا استفاده خواهیم کرد. برای این کار کافیست به https://launch.joomla.org بروید، فرم را پر کنید و در عرض چند دقیقه یک وب سایت جوملا راه اندازی خواهید کرد.
قبل از نصب افزونه خود، باید یک بسته فشرده ایجاد کنیم که حاوی افزونه باشد. اگر ساختار دایرکتوری ما را در بخش های قبلی دنبال کرده اید، می توانید به راحتی آن را با ساخت یک فایل.zip که حاوی پوشه کامپوننت است ایجاد کنید. نام بسته میتواند هر چیزی باشد، اما توصیه می کنم نام آن را com_spm_TIMESTAMP.zip بگذارید.
به جای TIMESTAMP زمان و تاریخ فعلی را جایگزین کنید. این نام دارای مهر زمانی نیز می باشد، بنابراین می توانید به راحتی بسته را شناسایی کنید.
پس از ورود به backend جوملا ، به نصب کننده افزونه بروید و بسته را آپلود کنید.
پس از نصب آن، یک پیام موفقیت آمیز و یک جعبه اطلاعات با محتوای تگ description فایل مانیفست ما مشاهده خواهید کرد.
همچنین، وقتی روی بخش Components در منوی کناری کلیک می کنید، می بینید که یک ورودی منوی جدید با متن COM_SPM_MENU_BACKEND وجود دارد. اگر روی آن لینک کلیک کنید، به کامپوننت خود می روید و نمای کنترل پنل را مشاهده میکنید.
ایجاد نمای لیست برای کامپوننت
هورا! ما داریم اولین کامپوننت جوملا خود را ایجاد میکنیم، و در backend سایت ما نصب شده است! با این حال، باید اعتراف کنیم که هنوز کار زیادی انجام نداده است. بیایید آن را کمی مفیدتر کنیم.
در فصل قبل، تعدادی داده نمونه برای پایگاه داده در جداول کامپوننت خود نصب کردیم. بیایید یک لیست View برای داده های پروژه را آماده کنید.
افزودن View برای داده های پروژه
ما با افزودن پوشه ای به نام Projects در داخل پوشه src/component/admin/src/View شروع می شود.
داخل این پوشه، فایل HtmlView.php خود را نیز اضافه می کنیم، اما در حال حاضر، این فایل فاقد کدی برای فراخوانی مدل و دریافت داده های او قبل از ارسال آن به قالب است:
<?php
namespace Piedpiper\Component\Spm\Administrator\View\Projects;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
class HtmlView extends BaseHtmlView
{
public $filterForm;
public $state;
public $items=[];
public $pagination;
public $activeFilters=[];
public function display($tpl=null): void
{
$this->state = $this->get('State');
$this->items = $this->get('Items');
$this->pagination = $this->get('Pagination');
$this->filterForm = $this->get('FilterForm');
$this->activeFilters = $this->get('ActiveFilters');
if (count($errors = $this->get('Errors'))) {
throw new GenericDataException(implode('\n',
$errors), 500);
}
parent::display($tpl);
}
}
کد جدید متغیرهایی را دریافت می کند که در نمای لیست به آنها نیاز داریم. اول از همه، وضعیت جلسه را در ویژگی State بدست می آوریم. این حالت اطلاعاتی در مورد وضعیت درخواست ارائه می دهد. معمولاً اطلاعات مربوط به فیلترهای موجود، تعداد مواردی را که باید در فهرست نشان دهید و هر گونه اطلاعات غیر دائمی دیگری درباره کاربر، در حال مرور یک صفحه ذخیره می کند.
پس از گرفتن حالت، با فراخوانی متد $this->get('Items') از آیتم ها درخواست می کنیم که نشان داده شوند. این متد مستقیماً متد getItems() را در مدل فراخوانی می کند که آیتم ها را از پایگاه داده بازیابی می کند. در این صورت، لیست پروژه های موجود در پایگاه داده ما را بازیابی می کند.
بالاخره ما متغیر pagination $ و فرمی را برای ارائه فیلتری برای لیست دریافت می کنیم و کشف می کنیم که کدام فیلد فیلتر در این درخواست وجود دارد.
اگر هنگام فرآخوانی داده ها خطایی رخ دهد، آنها را می گیریم و یک ارور PHP، از جمله یک پیام خطا، ایجاد می کنیم. در این مورد، پیام خطای ما فقط لیستی از خطاهای متغیر $errors است. جوملا به طور خودکار خطاها را تشخیص می دهد و خطا را به کاربر نشان می دهد.
همانطور که می بینید، ما کار زیادی انجام نمی دهیم. ما فقط داده ها را با استفاده از متد $this->get() درخواست می کنیم. این روش یک گیرنده برای مدل است، بنابراین اجازه دهید ببینیم وقتی داده ها را درخواست می کنیم چه اتفاقی می افتد.
افزودن مدل به نمای پروژه ها
همانطور که ما با استفاده از الگوی MVC، یک مدل به کامپوننت خود اضافه می کنیم. این مدل وظیفه بازیابی اطلاعات از پایگاه داده را بر عهده دارد. برای ایجاد مدل، یکی از کلاس های مدل موجود در جوملا را نیز گسترش می دهیم. این تضمین می کند که ما از استانداردهای جوملا پیروی می کنیم و از کارهای اضافی برای ما جلوگیری می کند.
شما می توانید تمام مدل های ممکن را که می توانید در نصب جوملا خود گسترش دهید در پوشه libraries/src/MVC/Model پیدا کنید. برای مدل Backend خود، ما روی این موارد تمرکز خواهیم کرد:
- BaseModel : این اساسی ترین مدلی است که هر مدل دیگری مدیریت حالت اولیه را از آن به ارث می برد. با این حال، اتصال پایگاه داده را پیاده سازی نمی کند. مگر اینکه یک مدل بسیار ابتدایی ایجاد کنید، احتمالاً نمی خواهید از آن استفاده کنید.
- BaseDatabaseModel : این از BaseModel ارث می برد ، بنابراین مدیریت حالت را ارائه می دهد، اما روش هایی برای کوئری از پایگاه داده نیز ارائه می دهد.
- ListModel : این کلاس از BaseDatabaseModel ارث می برد و علاوه بر اتصال پایگاه داده، برخی از توابع را برای کمک به ما در ایجاد لیستی از موارد ارائه می دهد. به عنوان مثال، یک روش استاندارد برای پیاده سازی فیلتر در لیست های ما ارائه می دهد و به ما امکان می دهد برای به دست آوردن لیستی از موارد، پایگاه داده را بررسی کنیم.
هنگام توسعه backend کامپوننت خود، بیشتر اوقات از این مدل ها استفاده خواهید کرد. با این حال، این بدان معنا نیست که شما نمی توانید از آنها در قسمت frontend استفاده کنید.
همانطور که ما در حال توسعه لیستی از موارد هستیم، از ListModel استفاده می کنیم ، بنابراین فایل ProjectsModel.php را در داخل src/component/admin/src/Model خود ایجاد می کنیم. ما شروع به تعریف فضای نام خود خواهیم کرد و از فضاهای نام دیگری در این فایل استفاده خواهیم کرد :
<?php
namespace Piedpiper\Component\Spm\Administrator\Model;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\CMS\Factory;
در این مورد، ما باید فضای نام ListModel را که حاوی تعریف کلاسی است که در مدل خود تعمیم خواهیم داد، اعلام کنیم. اکنون، می توانیم اضافه کنیم کلاس:
class ProjectsModel extends ListModel
{
}
در کلاس ProjectsModel ما شروع به اضافه کردن متد __construct با این کد می کنیم :
public function __construct($config = [])
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = [
'id', 'a.id',
'name', 'a.name',
];
}
parent::__construct($config);
}
این سازنده والد کلاس است. یک آرایه پیکربندی را دریافت می کند. اگر کلاس والد را بررسی کنید، می توانید تمام گزینه هایی را که می توانید در این آرایه پیکربندی تنظیم کنید، مشاهده کنید. اما در کد ما فقط نام فیلد id و فیلد نام را اضافه می کنیم. اینها تنها دو فیلدی خواهند بود که به آنها اجازه می دهد، بر ترتیب فهرست پروژه هایمان نظارت کنند.
در یک مدل جوملا که از جوملا MVC پیروی می کند، باید متد ()populateState را تعریف کنیم، بنابراین آن را در ادامه اضافه می کنیم:
protected function populateState($ordering = 'name', $direction = 'ASC')
{
$app = Factory::getApplication();
$value = $app->input->get('limit', $app->get('list_limit', 0), 'uint');
$this->setState('list.limit', $value);
$value = $app->input->get('limitstart', 0, 'uint');
$this->setState('list.start', $value);
$search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
$this->setState('filter.search', $search);
parent::populateState($ordering, $direction);
}
متد ()populateState مهم است زیرا تمام اطلاعات ارسال شده را دریافت می کند. کاربر درخواست می کند و وضعیت برنامه را دوباره ایجاد می کند. به این ترتیب، لیست پروژه های ما تعداد موارد درخواستی را نشان می دهد یا هنگام جستجو در صفحات داده، همان ترتیب یا فیلترها را حفظ می کند.
در کد قبلی، تعداد کل پروژه هایی را که می خواستیم در هر صفحه نمایش دهیم را با ( Limit ) دریافت کردیم و اولین پروژه ای است که باید نمایش دهیم با ( Limitstart )نمایش داده میشود. به همراه اینکه آیا کاربر فیلترهای جستجو را اضافه کرده است، را با (search) نشان داده ایم.
در نهایت آخرین متدی که نیاز داریم getListQuery() است. این روش کوئری را ایجاد می کند که ما برای دریافت لیست آیتم ها، از پایگاه داده استفاده می کنیم.
در این متد از $db Object برای تعریف تمام قسمت های کوئری که جوملا به SQL ترجمه کرده و به پایگاه داده ارسال می کند، استفاده می کنیم. توجه داشته باشید که در این روش هیچ تماس مستقیمی با پایگاه داده وجود ندارد. ما فقط تمام اطلاعاتی را که می خواهیم استخراج کنیم، فراخوانی می کنیم و به کلاس والد ListModel اجازه می دهیم بقیه را مدیریت کند:
protected function getListQuery()
{
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select(
$this->getState('list.select',
[
$db->quoteName('a.id'),
$db->quoteName('a.name'),
$db->quoteName('a.deadline'),
]
)
)->from($db->quoteName('#__spm_projects', 'a'));
$search = $this->getState('filter.search');
if (!empty($search))
{
$search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%'));
$query->where('(a.name LIKE ' . $search . ')');
}
$orderCol = $this->state->get('list.ordering','a.name');
$orderDirn = $this->state->get('list.direction','ASC');
$query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn));
return $query;
}
این یک مدل ساده است که پایگاه داده را کوئری می کند و لیستی از نتایج را برمی گرداند. ما فقط سه روش را به مدل اضافه کرده ایم و ویژگی های زیادی به ما می دهد.
کار با انواع مختلف سیستم های SQL
یکی از ویژگی های جالب استفاده از کلاس Db جوملا این است که به طور خودکار درخواست شما را به MySQL یا PostgreSQL ترجمه می کند. بنابراین، اگر قصد دارید یک افزونه ایجاد کنید که بتواند در هر دو نوع داده کار کند، لازم نیست نگران آن باشید.
با این مدل حداقلی، نمای ما می تواند تمام داده هایی را که برای نمایش فهرستی از پروژه ها نیاز دارد، دریافت کند، بنابراین بیایید ببینیم چگونه می توانیم همه این اطلاعات را در قالب کنار هم قرار دهیم تا فهرست خود را در بخش بعدی نشان دهیم.
نمایش لیست پروژه ها
یک بار ما مدل و نما را ایجاد کرده ایم، فقط باید با افزودن فایل الگو، آن را زیبا کنیم. برای اضافه کردن فایل داده ما باید پوشه src/component/tmpl/projects/ را ایجاد کنیم و می توانیم فایل default.php را با استفاده از کد زیر ایجاد کنیم:
<?php
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\CMS\HTML\HTMLHelper;
$listOrder = $this->escape($this->state->get('
list.ordering'));
$listDirn = $this->escape($this->state->get('
list.direction'));
?>
طبق معمول، فضاهای نامی را که برای پشتیبانی از کد خود نیاز داریم، اعلام می کنیم.
در نهایت، ما چند متغیر را برای پیگیری سفارش تعریف می کنیم.
پس از این بلوک، می توانیم HTML را برای قالب خود اضافه کنیم:
<form action="<?php echo Route::_('index.php?option=
com_spm&view=projects'); ?>" method="post" name="
adminForm" id="adminForm">
<div class="table-responsive">
<table class="table table-striped">
<caption><?php echo Text::_('COM_SPM_PROJECTS
_LIST');?></caption>
<thead>
<tr>
<td><?php echo Text::_('COM_SPM_
PROJECTS_LIST_ID');?></td>
<td><?php echo Text::_('COM_SPM_
PROJECTS_LIST_NAME');?></td>
<td><?php echo Text::_('COM_SPM_
PROJECTS_LIST_DEADLINE');?></td>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $item) : ?>
<tr>
<td><?php echo $item->id; ?></td>
<td><?php echo $item->name; ?></td>
<td><?php echo $item->deadline; ?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php echo $this->pagination->getListFooter(); ?>
<input type="hidden" name="task" value="">
<?php echo HTMLHelper::_('form.token'); ?>
</form>
دریک جدول با سه ستون - شناسه ، نام و مهلت - اضافه می کنیم تا داده های پروژه های خود را نشان دهیم.
اگر نگاه دقیق تری به کد بیندازید، می بینید که ما جدول را در یک فرم HTML قرار داده ایم. ما باید این کار را انجام دهیم تا صفحه بندی و سایر اقداماتی را که در سراسر این کتاب اضافه خواهیم کرد، فعال کنیم. این اکشن فرم فقط به نمای پروژه های کامپوننت ما هدایت می شود.
پس از پرداختن به جدول خود، می بینید که یک فراخوانی به آبجکت صفحه بندی اضافه کرده ایم. این روش صفحه بندی را در موقعیت footer جدول ما نشان می دهد.
تا اینجا، ما یاد گرفته ایم که چگونه فهرستی از آیتم ها را در کامپوننت خود نشان دهیم و جوملا چگونه الگوی MVC را پیاده سازی می کند. علاوه بر این، ما همچنین تعدادی کتابخانه مفید جوملا را برای کاهش کدهایی که باید بنویسیم کشف کرده ایم. بیایید به بخش بعدی برویم تا ببینیم چگونه می توانیم موارد خود را ویرایش کنیم.
در حال ایجاد نمای ویرایش آیتم برای کامپوننت ما
علاوه بر این با فهرست کردن پروژه ها از پایگاه داده، کامپوننت ما ابزاری برای مدیریت آنها است. به عنوان یک مدیر پروژه، باید بتوانید پروژه های خود را ویرایش کنید. بیایید ببینیم چگونه می توانیم پروژه های خود را در این بخش ویرایش کنیم.
برای افزودن یک صفحه ویرایش برای پروژه های خود، یک نمای ویرایش برای پروژه های خود ایجاد می کنیم. برای این کار به موارد زیر نیاز داریم:
- نمای Project در پوشه View
- مدلی برای دریافت داده ها یا پروژه ما از پایگاه داده و ذخیره تغییرات ما
- یک طرح فایل داخل پوشه tmpl برای نمایش فرم ویرایش ما
- یک فیلد ProjectController در پوشه Controller
بیایید اولین نمای آیتم ویرایشی خود را شروع کنیم.
ایجاد نمای پروژه
نمای تک موردی کاملاً شبیه نمای لیست در جوملا است، اما تغییرات مهمی وجود دارد که باید از آنها آگاه باشیم. برای افزودن این نما، فایل src/component/admin/src/View/Project/HtmlView.php و سپس کلاس HTMLView را ایجاد کنید که آن را گسترش می دهد، همانطور که در قسمت قبل هنگام ایجاد نمای لیست انجام دادیم. بنابراین، بیایید با کد زیر شروع کنیم:
<?php
namespace Piedpiper\Component\Spm\Administrator\View\Project;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\ContentHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
class HtmlView extends BaseHtmlView
{
public $form;
public $state;
public $item;
}
در داخل کلاس خود، باید متد displaye() را معرفی کنیم تا داده ها را به مدل درخواست کند و آن را به قالب ارسال میکند. بنابر این ما به اضافه کردن کد ادامه خواهیم داد:
public function display($tpl=null): void
{
$this->form = $this->get('Form');
$this->state = $this->get('State');
$this->item = $this->get('Item');
if (count($errors = $this->get('Errors')))
{
throw new GenericDataException(implode("\n",
$errors), 500);
}
$this->addToolbar();
parent::display($tpl);
}
در این بلوک کد، صفحه بندی و فیلتر را از نمای لیست قبل حذف کردیم، زیرا ما دیگر با فهرستی از موارد سروکار نداریم. در عوض، یک ویژگی Form اضافه کردیم که تعریف فرم HTML را که در قالب به کاربران خود نشان خواهیم داد، بازیابی می کند.
ما همچنین یک روش جدید اضافه کردیم به نام addToolbar(). این روش به ما کمک می کند تا دکمه های Save, Apply, and Cancel را با کد جوملا که قبلا ارائه کرده، اضافه کنیم. می توانیم این روش را به صورت زیر تعریف کنیم:
protected function addToolbar()
{
Factory::getApplication()->input->set('hidemainmenu',true);
$isNew = ($this->item->id == 0);
$canDo = ContentHelper::getActions('com_spm');
$toolbar = Toolbar::getInstance();
ToolbarHelper::title(
Text::_('COM_SPM_PROJECT_TITLE_' . ($isNew ?
'ADD' : 'EDIT'))
);
if ($canDo->get('core.create'))
{
if ($isNew)
{
$toolbar->apply('project.save');
}
else
{
$toolbar->apply('project.apply');
}
$toolbar->save('project.save');
}
$toolbar->cancel('project.cancel', 'JTOOLBAR_CLOSE');
}
در این متد، ما از کلاس های Toolbar و ToolbarHelper از پایه کد جوملا برای ایجاد دکمه های عمل، با استفاده از متدهای application()، save() و cancel() استفاده می کنیم.
مقداری که ما برای این متدها استفاده می کنیم، نام کنترل کننده و وظیفه ای است که باید اجرا شود. بنابراین، به عنوان مثال، برای دکمه save ، نوار ابزار را با کنترلر project و وظیفه save مقداردهی اولیه می کنیم.
در کد view، می بینید که ما برخی از بررسی های سطح دسترسی یا مجوز را انجام می دهیم تا تصمیم بگیریم کدام دکمه های عملکرد را نشان دهند. برای انجام این کار، ما به سادگی بررسی می کنیم که چه اقداماتی را می توان با توجه به مجوزهای کاربر انجام داد. این مجوزهای کاربر با استفاده از پیکربندی سطح دسترسی جوملا (ACL) پیکربندی می شوند.
در فصل 5 به جزئیات بیشتری خواهیم پرداخت ، اما در حال حاضر، می توانیم ACL استاندارد را به راحتی تعریف کنیم. ما فقط باید یک فایل جدید به نام access.xml را به پوشه اصلی backend کامپوننت خود اضافه کنیم. در داخل این فایل اقدامات مختلفی را که می توانیم انجام دهیم را تعریف خواهیم کرد.
بنابراین، فایل access.xml را در آن ایجاد کنید پوشه src/component/admin را با کد زیر کنار بگذارید :
<?xml version="1.0" encoding="utf-8" ?>
<access component="com_spm">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" />
<action name="core.options" title="JACTION_OPTIONS" />
<action name="core.manage" title="JACTION_MANAGE" />
<action name="core.create" title="JACTION_CREATE" />
<action name="core.delete" title="JACTION_DELETE" />
<action name="core.edit" title="JACTION_EDIT" />
</section>
</access>
با این فایل ساده، ما قابلیت های اساسی ACL را به کامپوننت خود اضافه می کنیم و ما می توانیم از ACL جهانی برای مدیریت دسترسی به افزونه خود استفاده کنیم.
افزودن مدل برای بازیابی و ذخیره داده ها
برای یک مدل view آیتم، خواهید دید که اگر جوملا MVC را رعایت کنید، با نمای فهرست کاملاً متفاوت است. بیایید فایل ProjectModel.php را در داخل src/component/admin/src/Model/ با کد زیر ایجاد کنیم:
<?php
namespace Piedpiper\Component\Spm\Administrator\Model;
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\AdminModel;
class ProjectModel extends AdminModel
{
}
برای آسان تر کردن کارها، کلاس AdminModel را از کتابخانه جوملا MVC گسترش می دهیم که فایل ما را کوچک می کند. در این فایل، ما نیازی به یادآوری وضعیت یا اضافه کردن صفحه بندی به view نداریم، بنابراین تمام آن متدها در مدل گنجانده نشده است. کاری که ما انجام می دهیم فرمی است که برای ارسال تغییرات استفاده خواهیم کرد. برای بازیابی فرم، باید متد getForm() را با استفاده از کد زیر تعریف کنیم:
public function getForm($data = array(), $loadData = true)
{
$form = $this->loadForm(
'com_spm.project',
'project',
[
'control' => 'jform',
'load_data' => $loadData
]);
if (empty($form)) {
return false;
}
return $form;
}
این متد جادویی کد ها را فشرده میکند تا فرایند آسان تر شود. در پارامتر اول رشته com_spm.project را پاس می کنیم. این به روش دستور می دهد تا فایل project.xml را در داخل پوشه forms در backend کامپوننت ما جستجو کند.
این متد loadForm() متد loadFormData() را نیز فراخوانی می کند که می توانیم آن را به صورت زیر تعریف کنیم:
protected function loadFormData()
{
$app = Factory::getApplication();
$data = $app->getUserState(
'com_spm.edit.project.data',
[]
);
if (empty($data)) {
$data = $this->getItem();
}
return $data;
}
متد loadFormData() فرم را با مقادیر پایگاه داده یا درخواست پر می کند. برای این کار از متد getItem() استفاده می کند. ما می توانیم آن را تعریف کنیم، اما از آنجایی که داده های آیتم فقط در یک جدول از پایگاه داده ما هستند، می توانیم از متد getItem() ارائه شده در کلاس AdminModel استفاده کنیم.
ساخت پوشه فرم ها
ما مزایای فرم های جوملا را در فصل 4 خواهیم دید، اما بیایید اولین فرم خود را اکنون ایجاد کنیم تا بتوانیم پروژه های خود را ویرایش کنیم::
- پوشه Form را در داخل src/component/admin/ ایجاد کنید. این مکانی خواهد بود که در آن همه فرم ها را ایجاد خواهیم کرد.
- در داخل این پوشه، ما تمام تعاریف فرمی را که برای backend کامپوننت خود نیاز داریم، اضافه می کنیم.
برای تعریف فرم در جوملا، از یک فایل xml. استفاده می کنیم که در آن دستورالعمل هایی را برای فیلدها ارائه می دهیم. از فرم ما برای فرم ویرایش پروژه خود، فایل src/component/admin/forms/project.xml را ایجاد می کنیم و آن را با این کد پر می کنیم:
<?xml version="1.0" encoding="UTF-8"?>
<form>
<field
name="name"
type="text"
label="COM_SPM_PROJECT_NAME"
required="true"
/>
<field
name="alias"
type="text"
label="COM_SPM_PROJECT_ALIAS"
required="false"
/>
<field
name="description"
type="text"
label="COM_SPM_PROJECT_DESCRIPTION"
required="false"
/>
<field
name="deadline"
type="text"
label="COM_SPM_PROJECT_DEADLINE"
required="false"
/>
<field
name="created_by"
type="user"
label="COM_SPM_PROJECT_CREATED_BY"
filter="unset"
/>
</form>
برای ساده تر کردن کارها در این مرحله، از یک فیلد Text ساده برای همه فیلدها استفاده می کنیم. در فصل 4، نحوه استفاده از انواع فیلدهای دیگر و توسعه فیلدهای خود را خواهیم آموخت.
دریافت اطلاعات پروژه از پایگاه داده
به دریافت داده از پایگاه داده، متد loadFormData() متد getItem() را فراخوانی می کند که قبلاً در کلاس AdminModel تعریف شده است و نیازی به ایجاد آن نداریم. با این حال، جوملا برای استفاده از روش استاندارد دریافت (و ذخیره) داده برای یک آیتم، از الگوی طراحی Active Record استفاده می کند. این بدان معنی است که ما باید یک پوشه جدید در ساختار MVC خود ایجاد کنیم:
– src/component/admin/src/Table
در داخل این پوشه جدید، فایل ProjectTable.php را با کد زیر ایجاد کنید:
<?php
namespace Piedpiper\Component\Spm\Administrator\Table;
use Joomla\CMS\Table\Table;
use Joomla\Database\DatabaseDriver;
class ProjectTable extends Table
{
public function __construct(DatabaseDriver $db)
{
parent::__construct('#__spm_projects', 'id', $db);
}
}
در این کد، ما از کتابخانه های جوملا نهایت بهره را می بریم و کلاس جدول جوملا را گسترش می دهیم. کلاس Table الگوی به اصطلاح Active Record را پیاده سازی می کند که به ما اجازه می دهد تا رکورد های پایگاه داده خود را به عنوان اشیاء برنامه نویسی در نظر بگیریم. برای ارتباط این کلاس با جدول پایگاه داده، نام جدول، نام کلید اصلی جدول و db object$ را ارسال می کنیم.
افزودن یک controller به نهاد پروژه ما
ما باید یک کنترلر اضافه کنیم تا کنترل کنیم کدام اقدامات برای داده های ما انجام می شود. با این حال، طبق معمول، جوملا اکثر کارها را در صورت رعایت استانداردهای آن انجام می دهد، بنابراین فقط باید فایل ProjectController.php را در داخل پوشه src/component/admin/src/Controller با حداقل کد ایجاد کنیم:
<?php
namespace Piedpiper\Component\Spm\Administrator\Controller;
use Joomla\CMS\MVC\Controller\FormController;
class ProjectController extends FormController
{
}
از آنجایی که ما کلاس FormController را گسترش می دهیم، متدهای save، application و cancel قبلا پیاده سازی شده اند، بنابراین نیازی به انجام کاری نداریم.
ایجاد یک طرح برای نمای ویرایش پروژه
هنگامی که همه کدها و فایل های مورد نیاز برای ویرایش یک پروژه را اضافه کردیم، فقط باید یک طرح برای نمای ویرایش پروژه خود ایجاد کنیم. همانطور که قبلا با نمای پروژه ها انجام دادیم ، باید چیدمان را با رابط کاربری برای فرم ویرایش خود ایجاد کنیم. بنابراین، در داخل src/component/admin/tmpl/ فایل edit.php را با کد زیر ایجاد می کنیم:
<?php
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Router\Route;
HTMLHelper::_('behavior.formvalidator');
HTMLHelper::_('behavior.keepalive');
?>
<form action="<?php echo Route::_('index.php?option=
com_spm&view=project&layout=edit&id=' . (int) $this->
item->id); ?>" method="post" name="adminForm" id="project-form" class="form-alidate">
<div>
<div class="row">
<div class="col-md-9">
<div class="row">
<div class="col-md-6">
<?php echo $this->form->
renderField('name'); ?>
<?php echo $this->form->
renderField('alias'); ?>
<?php echo $this->form->
renderField('description'); ?>
<?php echo $this->form->
renderField('deadline'); ?>
</div>
</div>
</div>
</div>
</div>
<input type="hidden" name="task" value="">
<?php echo HTMLHelper::_('form.token'); ?>
</form>
در این کد، یک عنصر فرم را با استفاده از object فرم که در view به دست آورده ایم، اضافه می کنیم تا فیلدهای خود را با استفاده از متد ()renderField ارائه کنیم. به این ترتیب، این جوملا است که فیلدها را از تعریف ما ایجاد می کند، و از تمام ویژگی ها و نیازهای HTML برای فرم های ما مراقبت می کند. به عنوان مثال، از تنظیم ویژگی مورد نیاز در فیلد HTML مراقبت می کند.
در ابتدای کد، دو کمک کننده را نیز فراخوانی می کنیم:
HTMLHelper::_('behavior.formvalidator');
HTMLHelper::_('behavior.keepalive');
اینها شامل برخی از کد های مفید جاوا اسکریپت در صفحه است. اولی اعتبار سنجی جاوا اسکریپت را فراهم می کند، بنابراین خطاهای موجود در فرم را شناسایی و در مورد آن اطلاع می دهد، و دومی به فعال نگه داشتن جلسه در هنگام پر کردن فرم کمک می کند.
یک واقعیت جالب دیگر این است که شما باید ویژگی name=adminForm را در فرم های خود قرار دهید تا دکمه های نوار ابزاری که ما از view اضافه کرده ایم خارج از کادر کار کنند (در غیر این صورت، باید کد جاوا اسکریپت خود را اضافه کنید تا آنها کار کنند).
در انتهای فرم یک فیلد مخفی به نام task تعریف می کنیم. این فیلد برای استفاده از دکمه های نوار ابزار نیز لازم است و جوملا از آن برای دانستن آنچه می خواهید در درخواست خود انجام دهید استفاده می کند.
آخرین خط قبل از بستن فرم نیز در جوملا الزامی است. این خط یک فیلد مخفی دیگر را با یک کلید تصادفی به فرم ما اضافه می کند که از سایت ما در برابر حملات Cross-Site Scripting (XSS) محافظت می کند.
تغییرات در فایل مانیفست ما
همانطور که ما چند پوشه جدید به ساختار کامپوننت خود اضافه کرده ایم، باید آنها را در فایل مانیفست منعکس کنیم. در غیر این صورت جوملا آنها را نصب نخواهد کرد. بنابراین، ما مانیفست خود را باز می کنیم و پوشه های جدید را به بخش فایل ها اضافه می کنیم و فایل access.xml را نیز اضافه می کنیم.
در این مرحله می توانیم یک لینک مستقیم در منو برای نمای پروژه ها نیز قرار دهیم تا به راحتی به آن دسترسی داشته باشیم. برای این کار از تگ submenu استفاده می کنیم و لینک منو را در آنجا تعریف می کنیم.
فایل مانیفست نهایی ما به شکل زیر است:
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" method="upgrade">
<name>COM_SPM</name>
<author><![CDATA[Carlos Cámara]]></author>
<authorEmail>
تست کامپوننت
در این مرحله، کنترلر ویرایش پروژه خود را به پایان رساندیم و اکنون زمان خوبی برای بررسی نحوه عملکرد آن به نظر میرسد. بنابراین، یک فایل .zip جدید با محتوای پوشه src/component خود ایجاد کنید و آن را در سایت جوملا خود نصب کنید.
پس از نصب موفقیت آمیز، مشاهده خواهید کرد که لینک کامپوننت اصلی در نوار کناری به یک کشویی تغییر یافته است که پس از کلیک روی آن، لینک Projects را نشان می دهد.
همچنین، می توانیم نمای edit/new project خود را با استفاده از این URL مشاهده کنیم:
/ administrator/index.php?option=com_spm&view=project&layout=edit
ما نمای ویرایش و تمام قسمت های دیگر MVC را که برای ویرایش پروژه هایمان لازم است، به پایان رسانده ایم. ما اکنون آماده ایم تا داده های خود را در قسمت frontend برنامه ی خود مشاهده کنیم.
منابع فصل
- اگر تازه وارد جوملا هستید، می توانید این مقدمه را برای اجزای موجود در اسناد رسمی جوملا را بخوانید:
- می توانید درباره کلاس Table در مستندات رسمی جوملا اطلاعات بیشتری کسب کنید: