سرویس‌های وب

توضیح مفهوم سرویس‌های وب

- سرویس‌های وب برای برقراری ارتباط بین سیستمها از طریق پروتکل HTTP و امروزه با امنیت بیشتر روی TLS (Transport Layer Security) استفاده می‌شوند. 

- تعریف دیگری از سرویس‌های وب این است که مثل یک قرارداد (Contract) بین تولیدکننده (Producer) و مصرف‌کننده (Consumer) از طریق نقاط انتهایی (Endpoints) عمل می‌کنند. 

- به طور ساده، سرویس‌های وب مانند درها و پنجره‌های یک خانه هستند؛ آن‌ها ورودی‌ها و خروجی‌هایی به جهان بیرون محسوب می‌شوند. 

- در زمینه جوملا به عنوان یک سیستم، API سرویس‌های وب جوملا امکان تعامل جوملا با منابع داده خارجی را فراهم می‌کند، مثل برنامه‌های وب، موبایل و... 

 ارتباط با API سرویس‌های وب جوملا نسخه 4.x

ارتباط با API سرویس‌های وب جوملا از طریق نقاط انتهایی مشخص شده انجام می‌شود:

- نقاط انتهایی اصلی جوملا: 

  https://docs.joomla.org/J4.x:Joomla_Core_APIs 

- مجموعه‌ای از نقاط انتهایی جوملا برای استفاده در Postman: 

  https://github.com/alexandreelise/j4x-api-collection

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

اغلب وقتی از فریم‌ورک جوملا استفاده می‌کنید، در پس‌زمینه هنوز از cURL یا php streams استفاده می‌شود. اکثر هاست‌ها، cURL را پشتیبانی می‌کنند. در غیر این صورت می‌توانید با استفاده از تابع `phpinfo()` این موضوع را بررسی کنید. مواردی که با فریم‌ورک جوملا گفته می‌شود بیشتر شبیه نمونه‌های cURL است و به راحتی می‌توانید دنبال کنید.

تعریف متغیرها

ابتدا برخی متغیرها را که در تمام درخواست‌های cURL استفاده می‌کنیم، تعریف می‌کنیم:

- آدرس وب‌سایت جوملا نسخه 4.x شما 

- توکن API جوملا که باید متعلق به حساب کاربری با دسترسی‌های Super User یا حداقل `core.login.api` و `core.login.site` باشد تا بتوان توکن کاربر فعلی وارد شده را دید و تغییر داد.

 
// قبل از ارسال METHOD به CURL
use Joomla\Http\HttpFactory;
use Joomla\Uri\Uri;
$http = (new HttpFactory())->getAvailableDriver();
$url   = 'https://example.org/api/index.php/v1';
$uri  = new Uri($url);
// توکن API جوملا را در جای امنی نگه‌دارید، مثل یک مدیر رمزعبور یا محفظه‌ای برای ذخیره اسرار
// بهتر است از متغیرهای محیطی برای نگهداری اسرار استفاده نکنید.
// دلیلش را می‌توانید در اینجا بخوانید: https://www.trendmicro.com/en_us/research/22/h/analyzing-hidden-danger-of-environment-variables-for-keeping-secrets.html
$token = '';

 

ایجاد مقاله در دسته "دسته‌بندی نشده" (Category ID = 2)

 
$categoryId = 2; // دسته‌بندی پیش‌فرض جوملا: "دسته‌بندی نشده"
$data = [
    'title'       => 'چگونه یک مقاله را از طریق API به جوملا اضافه کنیم؟',
    'alias'       => 'how-to-add-article-via-joomla-api',
    'articletext' => 'نمی‌دانم چطور...',
    'catid'       => $categoryId,
    'language'    => '*',
    'metadesc'    => '',
    'metakey'     => '',
];
$dataString = json_encode($data);
// هدرهای درخواست HTTP
$headers = [
    'Accept: application/vnd.api+json',
    'Content-Type: application/json',
    'Content-Length: ' . mb_strlen($dataString),
    sprintf('X-Joomla-Token: %s', trim($token)),
];
// زمان انتظار (timeout) به ثانیه
$timeout = 30;
// مسیر ایجاد مقاله را تنظیم می‌کند (قسمت path آدرس URI)
$uri->setPath('content/articles');
// درخواست ارسال می‌شود (پاسخ به صورت PSR-7)
$response = $http->request('POST', $uri, $dataString, $headers, $timeout);
// بدنه پاسخ یک stream است، بنابراین باید آن را echo کنیم
echo $response->body;

 

