کاربر(User)

بررسی اجمالی

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

به طور کلی، کاربر نمایانگر هویت فردی است که می‌تواند به یک نمونه جوملا وارد شود، چه در بخش جلویی سایت (Front-end)، چه در بخش مدیریت (Back-end)، یا هر دو. اطلاعات مرتبط با کاربر شامل موارد زیر است:

- اطلاعات ایستا مانند نام کاربری، ایمیل، و همچنین تنظیمات کاربر مانند زبان، ویرایشگر مورد علاقه و غیره. 

- اطلاعات پویا مانند آخرین زمان ورود به سیستم (Last logon date/time). 

- داده‌های مربوط به دسترسی‌ها که مشخص می‌کند هر کاربر چه امتیازاتی دارد و اجازه انجام چه اقداماتی را در سیستم جوملا دارد.

User API جوملا به شما اجازه می‌دهد ویژگی‌های حساب کاربری را مشاهده، ویرایش، بررسی دسترسی‌ها، حذف کاربران و انجام وظایف مدیریت حساب کاربری مثل مسدود کردن حساب کاربری را انجام دهید.

تنظیم برخی از ویژگی‌های کاربر می‌تواند روی امکان ورود او اثر بگذارد، مثلاً مسدود کردن حساب یا تغییر رمز عبور. اما کد User API شامل اقدامات مکمل مانند ارسال ایمیل هشدار به کاربر نیست و باید این موارد را جداگانه مدیریت کنید.

عملیات پایه

برای دریافت شیء User کاربر فعلی که وارد شده است، می‌توانید از کد زیر استفاده کنید:

 
$user = \Joomla\CMS\Factory::getApplication()->getIdentity();

 

اگر کاربری وارد نشده باشد، این تابع یک شیء User "خالی" با مقدار `id = 0` برمی‌گرداند.

برای دریافت اطلاعات هر کاربر ثبت‌نام‌شده دیگری نیز می‌توانید از توابع کلاس `UserFactory` استفاده کنید که از طریق کانتینر تزریق وابستگی (Dependency Injection Container) در دسترس است:

 
// دریافت UserFactory
$userFactory = Factory::getContainer()->get(\Joomla\CMS\User\UserFactoryInterface::class);

// دریافت شیء User با شناسه ۹۹
$user = $userFactory->loadUserById(99); 

// دریافت شیء User با نام کاربری "joomuser" 
$user = $userFactory->loadUserByUsername("joomuser"); 
 

 تذکر برنامه‌نویسی: 

برای پایداری و قابلیت تست بهتر، می توانید به جای نمونه‌سازی مستقیم، از Factory موجود در کانتینر استفاده کنید.

نمونه‌سازی مستقیم

یک روش رایج دیگر برای گرفتن شیء User در کد جوملا، نمونه‌سازی مستقیم با ارسال شناسه کاربر است:

 
$id = 99;
$user = new \Joomla\CMS\User\User($id);

 

اما این روش باعث دشواری در تست واحد (unit testing) می‌شود چون کلاس‌ها به صورت مستقیم نمونه‌سازی شده‌اند، نه از طریق روش‌های Factory و کانتینر تزریق وابستگی.

نمایش اطلاعات کاربر

پس از داشتن شیء User می‌توانید اطلاعات کاربر را نمایش دهید. برای مثال:

 
echo "<p>نام کاربر: {$user->name},ایمیل: {$user->email},نام کاربری: {$user->username}</p>";

 

خصوصیات شیء User

جوملا برخی از داده‌های مرتبط با کاربر را در فیلدهای ثابت جدول `#__users` ذخیره می‌کند و داده‌های دیگر را در فیلد `params` که به صورت رشته JSON در همان جدول قرار دارد، نگهداری می‌کند. این موضوع در دسترسی به داده‌های شیء User نیز مشاهده می‌شود؛ برخی داده‌ها به‌صورت مستقیم به عنوان خصوصیات شیء قابل دسترسی هستند و برخی دیگر باید از طریق خصوصیت `params` دریافت شوند.

با توجه به عملکرد مدیریت کاربران بخش مدیرت (admin Users)، معمولاً داده‌های ذخیره‌شده در فیلدهای ثابت در تب اول فرم مدیریت/ویرایش کاربران قرار دارند (که در حال حاضر با عنوان «اطلاعات حساب» یا "Account Details" شناخته می‌شود)، و ویژگی‌هایی که در `params` ذخیره شده‌اند، در یک تب فرعی (معمولاً با عنوان «تنظیمات پایه» یا "Basic Settings") قابل مشاهده‌اند.

