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

در این مقاله اول ساختار را روشن می‌کنیم، بعد با کد کوتاهی یک نقش «عضو» و قفل محتوا می‌سازیم و در آخر می‌گوییم چه زمانی سراغ افزونه بروید.

اجزای یک سایت عضویت#

یک سایت عضویت چند تکه دارد و بهتر است قبل از نصب هر ابزاری آن‌ها را روی کاغذ بیاورید:

  • ثبت‌نام و ورود: کاربر چطور حساب بسازد و وارد شود؟ با فرم پیش‌فرض یا صفحه‌ی اختصاصی؟
  • نقش‌ها: چه سطح‌هایی دارید؟ مثلاً مهمان، عضو رایگان و عضو ویژه.
  • محتوای قفل‌شده: کدام صفحه، نوشته یا بخش از صفحه محدود است؟
  • تعیین نقش: عضو بعد از چه چیزی به نقش «ویژه» می‌رسد؟ پرداخت، تأیید دستی یا کد دعوت؟
  • پنل کاربر: کاربر کجا اطلاعات و اشتراکش را می‌بیند؟

اگر هنوز پایه‌ی سایت را نساخته‌اید، تنظیمات اولیه بعد از نصب را مرور کنید؛ بخشی از آن همین «هر کس می‌تواند ثبت‌نام کند» و نقش پیش‌فرض کاربر جدید است.

نقش و قابلیت در وردپرس#

هر کاربر یک نقش دارد و هر نقش مجموعه‌ای از قابلیت‌هاست. وردپرس نقش‌های پیش‌فرض دارد (مشترک، نویسنده، ویرایشگر، مدیر و…). نقش «مشترک» فقط پروفایل خودش را ویرایش می‌کند و برای سایت عضویت پایه‌ی خوبی است، ولی بهتر است نقش جداگانه بسازید تا بعداً بتوانید دسترسی‌ها را دقیق تنظیم کنید.

نکته‌ی مهم: هنگام بررسی دسترسی، قابلیت را بسنجید. اگر کد شما current_user_can( 'access_member_content' ) را بپرسد، می‌توانید بعداً این قابلیت را به نقش‌های دیگر هم بدهید بدون این‌که کد را عوض کنید.

ساختن نقش عضو و قابلیت اختصاصی#

این کد را در یک افزونه‌ی کوچک بگذارید (نه در functions.php قالب، چون با عوض شدن قالب از بین می‌رود). نقش فقط در فعال‌سازی افزونه ساخته می‌شود، نه در هر بار بارگذاری.

PHP
<?php
/**
 * Plugin Name: Member Basics
 * Description: نقش عضو و قفل محتوا.
 * Version: 1.0.0
 */

defined( 'ABSPATH' ) || exit;

register_activation_hook( __FILE__, function () {
	add_role(
		'site_member',
		__( 'عضو ویژه', 'member-basics' ),
		array(
			'read'                  => true,
			'access_member_content' => true,
		)
	);

	// مدیر هم همیشه دسترسی داشته باشد.
	$admin = get_role( 'administrator' );
	if ( $admin ) {
		$admin->add_cap( 'access_member_content' );
	}
} );

register_deactivation_hook( __FILE__, function () {
	remove_role( 'site_member' );
} );

حذف نقش در غیرفعال‌سازی را با دقت بپذیرید: کاربرانی که این نقش را دارند ممکن است بدون نقش بمانند. اگر نمی‌خواهید این اتفاق بیفتد، remove_role را فقط هنگام حذف کامل افزونه (فایل uninstall.php) اجرا کنید.

قفل کردن بخشی از محتوا با شورت‌کد#

ساده‌ترین قفل، شورت‌کدی است که فقط برای عضو محتوا را نشان می‌دهد و به بقیه پیام و پیوند ورود می‌دهد:

PHP
add_shortcode( 'member_only', function ( $atts, $content = '' ) {
	if ( current_user_can( 'access_member_content' ) ) {
		return do_shortcode( $content );
	}

	$login_url = wp_login_url( get_permalink() );

	return sprintf(
		'<p class="member-locked">%s <a href="%s">%s</a></p>',
		esc_html__( 'این بخش ویژه‌ی اعضاست.', 'member-basics' ),
		esc_url( $login_url ),
		esc_html__( 'ورود به حساب', 'member-basics' )
	);
} );