بازیابی همه مقاله‌ها از دسته "دسته‌بندی نشده"

 
$categoryId = 2; // دسته‌بندی پیش‌فرض جوملا: "دسته‌بندی نشده"
// بدنه درخواست ارسال نمی‌شود
$dataString = null;
// هدرهای درخواست HTTP
$headers = [
    'Accept: application/vnd.api+json',
    'Content-Type: application/json',
    sprintf('X-Joomla-Token: %s', trim($token)),
];
// زمان انتظار
$timeout = 30;
// مسیر دریافت همه مقاله‌ها را تنظیم می‌کند
$uri->setPath('content/articles');
// درخواست GET ارسال می‌شود
$response = $http->request('GET', $uri, $dataString, $headers, $timeout);
// نمایش محتوای پاسخ
echo $response->body;

 

بازیابی یک مقاله مشخص

 
$articleId = 1; // شناسه مقاله مشخص
$dataString = null;
$headers = [
    'Accept: application/vnd.api+json',
    'Content-Type: application/json',
    sprintf('X-Joomla-Token: %s', trim($token)),
];
$timeout = 30;
// مسیر دریافت مقاله مشخص را تنظیم می‌کند
$uri->setPath(sprintf('content/articles/%d', $articleId));
$response = $http->request('GET', $uri, $dataString, $headers, $timeout);
echo $response->body;

 

ویرایش یک مقاله مشخص (PATCH)

 
$articleId = 1;
$data = [
    'id'          => $articleId,
    'title'       => 'چگونه یک مقاله را از طریق API جوملا 4 ویرایش کنیم؟',
    'introtext'   => 'زمان استفاده از PATCH، articletext باید به دو بخش تقسیم شود یا حداقل فقط introtext استفاده شود تا به درستی کار کند',
    'fulltext'    => 'اگر بخواهید محتوای بیشتر',
];
$dataString = json_encode($data);
$headers = [
    'Accept: application/vnd.api+json',
    'Content-Type: application/json',
    'Content-Length: ' . mb_strlen($dataString),
    sprintf('X-Joomla-Token: %s', trim($token)),
];
$timeout = 30;
$uri->setPath(sprintf('content/articles/%d', $articleId));
$response = $http->request('PATCH', $uri, $dataString, $headers, $timeout);
// نمایش کد وضعیت پاسخ
echo $response->code;
 

 

حذف یک مقاله مشخص

 
$articleId = 1;
$dataString = null;
$headers = [
    'Accept: application/vnd.api+json',
    'Content-Type: application/json',
    sprintf('X-Joomla-Token: %s', trim($token)),
];
$timeout = 30;
$uri->setPath(sprintf('content/articles/%d', $articleId));
$response = $http->request('DELETE', $uri, $dataString, $headers, $timeout);
echo $response->code;

 

در ادامه ترجمه بخش «استفاده از توابع cURL در PHP» جهت کار با API جوملا آمده است:

استفاده از توابع cURL در PHP

توابع cURL باید در تنظیمات PHP فعال باشند، برای اطمینان `phpinfo();` را چک کنید.

تعریف تعدادی متغیر

ابتدا متغیرهایی که در همه درخواست‌های cURL استفاده می‌کنیم را تعریف می‌کنیم:

- آدرس وب‌سایت جوملا نسخه ۴ 

- توکن API جوملا مربوط به حساب Super User یا حسابی که حداقل دسترسی‌های `core.login.api` و `core.login.site` را دارد تا بتوان توکن کاربر فعلی را دید و تغییر داد.

 
// قبل از تعیین METHOD برای cURL مقداردهی می‌کنیم
$curl  = curl_init();
$url = 'https://example.org/api/index.php/v1';
// توکن API جوملا را در مکانی امن نگه دارید، مثلاً یک مدیر رمزعبور یا صندوق اسرار  
// بهتر است از متغیرهای محیطی برای نگهداری اسرار استفاده نشود.
// دلیلش را اینجا بخوانید: https://www.trendmicro.com/en_us/research/22/h/analyzing-hidden-danger-of-environment-variables-for-keeping-secrets.html
$token = '';
 

 