ویژگی‌های زیر به صورت خودکار هنگام فراخوانی `getIdentity()` ایجاد می‌شوند، به ترتیبی که در مستندات API آمده است:

- id: شناسه یکتای عددی کاربر (این شناسه در جداول دیگر جوملا به عنوان کلید خارجی برای مرتبط کردن رکوردها استفاده می‌شود).

- name: نام کامل کاربر. (مثلاً Vint Cerf)

- username: نام کاربری یا شناسه ورود کاربر. (مثلاً shmuffin1979)

- email: آدرس ایمیل کاربر. (مثلاً این آدرس ایمیل توسط spambots حفاظت می شود. برای دیدن شما نیاز به جاوا اسکریپت دارید)

- password: رمز عبور رمزنگاری‌شده کاربر.

- password_clear: فقط هنگام تغییر رمز عبور مقداردهی می‌شود؛ در حالت عادی خالی است.

- block: اگر کاربر در جوملا مسدود شده باشد (یعنی امکان ورود ندارد) مقدارش برابر '1' است.

- sendEmail: نشان می‌دهد آیا این کاربر باید ایمیل‌های سیستمی دریافت کند یا نه.

- registerDate: تاریخ ثبت‌نام اولیه کاربر.

- lastvisitDate: تاریخ آخرین بازدید کاربر از سایت.

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

- params: رشته JSON حاوی جفت‌های نام/مقدار برای ویژگی‌های فرعی کاربر (که در ادامه توضیح داده شده‌اند).

- groups: آرایه انجمنی که شامل شناسه گروه‌ها به عنوان کلید و مقدار (رشته‌ای) برای گروه‌هایی است که این کاربر عضو آن‌ها است.

- guest: اگر کاربر وارد نشده باشد، این مقدار برابر '1' است و سایر متغیرهای کاربر معمولاً مقدار پیش‌فرض یا خالی دارند.

- lastResetTime: زمان آخرین بازنشانی رمز عبور.

- resetCount: تعداد دفعات بازنشانی رمز عبور.

- requireReset: نشان می‌دهد که آیا کاربر باید در دفعه بعد ورود، رمز عبور خود را تغییر دهد یا نه.

ویژگی‌هایی که در فیلد params ذخیره می‌شوند

این ویژگی‌ها از طریق متد `user->getParam()` قابل دسترسی هستند:

- admin_style: شناسه قالب (تمپلیت) بخش مدیریت.

- admin_language: کد زبان بخش مدیریت.

- language: کد زبان بخش جلویی سایت (Front-end).

- editor: ویرایشگر پیش‌فرض مورد علاقه کاربر.

- timezone: ناحیه زمانی انتخاب‌شده توسط کاربر (یکی از نواحی زمانی استاندارد PHP). همچنین با متد `$user->getTimezone()` نیز قابل دسترسی است.

مثال برای دریافت زبان پیش‌فرض بخش جلویی کاربر:

$user = \Joomla\CMS\Factory::getApplication()->getIdentity();
$language = $user->getParam('language', 'the default');
echo "<p>زبان بخش جلویی شما روی {$language} تنظیم شده است.</p>";
 

تشخیص وضعیت ورود کاربر

معمولاً شما تنها می‌خواهید مطمئن شوید که کاربر قبل از انجام ادامه کار وارد سیستم شده است یا خیر.

اگر کاربر فعلی وارد نشده باشد، خصوصیت `guest` مقدار '1' خواهد داشت و اگر کاربر احراز هویت شده باشد (`logged in`)، مقدار `guest` برابر با '0' تنظیم می‌شود.

مثال کد:

 
$user = \Joomla\CMS\Factory::getApplication()->getIdentity(); 
if ($user->guest) { 
	echo "برای مشاهده این محتوا باید وارد شوید."; 
} else { 
	echo "شما وارد شده‌اید، می‌توانید محتوا را مشاهده کنید."; 
}
 

 نکته:

اگر از متدهای `loadUserById` یا `loadUserByUsername` برای بارگذاری شیء User کاربر دیگری استفاده کرده‌اید، توجه کنید که مقدار `guest` نشان‌دهنده وضعیت ورود آن کاربر نیست (یعنی اینکه آیا آن کاربر در حال حاضر یک نشست فعال دارد یا خیر). مقدار `guest = 0` در این حالت صرفاً بیانگر این است که یک رکورد کاربر معتبر بارگذاری شده است.