در ویرایشگر می‌نویسید: [member_only]متن ویژه[/member_only]. چون بررسی در سمت سرور انجام می‌شود، متن قفل‌شده اصلاً در خروجی HTML برای مهمان نمی‌آید؛ برخلاف روش‌هایی که فقط با CSS یا جاوااسکریپت پنهانش می‌کنند.

قفل کردن کل صفحه یا دسته#

برای محافظت از کل یک نوشته، صفحه یا دسته، از template_redirect استفاده کنید. این مثال، نوشته‌های دسته‌ی «ویژه» را برای غیرعضو به صفحه‌ی ورود می‌فرستد:

PHP
add_action( 'template_redirect', function () {
	if ( ! is_singular( 'post' ) || ! has_category( 'vije' ) ) {
		return;
	}

	if ( current_user_can( 'access_member_content' ) ) {
		return;
	}

	wp_safe_redirect( wp_login_url( get_permalink() ) );
	exit;
} );

نامک دسته (vije) را با دسته‌ی خودتان عوض کنید. اگر محتوای ویژه در پست‌تایپ سفارشی است (مثلاً «درس»)، مقاله‌ی پست‌تایپ سفارشی نشان می‌دهد چطور آن را بسازید و شرط بالا را با is_singular('lesson') عوض کنید.

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

ثبت‌نام و تعیین نقش#

سه الگوی رایج برای ارتقای نقش هست:

  1. تأیید دستی: کاربر ثبت‌نام می‌کند و مدیر نقش «عضو ویژه» را از صفحه‌ی کاربران می‌دهد. برای اجتماع کوچک عالی است.
  2. بعد از پرداخت: با ووکامرس یا ابزار دیگر، پس از سفارش تکمیل‌شده نقش داده می‌شود. به درگاه پرداخت نیاز دارید.
  3. کد دعوت: عضو با واردکردن کد، نقش را می‌گیرد؛ مناسب مجموعه‌های بسته.

در هر سه حالت، تغییر نقش را فقط در کد سمت سرور و پس از بررسی معتبر انجام دهید. از کاربر نخواهید که نقش خودش را انتخاب کند و هرگز نقش را از ورودی فرم نخوانید. به‌جایش از $user->set_role( 'site_member' ) یا $user->add_role( 'site_member' ) روی کاربر مشخص استفاده کنید.

ملاحظات امنیتی و تجربه‌ی کاربر#

  • ثبت‌نام عمومی را روشن می‌کنید؟ پس اسپم ثبت‌نام را هم انتظار داشته باشید. تأیید ایمیل و محدودیت تعداد تلاش، پایه است. درباره‌ی ورود امن و محدودیت تلاش بخوانید.
  • فایل‌های ویژه (PDF، ویدیو) با محافظت از صفحه محافظت نمی‌شوند؛ نشانی مستقیم آن‌ها باید جداگانه قفل شود، مثل آنچه در فروش فایل گفتیم.
  • صفحه‌ی «حساب من» داشته باشید تا عضو بتواند اطلاعاتش را ببیند و ایمیل و رمز را عوض کند.
  • نقش مدیر را به هیچ عضو ندهید و دسترسی ابزارها را به حداقل برسانید. ساده‌ترین قانون: کمترین دسترسی لازم.

کی افزونه‌ی عضویت بگیریم؟#

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

خلاصه#

  • سایت عضویت یعنی ثبت‌نام، نقش، محتوای قفل‌شده و راهی برای ارتقای نقش.
  • دسترسی را با قابلیت (capability) بسنجید، نه با نام نقش.
  • نقش را در فعال‌سازی افزونه بسازید، نه در هر بار بارگذاری و نه در قالب.
  • قفل محتوا باید سمت سرور باشد؛ پنهان‌کردن با CSS محتوا را محافظت نمی‌کند.
  • کش و فایل‌های مستقیم دو سوراخ رایج‌اند؛ هر دو را بسنجید.
  • برای پرداخت دوره‌ای و تمدید، افزونه‌ی عضویت را در نظر بگیرید.