ایجاد مقاله در دسته "دسته‌بندی نشده" (Category ID = 2)

 
$categoryId = 2; // دسته‌بندی پیش‌فرض جوملا: "دسته‌بندی نشده"
$data = [
    'title'       => 'چگونه یک مقاله را از طریق API به جوملا اضافه کنیم؟',
    'alias'       => 'how-to-add-article-via-joomla-api',
    'articletext' => 'نمیدانم چطور...',
    'catid'       => $categoryId,
    'language'    => '*',
    'metadesc'    => '',
    'metakey'     => '',
];
$dataString = json_encode($data);
$headers = [
    'Accept: application/vnd.api+json',
    'Content-Type: application/json',
    'Content-Length: ' . mb_strlen($dataString),
    sprintf('X-Joomla-Token: %s', trim($token)),
];
curl_setopt_array($curl, [
    CURLOPT_URL            => sprintf('%s/%s', $url, 'content/articles'),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING       => 'utf-8',
    CURLOPT_MAXREDIRS      => 10,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,
    CURLOPT_CUSTOMREQUEST  => 'POST',
    CURLOPT_POSTFIELDS     => $dataString,
    CURLOPT_HTTPHEADER     => $headers,
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;

 

بازیابی همه مقاله‌ها از دسته "دسته‌بندی نشده"

 
$categoryId = 2; // دسته‌بندی پیش‌فرض جوملا: "دسته‌بندی نشده"
$headers = [
    'Accept: application/vnd.api+json',
    'Content-Type: application/json',
    sprintf('X-Joomla-Token: %s', trim($token)),
];
curl_setopt_array($curl, [
    CURLOPT_URL            => sprintf('%s/content/articles?filter[category]=%d', $url, $categoryId),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING       => 'utf-8',
    CURLOPT_MAXREDIRS      => 10,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,
    CURLOPT_CUSTOMREQUEST  => 'GET',
    CURLOPT_HTTPHEADER     => $headers,
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;

 

بازیابی یک مقاله مشخص

 
$articleId = 1; // شناسه مقاله مورد نظر
$headers = [
    'Accept: application/vnd.api+json',
    'Content-Type: application/json',
    sprintf('X-Joomla-Token: %s', trim($token)),
];
curl_setopt_array($curl, [
    CURLOPT_URL            => sprintf('%s/content/articles/%d', $url, $articleId),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING       => 'utf-8',
    CURLOPT_MAXREDIRS      => 10,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,
    CURLOPT_CUSTOMREQUEST  => 'GET',
    CURLOPT_HTTPHEADER     => $headers,
]);

$response = curl_exec($curl);
curl_close($curl);
echo $response;

 

ویرایش یک مقاله مشخص (PATCH)

 
$articleId = 1; // شناسه مقاله مورد نظر
$data = [
    'id'        => $articleId,
    'title'     => 'چگونه یک مقاله را از طریق API جوملا 4 ویرایش کنیم؟',
    'introtext' => 'زمان استفاده از PATCH، articletext باید به دو بخش تقسیم شود یا حداقل فقط introtext استفاده شود تا به درستی کار کند',
    'fulltext'  => 'اگر بخواهید محتوای بیشتری اضافه کنید',
];
$dataString = json_encode($data);
$headers = [
    'Accept: application/vnd.api+json',
    'Content-Type: application/json',
    'Content-Length: ' . mb_strlen($dataString),
    sprintf('X-Joomla-Token: %s', trim($token)),
];
curl_setopt_array($curl, [
    CURLOPT_URL            => sprintf('%s/content/articles/%d', $url, $articleId),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING       => 'utf-8',
    CURLOPT_MAXREDIRS      => 10,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_POSTFIELDS     => $dataString,
    CURLOPT_HTTPHEADER     => $headers,
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;

 

حذف یک مقاله مشخص (DELETE)

 
$articleId = 1; // شناسه مقاله مورد نظر
$headers = [
    'Accept: application/vnd.api+json',
    'Content-Type: application/json',
    sprintf('X-Joomla-Token: %s', trim($token)),
];
curl_setopt_array($curl, [
    CURLOPT_URL            => sprintf('%s/content/articles/%d', $url, $articleId),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING       => 'utf-8',
    CURLOPT_MAXREDIRS      => 10,
    CURLOPT_TIMEOUT        => 30,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => $headers,
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;