امتیازات (Privileges)

همه کاربران دسترسی‌های برابر ندارند. مثلاً، یک کاربر با نقش «مدیر ارشد» (Super Administrator) ممکن است بتواند محتوای همه کاربران را ویرایش کند، در حالی که یک «ناشر» (Publisher) فقط اجازه ویرایش محتوای خود را دارد. همچنین برخی مقالات ممکن است محرمانه باشند و فقط کاربران دارای مجوز مشاهده آن‌ها، بتوانند دسترسی داشته باشند.

متدهای مربوط به امتیازات در User API

۱. authorize:

متد `authorize()` برای بررسی این استفاده می‌شود که آیا کاربر جاری اجازه انجام کاری خاص را دارد یا خیر. 

پارامتر اول، وظیفه یا عملی که می‌خواهید بررسی کنید را مشخص می‌کند، و پارامتر دوم، مؤلفه (کامپوننت) مورد نظر که حقوق دسترسی آن باید بررسی شود را بیان می‌کند.

مثال:

 
$user = \Joomla\CMS\Factory::getApplication()->getIdentity();

if ($user->authorise('core.edit', 'com_content')) {
    echo "<p>شما مجاز به ویرایش تمامی محتوا هستید.</p>";
} else {
    echo "<p>شما اجازه ویرایش کل محتوا را ندارید.</p>";
}
if ($user->authorise('core.edit.own', 'com_content')) {
    echo "<p>شما مجاز به ویرایش محتوای خود هستید.</p>";
} else {
    echo "<p>شما اجازه ویرایش محتوای خود را ندارید.</p>";
}
 

 

۲. getAuthorisedCategories :

متد `getAuthorisedCategories()` دو پارامتر می‌گیرد: نام کامپوننت و عملی که می‌خواهید بررسی کنید. این متد یک آرایه از شناسه‌های دسته‌بندی (Category ID) برمی‌گرداند که کاربر اجازه انجام آن عمل (مثلاً حذف) را بر روی آن‌ها دارد.

مثال:

$categoriesUserCanDelete = $user->getAuthorisedCategories('com_content', 'core.delete');

که آرایه‌ای از شناسه دسته‌بندی‌هایی است که کاربر می‌تواند در آن‌ها عملیات حذف انجام دهد.

۳. getAuthorisedGroups :

متد `getAuthorisedGroups()` آرایه‌ای از شناسه‌های گروه‌های کاربری (User Group IDs) را برمی‌گرداند که این کاربر عضو آن‌ها است. شناسه گروه‌ها در صفحه مدیریت کاربران / گروه‌ها در بخش مدیریت قابل مشاهده است.

۴. getAuthorisedViewLevels

متد `getAuthorisedViewLevels()` آرایه‌ای از شناسه‌های سطح دسترسی مشاهده (Viewing Access Level IDs) را برمی‌گرداند. این سطوح در صفحه مدیریت کاربران / سطوح دسترسی در بخش مدیریت قابل مشاهده هستند.

معمولاً کامپوننت ها برای محدود کردن مشاهده یک مورد، یک سطح دسترسی را به آن تخصیص می‌دهند و شناسه آن سطح دسترسی در فیلد `Access` جدول داده‌های آن آیتم ذخیره می‌شود. برای بررسی اینکه آیا کاربر اجازه مشاهده یک آیتم را دارد، مقدار فیلد `Access` با آرایه برگشتی از `getAuthorisedViewLevels()` مقایسه می‌شود.

مثال: فرض کنید می‌خواهید مقاله‌ای به نام "article50" فقط توسط کاربران سطح دسترسی "Special" (با شناسه ۳) دیده شود. در این صورت مقدار ۳ را در فیلد Access رکورد آن مقاله قرار می‌دهید و فقط کاربرانی که آرایه برگشتی از `getAuthorisedViewLevels()` آن‌ها شامل عدد ۳ باشد اجازه مشاهده خواهند داشت.

عملیات پایگاه داده

طرح کلی زیر نشان می‌دهد که چگونه می‌توانید با استفاده از User API داده‌های کاربر را به‌روزرسانی کنید. فلش‌های سیاه، جریان کنترل و فلش‌های سبز جهت جریان داده را نشان می‌دهند.

