بیان خلاصه ای از بحث توسط هوش مصنوعی:
رابط های خط فرمان Command-Line Interfaces ( CLIs ) ابزاری محبوب برای توسعه دهندگان برای خودکار کردن وظایف خاص هستند. برنامه های CLI برای استفاده از طریق یک شبیه ساز ترمینال، مانند xterm در سیستم های لینوکس، خط فرمان ویندوز (Command Prompt) در سیستم های ویندوز، یا برنامه ترمینال در macOS در نظر گرفته شده است.
رایج ترین دلیلی که مردم ازCLI استفاده می کنند، خودکار کردن برخی وظایف است. این را می توان با Cron Jobs یا با گنجاندن دستورات CLI در یک خط لوله خودکار توسعه (مثلاً یک خط لوله ادغام پیوسته) انجام داد.
Pipeline یا خط لوله : مجموعه ای از عناصر (مراحل) پردازش داده است که به صورت سری به یکدیگر متصلند و ورودی هر عنصر، خروجی عنصر قبلی است. در تکنیک pipeline، چند دستور می توانند در یک زمان اجرا شوند. یعنی دستورها از لحاظ زمان اجرا دارای همپوشانی هستند.
بسیاری از CMS ها و فریم ورک های PHP یک برنامه CLI را با نام های مختلف پیاده سازی می کنند.
به عنوان مثال، می توانید در لاراول از Artisan ، کنسول Symfony،و در وردپرس WP-CLI یا حتی برای پرستاشاپ PrestaShop CLI را پیدا کنید. برخی از این سیستم ها در واقع کد و بسته هایی را برای ایجاد CLI خود به اشتراک می گذارند. جوملا CLI مبتنی بر کامپوننت Symfony Console است.
در این فصل قصد داریم جوملا CLI را بررسی کنیم و گزینه های ارائه شده را ببینیم. ما یاد خواهیم گرفت که چگونه یک برنامه کاربردی CLI ایجاد کنیم که وظایف نزدیک به ضرب الاجل را شناسایی می کند و با استفاده از Cron Job یک ایمیل یادآوری برای ما ارسال می کند.
در پایان این فصل، نحوه تعامل با جوملا CLI را خواهید فهمید و نحوه ایجاد برنامه های کاربردی جوملا CLIخود را خواهیم فهمید.
اینها موضوعات خاصی هستند که می خواهیم بررسی کنیم:
- CLI چیست ؟
- نحوه استفاده از جوملا CLI
- اضافه کردن دستور به CLI جوملا!
- اضافه کردن پارامترها به دستور CLI
الزامات فنی
- شبیه ساز ترمینال برای اتصال به سایت جوملا
- دسترسی SSH یا دسترسی مستقیم به ترمینال به سرور سایت جوملا شما
- راهی برای برنامه نویسی Cron Job در سایت شما
- سایتی که قبلا ایجاد کردیم
می توانید کد استفاده شده در این فصل را در GitHub پیدا کنید:
https://github.com/PacktPublishing/Developing-Extensions-for-Joomla-5/tree/chapter09
CLI چیست؟
CLI یک رابط مبتنی بر متن برای تعامل با وب سایت شما، با استفاده از دستورات متنی تایپ شده روی صفحه کلید شماست. در یک CLI، شما نمی توانید از ماوس (Mouse) خود برای انجام هیچ عملی استفاده کنید، زیرا در واقع حتی یک رابط گرافیکی نیز ندارد.
برنامه های CLI نسبت به برنامه های وب معمولی مزایایی دارند :
- آنها نسبت به صفحات وب کارایی بیشتری دارند، زیرا مجبور نیستند عناصر گرافیکی را نشان دهند، و از آنجایی که از طریق خط فرمان سرور فعال می شوند، برای ایجاد اتوماسیون عالی هستند. در واقع، شما نمی توانید از طریق مرورگر وب خود به یک برنامه CLI دسترسی داشته باشید.
- با استفاده از یک برنامه CLI، می توانید از برخی محدودیت های سرور مانند حداکثر محدودیت زمانی برای اجرا اجتناب کنید. بنابراین، اجرای اسکریپت های وقت گیر از ترمینال سرور منجر به خطای تایم اوت نمی شود.
- برنامه های CLI از Webhooks امن تر هستند، زیرا فقط می توانند از طریق داخلی سرور شما راه اندازی شوند. این مانع از تلاش مهاجمان برای دسترسی به آنها برای آسیب رساندن به سایت شما می شود.
برای تعامل با یک CLI، باید از شبیه ساز ترمینال یا خط فرمان استفاده کنیم، مانند xterm در لینوکس، ترمینال در macOS، یا خط فرمان Windows Command Prompt در سیستم های ویندوز.
هنگام استفاده از CLI در یک وب سایت در یک سرور راه دور، ما معمولاً از طریق SSH به سرور متصل می شویم تا با CLI تعامل داشته باشیم.
در برخی از حالات، به دلایل امنیتی نمی توانیم از طریق SSH به سرور متصل شویم (به عنوان مثال، وب سرورهای اشتراکی اجازه دسترسی به SSH را نمی دهند.) در این سیستم ها، ما همچنان می توانیم از یک برنامه CLI از طریق ویژگی Cron Job آنها استفاده کنیم.
Cron Job چیست؟
Cron Job یک سیستم زمانبندی کارها، مبتنی بر زمان موجود در سیستم های مبتنی بر لینوکس وجود دارد.
Cron Job در مدیریت وب برای خودکار سازی کارهای تکراری یا بدون مراقبت، بسیار محبوب است. از این رو، اکثر سرور ها آنها یا ابزاری مشابه را پیاده سازی می کنند.
برای پیکربندی Cron Job، باید یک بازه زمانی خاص و دستوری را که می خواهید اجرا کنید، تعریف کنید. عبارت برای تعریف Cron Job ما شامل پنج فیلد است که زمان انجام کار را مشخص می کند - دقیقه، ساعت، روز در ماه، ماه و روز در هفته. پس از آن دستور اجرا را اضافه می کنیم.
به عنوان مثال، یک پیکربندی مشترک Cron Job می تواند موارد زیر باشد:
05 3 * * * php cli/joomla.php update:extensions:check
این عبارت Cron Job هر روز ساعت 3:05 بروز رسانی های افزونه را در وب سایت جوملا بررسی می کند. گاهی اوقات، شما نیاز دارید که مسیر کامل را به نسخه PHP خود اضافه کنید، و همچنین ممکن است لازم باشد چند پوشه اضافی برای دسترسی به دایرکتوری cli جوملا اضافه کنید.
در هر صورت، ممکن است آنها را در ابزارهای مدیریت سرور خود بیابید. (به عناوینی مانند scheduled tasks ، Cron tasks ، یا نام های مشابه.) اگر روی رایانه شخصی خود کار می کنید، می توانید با استفاده از دستور Cron Tab در ترمینال خود به وظایف دسترسی پیدا کنید. برای کسب اطلاعات بیشتر در مورد Cron Job، بخش منابع در پایان این فصل را بررسی کنید.
اکنون که می دانید برنامه CLI چیست و چگونه می توانید از آن با سیستم زمان بندی وظایف خود استفاده کنید، بیایید به جزئیات CLI جوملا بپردازیم.
نحوه استفاده از جوملا CLI
جوملا CLI بر اساس کنسول Symfonyاست و می توانید با فراخوانی فایل cli/joomla.php از وب سایت خود به آن دسترسی داشته باشید. همانطور که قبلا گفته شد، شما نمی توانید از مرورگر وب خود به آن دسترسی داشته باشید. برای دسترسی به جوملاCLI ، باید از یک ترمینال استفاده کنید و دستورات را تایپ کنید.
در این کتاب فرض می کنیم که شما SSH یا دسترسی مستقیم به نصب جوملا دارید. بنابراین، ترمینال خود را راه اندازی کنید و آن را در پوشه root جوملا خود تنظیم کنید.
ابتدا نسخه PHP مورد استفاده در ترمینال را بررسی می کنیم. این امکان وجود دارد که سرور شما از یک نسخه PHP خاص برای وب سایت جوملا و از نسخه ی دیگری برای CLI استفاده کند. برای بررسی نسخه PHP خود، کد زیر را تایپ می کنید:
php -v
اگر همان نسخه ایست که وب سایت شما را اجرا می کند، میتوانید ادامه دهید. اگر نسخه مشابه نیست، باید بررسی کنید که حداقل پایین ترین نسخه ایست که می توانید در جوملا اجرا کنید.
هنگامی که از نسخه PHP-CLI خود مطمئن شدیم، می توانیم کار با CLI جوملا برای فراخوانی برنامه CLIرا شروع کنیم ، باید فایل joomla.php را در داخل پوشه cli فراخوانی کنیم، بنابراین در ترمینال خود عبارت زیر را تایپ می کنیم :
php cli/joomla.php
این یک پیام راهنما با گزینه های استفاده از CLI جوملا لیست می کند. در این پیام می توانیم دستورات یا برنامه های موجود برای نصب جوملا و گزینه های عمومی که می توانیم استفاده کنیم را مشاهده کنیم.
سینتکس CLI جوملا به شرح زیر است:
php cli/joomla.php COMMAND OPTIONS ARGUMENTS
بیایید با جزئیات، نحوه ی کار با این دستورات را ببینیم.
معرفی دستورات CLIجوملا
دستورات CLI جوملا اقداماتی هستند که می توانیم در سایت جوملا انجام دهیم. ما می توانیم دستورات بیشتری را به دستوراتی که خارج از جعبه (اصطلاح Out of box یعنی پس از نصب قابل اجرا خواهد بود) شامل می شوند، اضافه کنیم. دستورات در فضای نام گروه بندی می شوند. در این زمینه، فضاهای نام نشان دهنده مناطق مختلف سایت شما هستند. در نصب اولیه ی جوملا، ممکن است فضاهای نامی مانند Database را پیدا کنید که همه دستورات مربوط به اقدامات پایگاه داده یا Extension را که تمام دستورات مربوط به مدیریت افزونه را پوشش می دهد، پیدا کنید. با استفاده از دستور list می توانید تمام دستورات و فضاهای نام موجود را پیدا کنید:
php cli/joomla.php list
پس از اجرای این دستور در ترمینال خود، یک پیام استفاده مختصر را مشاهده خواهید کرد و به دنبال آن تمام دستورات بر اساس فضای نام گروه بندی شده است. در نصب اولیه ی جوملا ما 11 فضای نام با حداقل یک دستور در هر فضای نام داریم. تمام دستورات با اسم فضای نام و عملی که انجام داده اند، تشکیل می شوند. به عنوان مثال، برای فضای نام extension ، دستورات زیر را داریم :
- extension:discover این دستور باعث میشود جوملا، افزونه های حذف شده را در ساختار پوشه کشف کند
- extension:discover:install این دستور یک اکتشاف انجام می دهد و سپس افزونه های کشف شده را نصب می کند.
- extension:discover:list این فقط افزونه های کشف شده را فهرست می کند
- extension:list این دستور تمام افزونه های نصب شده در سایت را فهرست می کند
- extension:remove این دستور باید شناسه افزونه ای که می خواهیم حذف کنیم را پیدا کند، و آن افزونه را از سایت حذف خواهد کرد
برخی از دستورات برای انجام اقدامات خود به آرگومان نیاز دارند، اما در هر صورت، همه دستورات برخی از گزینه های عمومی را برای تغییر خروجی خود می پذیرند. در بخش بعدی بیشتر به این گزینه ها خواهیم پرداخت.
معرفی گزینه های عمومی برای CLI جوملا
دستورات CLI ممکن است گزینه هایی را بپذیرید تا خروجی آنها را اصلاح کرده و آن را با نیازهای ما تطبیق دهید. هر دستور ممکن است چندین گزینه داشته باشد که با بررسی کمک آنها ظاهر می شود (که می توانید با افزودن گزینه -h به دستور آنها دسترسی پیدا کنید)، اما گزینه های عمومی نیز وجود دارد که می توانید از آنها استفاده کنید. اینها گزینه های عمومی موجود در زمان نوشتن هستند:
- –live-site[=LIVE-SITE]
جایی که LIVE-SITE آدرس واقعی سایت شما است. برنامه CLI آدرس سایت را نمی شناسد، بنابراین با افزودن این پارامتر آدرس وب سایت مشخص می شود. زمانی که یک برنامه CLI باید لینک های سایت را برگرداند، مانند لینک های فعال سازی، مفید است. اگر وجود نداشته باشد، CLI سعی خواهد کرد از پارامتر $live_site از فایل configuration.php جوملا استفاده کند.
- -h, –help
این گزینه یک پیام راهنما برای دستوری که می خواهید استفاده کنید نشان می دهد. اگر دستوری را مشخص نکنید، یک پیام راهنما کوتاه نشان می دهد.
- -n, –no-interaction
این گزینه از پرسیدن سوال از کاربر جلوگیری می کند.
- -q, –quiet
این گزینه خروجی فرمان را خاموش می کند. همچنین گزینه no-interaction را تنظیم می کند.
- -V, –version
با افزودن این گزینه، نسخه جوملا شما نمایش داده می شود.
- –ansi
این گزینه خروجی را مجبور می کند تا زمانی که ترمینال از ANSI پشتیبانی می کند رنگارنگ باشد.
- –no-ansi
این گزینه خروجی ANSI را غیرفعال می کند.
- -v|vv|vvv, –verbose
با این گزینه می توانید مقدار اطلاعات موجود در خروجی را انتخاب کنید.
روش معمول استفاده از یک گزینه این است که قبل از آن دو خط تیره قرار دهید، "--" ، اما برخی از دستورات یک شکل کوتاه دارند که قبل از آن فقط یک خط تیره وجود دارد "-" به عنوان مثال، "-h" همان "--help" است.
این انعطاف پذیری زیادی را فراهم می کند، زیرا ما احتمالاً می خواهیم از گزینه های مختلف مطابق با سناریوی خود استفاده کنیم. به عنوان مثال، برای وظایف یکپارچه سازی مداوم، گزینه -n انتخاب جالبی به نظر می رسد، و برای عملیات Cron Job، گزینه -q ما را از دریافت ایمیل های زیاد نجات می دهد.
حالا که با CLI جوملا آشنا شدیم، بیایید برنامه CLI خود را برای پروژه های افزونه ی Simple Project Manager ایجاد کنیم.
افزودن دستور CLI جوملا به جوملا
در جوملا، ما می توانیم دستورات خود را به CLI اضافه کنیم و برای هر دستوری که می خواهیم اضافه کنیم، یک پلاگین ایجاد کنیم. این پلاگین ها متعلق به گروه پلاگین کنسول (console plugin group) هستند. با دستورات خارج از جعبه (اصطلاح Out of box یعنی پس از نصب قابل اجرا خواهد بود) پلاگین ارتباط ندارند، اما در کتابخانه های جوملا گنجانده شده اند، بنابراین شما گروه پلاگین کنسول را در نصب اولیه ی جوملا نخواهید دید.
بعد از فصل 8 ، ما می دانیم که چگونه پلاگین های جوملا را کدنویسی کنیم، بنابراین می توانیم ساختار اصلی پلاگین خود را ایجاد کرده و مانیفست را اضافه کنیم. بیایید فایل src/plugins/console/spm/spm.xml را با محتوای زیر ایجاد کنیم:
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="console" method="upgrade">
<name>plg_console_spm</name>
<author>Carlos Cámara</author>
<creationDate>2023-05</creationDate>
<copyright>(C) 2023 Piedpiper, Inc.</copyright>
<license>GNU General Public License version 2 or later;
see LICENSE.txt</license>
<authorEmail>این آدرس ایمیل توسط spambots حفاظت می شود. برای دیدن شما نیاز به جاوا اسکریپت دارید </authorEmail>
<authorUrl>https://extensions.hepta.es</authorUrl>
<version>1.0.0</version>
<description>PLG_CONSOLE_SPM_XML_DESCRIPTION</description>
<namespace path="src">Piedpiper\Plugin\Console\Spm
</namespace>
<files>
<folder plugin="spm">services</folder>
<folder>src</folder>
</files>
</extension>
این ممکن است برای شما آشنا باشد، زیرا همان مانیفست اصلی است که در فصل قبل استفاده کردیم. تنها تفاوت این است که می توانیم ببینیم که گروه پلاگین در این مانیفست روی کنسول تنظیم شده است، و همچنین، ما یک پوشهtmpl برای ذخیره قالب های چیدمان خود نداریم، همانطور که در کنسول، نیازی ندارد.
ما یک پلاگین برای دستور CLI خود ایجاد خواهیم کرد تا آن را در ابتدای چرخه اجرای جوملا CLI اضافه کنیم. بنابراین، بیایید یک کلاس افزونه ایجاد کنیم تا پلاگین خود را در رویداد Before Execute ثبت کنیم. فایل src/plugins/console/spm/src/Extension/SpmConsolePlugin.php را با محتوای زیر ایجاد خواهیم کرد:
<?php
namespace Piedpiper\Plugin\Console\Spm\Extension;
use Joomla\Event\SubscriberInterface;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Application\ApplicationEvents;
use Piedpiper\Plugin\Console\Spm\CliCommand\
SpmTaskDeadlineCommand;
class SpmConsolePlugin extends CMSPlugin implements
SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
ApplicationEvents::BEFORE_EXECUTE =>
'registerCLICommands'
];
}
public function registerCLICommands(ApplicationEvent
$event): void
{
$app = $event->getApplication();
$app->addCommand(new SpmTaskDeadlineCommand());
}
}
در این کد، ما قصد داریم از متد registerCLICommands برای ثبت دستورات خود استفاده می کنیم. ما فقط یک دستور را ثبت می کنیم و ابتدا باید کد آن را ایجاد کنیم.
بنابراین، ما فایلsrc/plugins/console/spm/src/CliCommand/SpmTaskDeadlineCommand.php را با محتوای زیر ایجاد می کنیم:
<?php
namespace Piedpiper\Plugin\Console\Spm\CliCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Joomla\Console\Command\AbstractCommand;
class SpmTaskDeadlineCommand extends AbstractCommand
{
protected static $defaultName = 'spm:task:deadline';
protected function configure(): void
{
$this->setDescription('List upcoming task deadlines');
$this->setHelp('The <info>$command.name%</info>
command lists all the tasks with upcoming
deadlines. <info>php%command.full_name%</info>');
}
protected function getDeadlines() : array
{
$deadlines = [];
$days = 7;
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select('*')
->from('#__spm_tasks');
$query->where('deadline BETWEEN NOW() AND
DATE_ADD(NOW(), INTERVAL ' . $days .' DAY)');
$query->setQuery($query);
$deadlines = $db->loadAssocList('id');
return $deadlines;
}
protected function doExecute(InputInterface $input, OutputInterface $output): int
{
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->title('Simple Project Manager Upcoming Deadlines');
$deadlines = $this->getDeadlines();
if (empty($deadlines)) {
$this->outputStyle->note('There is no upcoming deadlines');
} else {
$this->outputStyle->table(['Deadline', 'Project', 'Task'], $deadlines);
}
return Command::SUCCESS;
}
}
این کلاس در فضای نام ما، Piedpiper ، و همه جادو ها در آنجا اتفاق می افتد. ابتدا، می توانیم ببینیم که چقدر به کنسول Symfony وابسته است، زیرا بیشتر فضاهای نامی که ما استفاده می کنیم از فضای نام آن هستند، اما همچنین می توانیم ببینیم که چگونه از کلاس AbstractCommand از فضای نام کنسول چارچوب جوملا استفاده می کنیم. این کلاس همان کلاسی است که ما گسترش خواهیم داد، زیرا راه حلی برای وظایف رایج دستورات CLI ارائه می دهد.
در متغیر $defaultName ، دستوری را برای استفاده در CLI تعریف می کنیم. دستور دقیق مورد استفاده را تنظیم می کنیم و در حالت ایده آل، قسمت های مختلف مانند فضای نام فرمان را با کاراکتر (" : ") تقسیم می کنیم.
در این سناریو، فضای نام CLI ما spm است. ما همچنین دستور task را اضافه کرده و در نهایت، دستور ویژه یdeadline را اضافه می کنیم. بنابراین، دستور ما spm:task:deadline خواهد بود.
در متد configureتمام اطلاعات دیگر دستور مانند توضیحات و پیام راهنما را تنظیم می کنیم. برای این کار از متدهای setDescription و setHelp از کلاس Abstract استفاده خواهیم کرد. برای پیام در متد setHelp تگ را اضافه کرده ایم. این تگ متن را با رنگ دیگری در ترمینال چاپ می کند. در چه تگ های خروجی کنسول Symfony می توانیم استفاده کنیم؟ در بخش دیگری، لیستی از برچسب هایی که می توانید استفاده کنید را ارائه می دهیم.
در نهایت در متدdoExecute کدی را اضافه می کنیم که خروجی دستور را ایجاد می کند. برای ارائه ی استایل و استفاده از مزایای کنسول Symfony از کلاس SymfonyStyle به کار گرفته میشود. این کلاس با توجه به پیشنهاد ما، از یک ظاهر طراحی شده برای خروجی ما مراقبت می کند.
بنابراین، عنوان را با استفاده از متدtitle تعریف می کنیم و بلافاصله پس از آن، مهلت هایی را که می خواهیم با متد getDeadlines داخلی خود نشان دهیم، دریافت می کنیم. این روش آرایه ای را با مهلت های پیش رو برای هفت روز آینده بر می گرداند. اگر ضرب الاجلی پیدا نشد، یک آرایه خالی بر می گرداند.
در این مورد، با استفاده از متد note از کلاس SymfonyStyle یک پیام آموزنده نشان خواهیم داد. در غیر این صورت، با استفاده از متدtable جدولی ایجاد می کنیم که تمام وظایف را با مهلت های پیش رو نشان می دهد.
ما برنامه کنسول خود را با برگرداندن ثابت SUCCESS از کلاس Console در Symfony پایان خواهیم داد.
این اولین برنامه CLI جوملا ماست. نصب و فعال کردن این پلاگین در جوملا، برنامه spm:task:deadline را به CLI اضافه می کند. با این حال، ما می توانیم این دستور را بهبود ببخشیم، بنابراین بیایید کمی عمیق تر بررسی کنیم و ببینیم چگونه می توانیم یک CLI کاربردی و آموزنده تر ایجاد کنیم.
در بخش بعدی، به روش های خروجی SymfonyStyle برای ارائه بهتر استایل برای پیام های خود خواهیم پرداخت.
بررسی روش های SymfonyStyle
برای اکثر دستورات، خروجی اولیه، اطلاعات کافی را ارائه می دهد. به عنوان مثال، وقتی می خواهیم بگوییم که هیچ مهلتی وجود ندارد، یک پیام کوتاه ساده کافی است. با این حال، چه اتفاقی می افتد زمانی که ما نیاز به تعیین ضرب الاجل در چندین کار داریم؟ ما به نوعی استایل نیاز داریم تا خواندن اطلاعات برای کاربرانمان، آسان تر شود.
برای ارائه خروجی خوب می توانیم از روش های زیر استفاده کنیم:
- title($title) این به تعریف عنوان کمک می کند. قرار است فقط یک بار از آن برای تنظیم عنوان اصلی خروجی خود استفاده کنید.
- section($title) این متن را به عنوان تیتر یک بخش جدید قالب بندی می کند.
- text($message) این روش برای نمایش پیام ها یا دستورالعمل های معمولی مانند متن استفاده می شود.
- listing($list) این روش آرایه ای از رشته ها را می پذیرد و هر عنصر آرایه را در یک لیست نامرتب نمایش می دهد.
- table($header, $body) این روش یک جدول را نمایش می دهد. دو آرایه را به عنوان آرگومان می پذیرد. اولی هدر جدول است و آرایه دوم به عنوان بدنه جدول استفاده می شود.
- horizontalTable($header, $body) این روش یک جدول افقی را نمایش می دهد و همان آرگومان های قبلی (هدر و بدنه) را می پذیرد.
- definitionList([$term => $definition]) این آرایه شاخص شده را می پذیرد و محتوای آن را به عنوان فهرست تعریف نشان می دهد، که در آن کلیدهای آرایه به عنوان عبارت تعریف و مقادیر به عنوان متن تعریف استفاده می شوند.
- newLine($lines) این متد یک خط جدید به متن اضافه می کند. یک آرگومان عدد صحیح را می پذیرد که نشان دهنده ی تعداد خطوط خالی است که می خواهید اضافه کنید.
- note($message) این نشان می دهد که متن ارائه شده برجسته شده است تا اطلاعات مهمی را نشان دهد.
- caution($message) این متد شبیه متد note است اما پیام را به صورت برجسته تر نمایش می دهد.
از چه تگ های خروجی کنسول Symfony می توانیم استفاده کنیم؟
با برنامه های CLI، ما نمی توانیم از همان استایلی که در وب سایت خود داریم، استفاده کنیم. با این حال، برخی از برچسب ها وجود دارد که می توانیم از آنها برای استایل دادن به خروجی خود استفاده کنید:
- info این متن محصور شده را به رنگ سبز چاپ می کند.
- comment این متن محصور شده را به رنگ زرد چاپ می کند.
- question این متن محصور شده را با پس زمینه آبی چاپ می کند.
- error این متن محصور شده را با پس زمینه قرمز چاپ می کند.
- bg=COLOR این تگ رنگ پس زمینه متن محصور شده را تعیین می کند. COLOR ممکن است هر مقدار رنگ هگزا دسیمال (مثلاً #00FF00 برای سبز) یا نام مرسوم آن در انگلیسی باشد. زمانی که ترمینال آن کد رنگی را پشتیبانی نکند، نزدیک ترین رنگ را نشان می دهد. باید از همان تگ / bg=COLOR استفاده کنیم، تا تگ را ببندیم.
- fg= این تگ رنگ پیش زمینه متن محصور شده را تعیین می کند. همان محدودیت هایی که برای bg= اعمال می شود.
مانند HTML، ما نیز باید این تگ ها را با استفاده از همان نحو ببندیم.
ما همچنین چند کد کوتاه در دسترس داریم تا نگهداری پیام هایمان را آسان تر کنید:
- %command.name% نام دستور را بر می گرداند.
- %command.full_name% این مسیر اسکریپت را پس از نام دستور بر می گرداند. در جوملا، زمانی که از جوملا اصلی اجرا می شود پوشه، مسیر اسکریپت همیشه cli/joomla.php است.
با استفاده از این برچسب ها، پیام های ما زیباتر به نظر می رسند. گام دیگر برای بهتر کردن آنها، افزودن قابلیت نمایش پیام ها به زبان کاربر است. بیایید در بخش بعدی ببینیم چگونه می توانیم پیام ها را به زبان های مختلف ترجمه کنیم.
نحوه بین المللی کردن پیام های CLI
در نهایت، می توانیم از سیستم زبان جوملا برای ترجمه پیام های CLI خود استفاده کنیم. حتی می توانیم از تگ های Symfony که در بخش قبلی یاد گرفتیم، در رشته های زبان خود استفاده کنیم.
حتی زمانی که فقط از یک زبان در برنامه CLI خود استفاده می کنیم، استفاده از سیستم ترجمه، کد ما را بهبود می بخشد و آن را ساده تر می کند. به عنوان مثال، فراخوانیsetHelp را در فایل SpmTaskDeadlineCommand.php در نظر بگیرید. در آن فایل این کد را اضافه کردیم:
$this->setHelp('The <info>$command.name%</info> command
lists all the tasks with upcoming deadlines. <info>php
%command.full_name%</info>');
با استفاده از سیستم ترجمه جوملا، می توانیم آن را با موارد زیر جایگزین کنیم:
$this->setHelp(Text::_('PLG_CONSOLE_SPM_
TASK_DEADLINE_HELP'));
این باعث می شود کد ما برای خواندن ساده تر شود.
برای اینکه برنامه CLI ما قابل ترجمه باشد، باید تغییراتی در کد فعلی خود ایجاد کنیم. اول از همه، ویژگی محافظت شده $autoloadLanguage را در کلاس SpmConsolePlugin روی true قرار می دهیم. ما باید این کار را انجام دهیم زیرا جوملا هیچ فایل زبانی را برای این پلاگین بارگذاری نمی کند، به خصوص که ما در یک محیط وب نیستیم. بنابراین، ما فایل src/plugins/console/spm/src/Extension/SpmConsolePlugin.php را ویرایش می کنیم و ویژگی بالای متد اول خود را اضافه می کنیم:
<?php
...
class SpmConsolePlugin extends CMSPlugin implements
SubscriberInterface
{
protected $autoloadLanguage = true;
public static function getSubscribedEvents(): array
...
}
اکنون، ما فایل های زبان خود را ایجاد میکنیم، بنابراین فایل های زیر را اضافه می کنیم:
src/plugins/console/spm/language/en-GB/plg_console_spm.sys.ini
PLG_CONSOLE_SPM="SPM CLI"
PLG_CONSOLE_SPM_XML_DESCRIPTION="Simple Project Manager Command Line Interface Commands"
فایل.sys.ini شامل فقط رشته هایی است که برای مدیریت جوملا نیاز داریم.
همچنین، ما فایلsrc/plugins/console/spm/language/en-GB/plg_console_spm.ini را ایجاد خواهیم کرد:
PLG_CONSOLE_SPM_TASK_DEADLINE_DESCRIPTION="List upcoming deadlines"
PLG_CONSOLE_SPM_TASK_DEADLINE_HELP="The <info> %command.name%</info> command lists all the tasks with
<bg=#00FF00>upcoming deadlines</bg=#00FF00>. <info>php
%command.full_name%</info>"
PLG_CONSOLE_SPM_TASK_DEADLINE_DEADLINE_HEADER="Deadline"
PLG_CONSOLE_SPM_TASK_DEADLINE_NO_DEADLINE="There is no upcoming deadlines"
PLG_CONSOLE_SPM_TASK_DEADLINE_TITLE="Simple Project Manager Deadlines"
این فایل شامل تمام رشته های مربوط به دستور می باشد. همانطور که می بینید، ما می توانیم تگ های استایل را بدون هیچ مشکلی در رشته ها قرار دهیم.
هنگامی که کلید و رشته های ترجمه شده خود را داشته باشیم، تمام رشته های کلاس SpmTaskDeadlineCommand خود را با متد Text::_() جایگزین می کنیم و در نهایت با این کد مواجه می شویم:
<?php
namespace Piedpiper\Plugin\Console\Spm\CliCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Joomla\Console\Command\AbstractCommand;
use Joomla\CMS\Language\Text;
class SpmTaskDeadlineCommand extends AbstractCommand
{
protected static $defaultName = 'spm:task:deadline';
protected function configure(): void
{
$this->setDescription(Text::_('PLG_CONSOLE
_SPM_TASK_DEADLINE_DESCRIPTION'));
$this->setHelp(Text::_('PLG_CONSOLE_SPM
_TASK_DEADLINE_HELP'));
}
protected function getDeadlines() : array
{
$deadlines = [];
$days = 7;
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select('*')
->from('#__spm_tasks');
$query->where('deadline BETWEEN NOW() AND
DATE_ADD(NOW(), INTERVAL ' . $days .' DAY)');
$query->setQuery($query);
$deadlines = $db->loadAssocList('id');
return $deadlines;
}
protected function doExecute(InputInterface $input,
OutputInterface $output): int
{
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->title(Text::_('PLG_CONSOLE_
SPM_TASK_DEADLINE_TITLE'));
$deadlines = $this->getDeadlines();
if (empty($deadlines)) {
$outputStyle->note(Text::_('PLG_CONSOLE_SPM_
TASK_DEADLINE_NO_DEADLINE'));
} else {
$outputStyle->table([Text::_('PLG_CONSOLE_
SPM_TASK_DEADLINE_DEADLINE_HEADER'),
'Project', 'Task'], $deadlines);
}
return Command::SUCCESS;
}
}
توجه داشته باشید که فضای نام Joomla\CMS\Language\Text را نیز برای استفاده از سیستم ترجمه به کلاس اضافه کرده ایم.
در نهایت، بخش مربوطه را به فایل مانیفست XML خود، درست در زیر بخش قبلی اضافه میکنیم:
...
</files>
<languages>
<language tag="en-GB">language/en-GB/
plg_console_spm.ini</language>
<language tag="en-GB">language/en-GB/
plg_console_spm.sys.ini</language>
</languages>
با این کار فایل های زبان در پوشه های مناسب در پکیج نصبی، نصب می شوند.
اکنون، برنامه CLI ما به زبان شما صحبت می کند و کد با پیام های راهنمایی شما مخلوط نمی شود. با این حال، آیا عالی نیست اگر بتوانیم آن را کمی جلوتر ببریم و گزینه های مختلفی را برای یک کاربر اضافه کنیم؟ در بخش بعدی، ما قصد داریم آرگومان هایی را اضافه کنیم تا یک برنامه ی CLI قدرتمندتر را امکان پذیر کنیم.
اضافه کردن پارامترها به دستور CLI
برنامه CLI ما برای مشاهده سریع ضرب الاجل های آینده در عرض یک هفته بسیار مفید است، اما در مورد ضرب الاجل های ماه آینده چطور؟ ما فقط می توانیم پارامتر زمان را در کوئری SQL خود تغییر دهیم، اما این چندان کاربردی نخواهد بود، بنابراین بیایید آرگومان هایی را به دستور CLI خود اضافه کنیم تا انعطاف پذیری بهتری داشته باشیم.
ما گزینه ای را به دستور خود اضافه می کنیم تا تعداد روزهایی را که می خواهیم برای مهلت در نظر بگیریم، سپری کنیم.
همانطور که در بخش گذشته ، معرفی گزینه های عمومی برای CLI جوملا دیدیم، قبل از نام گزینه دو خط تیره اضافه کردیم. ما گزینه روزهای days خود را فراخوانی می کنیم. بنابراین دستور ما به این صورت خواهد بود:
php joomla.cli spm:task:deadline --days 7
در اینجا، ما می توانیم 7 را با هر تعداد روز در هنگام اجرای دستور خود جایگزین کنیم.
جوملا چندین روش جالب را ارائه می دهد تا تعریف این گزینه های CLI را آسان تر کند. اجازه دهید ویرایش فایل src/plugins/console/spm/src/CliCommand/SpmTaskDeadlineCommand.php را شروع کنیم و متد configure خود را با این کد جایگزین کنیم:
protected function configure(): void
{
$this->setDescription(Text::_('PLG_CONSOLE
_SPM_TASK_DEADLINE_DESCRIPTION'));
$this->setHelp(Text::_('PLG_CONSOLE_SPM
_TASK_DEADLINE_HELP'));
$this->addOptions();
}
protected function addOptions()
{
$description = Text::_('PLG_CONSOLE_SPM_TASK
_DEADLINE_OPTION_DAYS_DESCRIPTION');
$this->addOption('days', 'd', InputOption::
VALUE_OPTIONAL, $description, 7);
return;
}
در این کد ما یک متد جدید addOptions را فراخوانی می کنیم تا گزینه های کلاس خود را اضافه کنیم. در داخل این متد، ابتدا توضیحات ترجمه شده ی خود را دریافت می کنیم. سپس از متد addOption از کلاس توسعه یافته AbstractCommand برای پیکربندی گزینه استفاده می کنیم. متد addOptionپنج آرگومان می گیرد:
- -days : این نام گزینه است.
- -d : این شکل مخفف گزینه است. باید مراقب باشید که با این دستور از یک مخفف برای دو گزینه مختلف استفاده نکنید.
- InputOption::VALUE_OPTIONAL : این یک ثابت است که در کلاس InputOption در Symfony تعریف شده است.
- $description: این پیام کمکی است که کاربر هنگام استفاده از گزینه -h می بیند.
- 7: آخرین آرگومان مقدار پیش فرض گزینه است.
ما باید موارد اضافی را در موردInputOption::VALUE_OPTIONAL روشن کنیم. اول از همه، برای استفاده از این ثابت، باید فضای نام مورد استفاده را اعلام کنیم. بنابراین، اعلان آن را درست بعد از بقیه فضاهای نام در بالای کلاس خود اضافه کنید:
use Symfony\Component\Console\Input\InputOption;
سپس می توانیم از ثابت های زیر استفاده کنیم:
- VALUE_NONEزمانی که گزینه هیچ مقداری را نمی پذیرد. هنگام استفاده از این، مقدار پیش فرض متد addOption بایدnull باشد.
- VALUE_REQUIREDزمانی که کاربر باید مقداری را برای گزینه تعیین کند.
- VALUE_OPTIONAL وقتی کاربر می تواند مقدار را حذف کند و از مقدار پیش فرضی که ما به عنوان آخرین آرگومان در متد addOptionارائه می کنیم، استفاده کند.
- VALUE_IS_ARRAYزمانی که کاربر می تواند مقادیر مختلفی را به گزینه اضافه کند.
به عنوان مثال، - days=7 –days=8*
- VALUE_NEGATABLEوقتی یک کاربر می تواند یک مقدار مثبت یا منفی داشته باشد.
به عنوان مثال، –ansi یا –no-ansi
پس از تعریف گزینه های ما، مرحله بعدی بازیابی و استفاده از آنها در متد doExecuteاست. بنابراین، بیایید آن متد را با کد زیر جایگزین کنیم:
protected function getOptions() : array
{
$options = [];
$options = $this->cliInput->getOptions();
return $options;
}
protected function doExecute(InputInterface $input,
OutputInterface $output): int
{
$this->cliInput = $input;
$outputStyle = new SymfonyStyle($input, $output);
$outputStyle->title(Text::_('PLG_CONSOLE_SPM_TASK
_DEADLINE_TITLE'));
$options = $this->getOptions();
$deadlines = $this->getDeadlines($options);
$outputStyle->block('this is a block of text');
if (empty($deadlines)) {
$outputStyle->note(Text::_
('PLG_CONSOLE_SPM_TASK_DEADLINE_NO_DEADLINE'));
} else {
$outputStyle->table([Text::_('PLG_CONSOLE_SPM_
TASK_DEADLINE_DEADLINE_HEADER'), 'Project',
'Task'], $deadlines);
}
return Command::SUCCESS;
}
با این تغییر، گزینه ها را با استفاده از متد جدید getOptions بازیابی می کنیم. آن متد از کلاس InputInterface برای بازیابی تمام گزینه های ارسال شده از طریق خط فرمان یا مقادیر پیش فرض آنها در یک آرایه استفاده می کند. زمانی که آن آرایه را داشتیم، آن را به متد getDeadlines خود برای استفاده در کوئری ارسال می کنیم.
بنابراین، برای پیاده سازی گزینه تصویب شده، باید گزینه getDeadlines خود را تغییر دهیم تا متغیر $options را بپذیریم و از گزینه days مراقبت کنیم. استفاده از این کد باعث این کار می شود:
protected function getDeadlines($options) : array
{
$deadlines = [];
$days = (int)$options['days'];
if ($days <= 0) {
$days = 7;
}
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select('*')
->from('#__spm_tasks');
$query->where('deadline BETWEEN NOW() AND
DATE_ADD(NOW(), INTERVAL ' . $days . ' DAY)');
$query->setQuery($query);
$deadlines = $db->loadAssocList('id');
return $deadlines;
}
کلاس هایInputInterface ، نوع آرگومان های ارسال شده به CLI را کنترل نمی کنند، بنابراین ما گزینه را روی نوع int قرار می دهیم، برای اطمینان از اینکه با مقدار مثبتINT سروکار داریم. در غیر این صورت از7 روز پیش فرض استفاده می کنیم. در عبارت Where از اپراتور BETWEEN و از متد های NOW() و DATE_ADD(() برای تشکیل کوئری MySQL استفاده میکنیم.
در نهایت، باید آخرین ترجمه را در فایل src/plugins/console/spm/language/en-GB/plg_console_spm.ini قرار دهیم و این خط را به انتهای فایل اضافه کنیم:
PLG_CONSOLE_SPM_TASK_DEADLINE_OPTION_DAYS_DESCRIPTION="Number of days in the future to check the deadlines"
منابع فصل
- در مجله جوملا ، مقاله مفصلی در مورد نحوه استفاده از CLI جوملا وجود دارد، به نام جوملا 4: یک برنامه قدرتمند CLI
https://magazine.joomla.org/all-issues/june-2022/joomla-4-a-powerful-cli-application
- کامپوننت Symfony Console مستندات عالی دارد:
https://symfony.com/doc/current/components/console.html
- نحوه استایل دادن به خروجی کنسول خود را با استفاده از خروجی Symfony در این مقاله مشاهده می کنید:
https://symfony.com/doc/current/console/coloring.html#using-color-styles
- می توانید درباره Cron Job در ویکی پدیا بیشتر بخوانید:
https://en.wikipedia.org/wiki/Cron