توجه داشته باشید که ویرایش داده‌های کاربر معمولاً در مؤلفه مدیریت کاربران جوملا (`com_users`) انجام می‌شود، جایی که بررسی‌های زیادی جهت اطمینان از انجام عملیات فقط توسط کاربران مجاز صورت می‌گیرد (برای مثال، کاربران عادی نمی‌توانند سطح دسترسی خود را بالاتر ببرند). اگر شما مستقیماً از User API استفاده کنید، بیشتر این اعتبارسنجی‌ها انجام نمی‌شود و احتمالاً باید اعتبارسنجی‌های اضافی را خودتان پیاده‌سازی کنید.

کلاس User از کلاس Table جوملا برای انجام عملیات CRUD در سطح پایگاه داده استفاده می‌کند. عملیاتی که رکورد کاربر را تغییر می‌دهند، باعث می‌شوند رویدادهای پلاگین کاربر فعال شوند.

User database operations

load()

برای بارگذاری ویژگی‌های یک رکورد کاربر (با شناسه $id) از پایگاه داده، از متد زیر استفاده کنید:

 
$user->load($id);

 

کد کلاس User داده‌ها را از پایگاه داده خوانده و در صورت معتبر بودن کاربر، این مقادیر را در ویژگی‌های کلاس ذخیره می‌کند، از جمله فیلد `params` که ویژگی‌های اضافی کاربر در آن ذخیره می‌شود. سپس می‌توانید به این خصوصیات به صورت مستقیم دسترسی داشته باشید، مانند:

 
echo $user->name;
 

 bind()

اگر یک آرایه انجمنی (associative array) از نام ویژگی‌ها به مقادیر آن‌ها دارید، مثلاً:

 
array('name' => 'Vint Cerf', 'username' => 'shmuffin1979')
 

 از متد `bind()` برای آپدیت مستقیم پراپرتی‌های شیء کاربر استفاده کنید:

 
$user->bind($data);
 

 این متد مقادیر آرایه را در ویژگی‌های محلی شیء قرار می‌دهد.

همچنین می‌توانید مستقیماً ویژگی‌ها را تنظیم کنید، مثلاً:

 
$user->name = 'Vint Cerf';
 

و یا با استفاده از متد `setParams()` فیلد `params` را تنظیم نمایید.

save()

برای ذخیره‌سازی تغییرات اعمال‌شده روی شیء کاربر و نوشتن آن‌ها به پایگاه داده، از متد زیر استفاده کنید:

 
$user->save();
 

 کد درون متد `save()` مقادیر ویژگی‌ها را در ساختار مربوط به جدول (table) کپی می‌کند و سپس متدهای `bind()` و `store()` از کلاس Table را برای نوشتن داده‌ها در پایگاه داده فراخوانی می‌کند.

درج رکوردها (Inserting Records)

می‌توانید مشابه روش‌های بالا از متدهای کلاس User برای درج رکوردهای جدید در پایگاه داده استفاده کنید؛ تنها تفاوت این است که ابتدا رکورد موجود را از پایگاه داده بارگذاری نمی‌کنید.

حذف رکوردها (Deleting Records)

برای حذف رکورد یک کاربر ابتدا باید آن را از پایگاه داده بارگذاری کنید و سپس متد `delete()` را فراخوانی نمایید. مثلاً:

 
$user = \Joomla\CMS\Factory::getContainer()
->get(\Joomla\CMS\User\UserFactoryInterface::class)
->loadUserById(99);
$user->delete();
 

رکوردهای مرتبط در جداول دیگر کاربری (مانند جدول `#__user_usergroup_map` که نگهدارنده نگاشت کاربران به گروه‌ها است و جدول `#__messages` که پیام‌های کاربر به کاربر را ذخیره می‌کند) نیز حذف می‌شوند. همچنین این عمل باعث فعال شدن رویدادهای `onUserBeforeDelete` و `onUserAfterDelete` می‌شود تا افزونه‌ها (plugins) نیز بتوانند داده‌های مرتبط با کاربر را حذف کنند.

با این حال، اگر کاربر مثلاً مقاله‌ای منتشر کرده یا به یک رکورد تماس (contact) مرتبط باشد، مراجع به شناسه کاربر در این رکوردها در پایگاه داده باقی خواهند ماند. 

کد نمونه ماژول

در زیر کد یک ماژول ساده جوملا آورده شده است که می‌توانید آن را نصب کرده و اجرا کنید تا استفاده از قابلیت‌های API کاربر جوملا را مشاهده کنید. همچنین می‌توانید کد را به صورت فایل فشرده mod_sample_user.zip دانلود کنید.

در پوشه mod_sample_user دو فایل زیر را ایجاد کنید:

فایل: mod_sample_user/mod_sample_user.xml

 
<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="4.4" client="site" method="upgrade">
    <name>User demo</name>
    <version>1.0.1</version>
    <description>Code demonstrating use of Joomla User class</description>
    <files>
        <filename module="mod_sample_user">mod_sample_user.php</filename>
    </files>
</extension>
 

فایل mod_sample_user/mod_sample_user.php

 
<?php
defined('_JEXEC') or die('Restricted Access');

use Joomla\CMS\Factory;
use Joomla\CMS\Language\LanguageHelper;
use Joomla\CMS\User\UserFactoryInterface;

$input = Factory::getApplication()->input;

// یافتن کاربر - یا با پارامتر username=xxx یا کاربر فعلی
if ($input->exists('username'))
{
    $username = $input->get('username', "", "STRING");
    echo "Getting details for {$username}<br>";
    $user = Factory::getContainer()->get(UserFactoryInterface::class)->loadUserByUsername($username);
}
else
{
    $user = Factory::getApplication()->getIdentity();
}
if ($user->id == 0)
{
    echo "لطفاً وارد شوید یا نام کاربری معتبر از طریق پارامتر URL وارد کنید";
    return;
}

// نمایش ایمیل کاربر و زبان رابط کاربری
$language = $user->getParam('language', 'the default');
echo "آدرس ایمیل {$user->name} برابر است با {$user->email}، زبان رابط کاربری {$language}<br>";

// تنظیم زبان جدید رابط کاربری اگر پارامتر userlanguage=xxx در URL باشد
// این تغییر در صورتی که بخواهید زبان یک سوپر یوزر را تغییر دهید و ورود به عنوان سوپر یوزر نشده باشید، با خطا مواجه می‌شود
if ($new_language = $input->get('userlanguage', "", "STRING"))
{
    if (array_key_exists($new_language, LanguageHelper::getContentLanguages()))
    {
        $user->setParam('language', $new_language);
        if ($user->save())
        {
            echo "زبان با موفقیت به {$new_language} تغییر کرد<br>";
        }
        else
        {
            echo "تغییر زبان به {$new_language} انجام نشد<br>{$user->getError()}<br>";
        }
    }
    else
    {
        echo "تغییر زبان به {$new_language} انجام نشد - این زبان وجود ندارد<br>";
    }
}

// اگر در صفحه یک مقاله هستیم، بررسی می‌کنیم که آیا کاربر اجازه ویرایش آن مقاله را دارد یا خیر
$option = $input->get('option', "", "cmd");
$view = $input->get('view', "", "string");
$id = $input->get('id', 0, "int");

if ($option == "com_content" && $view == "article")
{
    if ($user->authorise('core.edit', "com_content.article.{$id}"))
    {
        echo "{$user->name} ممکن است این مقاله را ویرایش کند<br>";
    }
    else
    {
        echo "{$user->name} اجازه ویرایش این مقاله را ندارد<br>";
    }
}
 

 پوشه mod_sample_user را به صورت فایل فشرده mod_sample_user.zip بسته‌بندی کنید.

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

برای نمایش دادن این ماژول باید آن را فعال کنید:

- وارد صفحه ماژول‌ها (Content / Site Modules) شده و ماژول را ویرایش کنید.

- وضعیت آن را روی «منتشر شده» قرار دهید.

- جایگاه نمایش ماژول را انتخاب کنید.

- در تب تخصیص منو تعیین کنید که ماژول در کدام صفحات نمایش داده شود.

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

- شی کاربر را می‌گیرد و نام، ایمیل و زبان مورد علاقه رابط کاربری او را نمایش می‌دهد. کاربر یا با ورود به سایت انتخاب می‌شود یا از طریق پارامتر URL با username=XXX (که XXX نام کاربری معتبر است).

- اگر پارامتر userlanguage=es-ES (مثلاً زبان اسپانیایی) را به URL اضافه کنید، زبان رابط کاربری کاربر را تغییر می‌دهد (اگر زبان در سایت نصب شده باشد).

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

می‌توانید کد ماژول را به آسانی تغییر دهید و با سایر فراخوانی‌های API جوملا نیز آزمایش کنید.