Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/amirrezashf/woocommerce-order-status-role-restrictions/archive/refs/heads/main.zipControl which WooCommerce order statuses each WordPress role is not allowed to select.
Overview
WooCommerce Order Status Role Restrictions adds role-based control to WooCommerce order status management.
Administrators with the manage_options capability can define, from a dedicated settings page, which order statuses are forbidden for each WordPress role. The plugin does not contain any hardcoded operational role names. Every available role is read dynamically from WordPress.
Restrictions are applied in two layers:
- Administration interface: prohibited statuses are disabled in WooCommerce's original status selector and supported button-based interfaces.
- Server-side enforcement: the requested status is checked again before WooCommerce saves the order.
The server-side check is important because a user could otherwise remove the HTML disabled attribute, disable JavaScript, or modify the submitted request.
Features
- Dynamic WordPress role detection
- No hardcoded role names
- Per-role restricted order statuses
- Users with
manage_optionsare always exempt - Dedicated settings page under WooCommerce
- Supports default and custom WooCommerce statuses
- Supports users with multiple roles
- Cumulative restrictions for multi-role users
- Disables restricted options in WooCommerce's original selector
- Supports
.fa-order-status-btncustom buttons - Supports
.wc-osb-btnfrom WooCommerce Order Status Buttons - Server-side protection against request manipulation
- Allows unrelated edits when an order already has a restricted status
- Supports classic WooCommerce order storage
- Supports WooCommerce HPOS
- Does not modify roles or capabilities
- Does not create custom database tables
- Stores all rules in one WordPress option
- Single-file plugin architecture
Why UI-Only Restrictions Are Not Enough
A disabled button improves usability but does not provide reliable authorization.
A user may attempt to bypass a visual restriction by:
- Disabling JavaScript
- Editing the page HTML
- Removing the
disabledattribute - Changing the submitted form value
- Sending a handcrafted POST request
- Using another administrative interface
For this reason, the plugin checks the transition again through WooCommerce's order object before the order is saved.
When an unauthorized transition is detected, the plugin restores the persisted order status. Other permitted order changes can still be saved.
Administrator Exemption
Users with the following capability are always exempt:
manage_options
This ensures the site administrator cannot accidentally lock themselves out of order statuses.
Roles that grant manage_options are not displayed on the settings page because restrictions would not affect them.
Settings Page
After activation, open:
WooCommerce → Order Status Access
The page displays an expandable card for every configurable WordPress role.
For each role:
- Open the role card.
- Select the statuses that must be forbidden.
- Save the settings.
A checked status means:
This role cannot select this order status.
The settings page includes:
- Role display name
- Internal role key
- Number of restricted statuses
- Expand and collapse controls
- Select-all control
- Clear-all control
- Status labels
- Internal status keys
- Responsive layout
Example Configuration
A saved configuration may look like:
array(
'shop_manager' => array(
'completed',
'refunded',
),
'support_agent' => array(
'cancelled',
'refunded',
),
);
In this example:
shop_managercannot selectcompletedorrefunded.support_agentcannot selectcancelledorrefunded.
Multi-Role Users
Restrictions are cumulative.
If one assigned role restricts completed and another assigned role restricts refunded, the user is restricted from both statuses.
This conservative behavior prevents a second role from unintentionally expanding access granted by another role.
Supported Order Statuses
Statuses are read through:
wc_get_order_statuses()
This normally includes:
- Pending payment
- Processing
- On hold
- Completed
- Cancelled
- Refunded
- Failed
- Compatible custom statuses
The plugin does not maintain a fixed status list.
Status-Key Normalization
WooCommerce may represent a status with or without the wc- prefix.
Examples:
wc-processing
processing
Both values are normalized to:
processing
This keeps rules consistent between the settings page, classic order storage, HPOS, the original selector, custom buttons, and server-side validation.
Administration Interface Enforcement
For restricted users, prohibited statuses are disabled in WooCommerce's original field:
<select id="order_status">
The plugin also supports these button interfaces:
<button class="fa-order-status-btn" data-value="completed">
<button class="wc-osb-btn" data-value="completed">
Restricted buttons receive:
- Disabled state
- Reduced opacity
aria-disabled- Explanatory tooltip
- Removed pointer interaction
Current Restricted Status
An order may already have a status that is restricted for the current user's role.
The plugin allows the user to save unrelated changes while the order remains in its already-persisted status. This prevents the order edit form from becoming unusable.
The user cannot transition another order into that restricted status.
Server-Side Enforcement Flow
Before WooCommerce saves an order, the plugin:
- Confirms that the request is inside WordPress administration.
- Exempts users with
manage_options. - Checks whether the order status has changed.
- Normalizes the target status key.
- Combines restrictions from all current user roles.
- Loads the persisted order status.
- Determines whether the requested transition is forbidden.
- Restores the persisted status when necessary.
- Allows other order changes to continue.
- Displays an administrator notice.
- Fires an optional action hook for audit integrations.
Supported Order Screens
Classic order storage
wp-admin/post.php?post=123&action=edit
WooCommerce HPOS
wp-admin/admin.php?page=wc-orders&action=edit&id=123
Data Storage
Rules are stored in one WordPress option:
wc_osrr_restriction_rules
The option uses a structure similar to:
array(
'role_key' => array(
'processing',
'completed',
),
);
Autoload is disabled for this option.
Temporary rejection notices use a short-lived transient:
wc_osrr_notice_USER_ID
The transient expires after one minute and is deleted after display.
Information Not Stored
The plugin does not store:
- Customer details
- Order contents
- Order status history
- User activity history
- IP addresses
- Browser information
- Analytics data
- External tracking identifiers
Requirements
- PHP 7.4 or later
- WordPress 6.0 or later
- WooCommerce
- An administrator with
manage_optionsto configure rules
Installation
- Download the plugin ZIP file.
- Open Plugins → Add New Plugin.
- Select Upload Plugin.
- Upload the ZIP file.
- Install and activate the plugin.
- Open WooCommerce → Order Status Access.
- Configure role restrictions.
- Save the settings.
Manual Installation
- Extract the plugin ZIP file.
- Upload the plugin folder to:
wp-content/plugins/
- Activate WooCommerce Order Status Role Restrictions.
- Open the settings page under WooCommerce.
File Structure
WooCommerce-Order-Status-Role-Restrictions/
├── woocommerce-order-status-role-restrictions.php
├── README.md
└── LICENSE
Security
The plugin includes:
- Direct-file access protection
manage_optionsrequirement for settings- WordPress nonce verification
- Sanitized role keys
- Sanitized status keys
- Validation against registered WordPress roles
- Validation against current WooCommerce statuses
- Server-side transition enforcement
- No public AJAX endpoint
- No custom REST API route
- No direct SQL queries
- No direct order-table access
- No modification of roles or capabilities
HPOS Compatibility
The plugin explicitly declares compatibility with WooCommerce High-Performance Order Storage.
All order operations use WooCommerce order objects. The plugin does not query or update order database tables directly.
Performance
Settings CSS and JavaScript load only on the plugin settings page.
Order restriction assets load only when:
- The user is editing an existing WooCommerce order
- The user does not have
manage_options - At least one status is restricted for one of the user's roles
No frontend assets are loaded.
Hooks and Filters
wc_osrr_rules
Filters normalized restriction rules after they are loaded.
add_filter(
'wc_osrr_rules',
static function ( $rules ) {
return $rules;
}
);
wc_osrr_configurable_roles
Filters roles displayed on the settings page.
add_filter(
'wc_osrr_configurable_roles',
static function ( $roles ) {
unset( $roles['subscriber'] );
return $roles;
}
);
wc_osrr_rules_saved
Runs after valid settings are saved.
add_action(
'wc_osrr_rules_saved',
static function ( $rules ) {
// Optional synchronization or audit logic.
}
);
wc_osrr_status_change_rejected
Runs when a forbidden status transition is rejected.
add_action(
'wc_osrr_status_change_rejected',
static function ( $order_id, $user_id, $target_status, $stored_status ) {
// Optional audit integration.
},
10,
4
);
Compatibility Notes
The following button selectors are supported directly:
.fa-order-status-btn
.wc-osb-btn
A different custom status interface may require an additional visual integration.
Server-side enforcement remains active even when a third-party interface is not visually disabled.
Limitations
- Restrictions apply to administrative order editing.
- Users with
manage_optionsare intentionally exempt. - The plugin does not replace WooCommerce capabilities.
- It does not hide orders from users.
- It does not hide status labels.
- It restricts transitions into selected statuses.
- Third-party order editors that bypass WooCommerce order objects may require integration.
- Unsupported custom JavaScript interfaces may need an additional selector for visual disabling.
Troubleshooting
A role does not appear
Roles with manage_options are excluded because they are exempt. A developer may also remove roles through wc_osrr_configurable_roles.
A custom status does not appear
Confirm that the status is registered before wc_get_order_statuses() runs and appears in WooCommerce's normal selector.
A restricted status is still visible
Statuses are disabled rather than removed. This keeps the current stored status stable and prevents broken order forms.
A custom button is not disabled
The custom interface may use another selector. Server-side enforcement still rejects the unauthorized transition.
The order already has a restricted status
The user can save unrelated order changes while the order remains in its current persisted status. The user cannot transition another order into that status.
Changelog
1.0.0
- Initial release
- Removed hardcoded role dependencies
- Added dynamic role discovery
- Added per-role restricted-status settings
- Added
manage_optionsexemption - Added multi-role cumulative restrictions
- Added original WooCommerce selector restrictions
- Added
.fa-order-status-btncompatibility - Added
.wc-osb-btncompatibility - Added server-side transition enforcement
- Added classic order edit-screen support
- Added HPOS order edit-screen support
- Added settings validation and nonce protection
- Added rejection notices
- Added public hooks and filters
License
GPL-3.0
https://www.gnu.org/licenses/gpl-3.0.html
Author
Amirreza Shayesteh Far
- Website: https://amirrezaa.ir/
- GitHub: https://github.com/amirrezashf
- Repository: https://github.com/amirrezashf/WooCommerce-Order-Status-Role-Restrictions
محدودسازی وضعیت سفارش ووکامرس بر اساس نقش
کنترل اینکه هر نقش وردپرس اجازه انتخاب کدام وضعیتهای سفارش ووکامرس را نداشته باشد.
معرفی
افزونه WooCommerce Order Status Role Restrictions امکان تعیین محدودیت وضعیت سفارش بر اساس نقشهای وردپرس را فراهم میکند.
مدیرانی که capability زیر را دارند میتوانند از طریق یک صفحه تنظیمات اختصاصی مشخص کنند که هر نقش از انتخاب کدام وضعیتهای سفارش منع شود:
manage_options
هیچ نام نقشی داخل افزونه hardcode نشده است. تمام نقشها بهصورت داینامیک از وردپرس خوانده میشوند.
محدودیتها در دو سطح اعمال میشوند:
- رابط مدیریت: وضعیتهای ممنوع در select اصلی ووکامرس و رابطهای دکمهای پشتیبانیشده غیرفعال میشوند.
- سمت سرور: پیش از ذخیره سفارش، وضعیت درخواستی دوباره بررسی میشود.
این کنترل سمت سرور مانع دور زدن محدودیت از طریق تغییر HTML، غیرفعال کردن JavaScript یا دستکاری درخواست میشود.
قابلیتها
- شناسایی داینامیک نقشهای وردپرس
- بدون نام نقش ثابت در کد
- تعیین وضعیتهای ممنوع برای هر نقش
- معافیت کاربران دارای
manage_options - صفحه تنظیمات اختصاصی زیرمنوی ووکامرس
- پشتیبانی از وضعیتهای پیشفرض و سفارشی
- پشتیبانی از کاربران دارای چند نقش
- ترکیب محدودیتهای تمام نقشهای کاربر
- غیرفعالسازی وضعیت در select اصلی ووکامرس
- سازگاری با
.fa-order-status-btn - سازگاری با
.wc-osb-btn - کنترل سمت سرور
- جلوگیری از دور زدن با درخواست دستی
- امکان ذخیره سایر تغییرات سفارش در وضعیت فعلی ممنوع
- پشتیبانی از ساختار کلاسیک سفارشها
- پشتیبانی از HPOS
- بدون تغییر role یا capability
- بدون جدول اختصاصی دیتابیس
- ذخیره قوانین در یک option
- معماری تکفایلی
اهمیت کنترل سمت سرور
غیرفعال کردن یک دکمه یا گزینه با JavaScript بهتنهایی یک کنترل امنیتی کامل نیست.
کاربر ممکن است تلاش کند محدودیت را با روشهای زیر دور بزند:
- غیرفعال کردن JavaScript
- حذف ویژگی
disabled - تغییر HTML صفحه
- تغییر مقدار ارسالی فرم
- ارسال درخواست POST دستی
- استفاده از رابط مدیریتی دیگری
افزونه پیش از ذخیره سفارش، transition درخواستی را دوباره بررسی میکند. اگر وضعیت برای نقش کاربر ممنوع باشد، وضعیت قبلی سفارش بازگردانده میشود و سایر تغییرات مجاز سفارش همچنان ذخیره میشوند.
معافیت مدیران
کاربران دارای capability زیر همیشه از محدودیتها مستثنا هستند:
manage_options
این رفتار مانع قفل شدن مدیر اصلی سایت میشود.
نقشهایی که این capability را دارند در ماتریس تنظیمات نمایش داده نمیشوند؛ زیرا محدودیت روی آنها اثری ندارد.
صفحه تنظیمات
پس از فعالسازی افزونه وارد مسیر زیر شوید:
ووکامرس ← دسترسی وضعیت سفارش
برای هر نقش:
- کارت نقش را باز کنید.
- وضعیتهایی را که باید ممنوع باشند تیک بزنید.
- تنظیمات را ذخیره کنید.
تیک خوردن یک وضعیت یعنی:
این نقش اجازه انتخاب این وضعیت را ندارد.
صفحه تنظیمات شامل موارد زیر است:
- نام نمایشی نقش
- کلید داخلی نقش
- تعداد وضعیتهای ممنوع
- باز و بسته کردن کارت نقش
- انتخاب همه
- پاک کردن همه
- نام وضعیت
- کلید داخلی وضعیت
- طراحی واکنشگرا
نمونه ساختار قوانین
array(
'shop_manager' => array(
'completed',
'refunded',
),
'support_agent' => array(
'cancelled',
'refunded',
),
);
در این مثال:
- نقش
shop_managerاجازه انتخابcompletedوrefundedرا ندارد. - نقش
support_agentاجازه انتخابcancelledوrefundedرا ندارد.
کاربران دارای چند نقش
محدودیتها با یکدیگر ترکیب میشوند.
اگر یک نقش وضعیت completed را محدود کند و نقش دیگر وضعیت refunded را محدود کند، کاربر از هر دو وضعیت منع میشود.
این رویکرد مانع افزایش ناخواسته دسترسی از طریق نقش دوم میشود.
وضعیتهای پشتیبانیشده
وضعیتها از تابع رسمی زیر خوانده میشوند:
wc_get_order_statuses()
در نتیجه موارد زیر پوشش داده میشوند:
- در انتظار پرداخت
- در حال انجام
- در انتظار بررسی
- تکمیلشده
- لغوشده
- مستردشده
- ناموفق
- وضعیتهای سفارشی سازگار
افزونه فهرست ثابتی از وضعیتها داخل کد ندارد.
نرمالسازی کلید وضعیت
ووکامرس ممکن است یک وضعیت را به شکلهای زیر ارائه کند:
wc-processing
processing
هر دو مقدار به شکل زیر نرمال میشوند:
processing
محدودیت در رابط مدیریت
وضعیتهای ممنوع در select اصلی ووکامرس غیرفعال میشوند:
<select id="order_status">
رابطهای دکمهای زیر نیز پشتیبانی میشوند:
<button class="fa-order-status-btn" data-value="completed">
<button class="wc-osb-btn" data-value="completed">
برای دکمه ممنوع موارد زیر اعمال میشود:
- حالت disabled
- کاهش opacity
aria-disabled- tooltip توضیحی
- حذف امکان کلیک
وضعیت فعلی ممنوع
ممکن است یک سفارش از قبل در وضعیتی باشد که بعداً برای نقش فعلی ممنوع شده است.
در این شرایط، افزونه اجازه میدهد کاربر سایر اطلاعات سفارش را ویرایش کند. این رفتار مانع خراب شدن فرم سفارش میشود.
کاربر اجازه انتقال سفارش دیگری به آن وضعیت را ندارد.
روند کنترل سمت سرور
پیش از ذخیره سفارش، افزونه:
- بررسی میکند درخواست داخل مدیریت وردپرس باشد.
- کاربران دارای
manage_optionsرا معاف میکند. - تغییر وضعیت سفارش را تشخیص میدهد.
- وضعیت هدف را نرمال میکند.
- محدودیت تمام نقشهای کاربر را ترکیب میکند.
- وضعیت ذخیرهشده سفارش را میخواند.
- transition غیرمجاز را تشخیص میدهد.
- وضعیت قبلی را بازمیگرداند.
- اجازه ذخیره سایر تغییرات را میدهد.
- پیام خطا نمایش میدهد.
- action اختیاری audit را اجرا میکند.
صفحههای پشتیبانیشده
ساختار کلاسیک
wp-admin/post.php?post=123&action=edit
ساختار HPOS
wp-admin/admin.php?page=wc-orders&action=edit&id=123
ذخیرهسازی داده
تمام قوانین در option زیر ذخیره میشوند:
wc_osrr_restriction_rules
ساختار کلی:
array(
'role_key' => array(
'processing',
'completed',
),
);
autoload این option غیرفعال است.
برای نمایش پیام رد شدن تغییر وضعیت، transient کوتاهمدت زیر استفاده میشود:
wc_osrr_notice_USER_ID
این transient پس از یک دقیقه منقضی میشود و پس از نمایش حذف خواهد شد.
اطلاعاتی که ذخیره نمیشوند
افزونه موارد زیر را ذخیره نمیکند:
- اطلاعات مشتری
- محتوای سفارش
- تاریخچه وضعیت سفارش
- تاریخچه فعالیت کاربر
- IP
- اطلاعات مرورگر
- analytics
- اطلاعات tracking
پیشنیازها
- PHP 7.4 یا جدیدتر
- WordPress 6.0 یا جدیدتر
- WooCommerce
- مدیر دارای
manage_optionsبرای تنظیم قوانین
نصب
- فایل ZIP افزونه را دانلود کنید.
- وارد افزونهها ← افزودن افزونه تازه شوید.
- گزینه بارگذاری افزونه را انتخاب کنید.
- فایل ZIP را بارگذاری کنید.
- افزونه را نصب و فعال کنید.
- وارد ووکامرس ← دسترسی وضعیت سفارش شوید.
- محدودیتها را تنظیم کنید.
- تنظیمات را ذخیره کنید.
نصب دستی
- فایل ZIP را استخراج کنید.
- پوشه افزونه را در مسیر زیر قرار دهید:
wp-content/plugins/
- افزونه را فعال کنید.
- تنظیمات را از زیرمنوی ووکامرس انجام دهید.
ساختار فایلها
WooCommerce-Order-Status-Role-Restrictions/
├── woocommerce-order-status-role-restrictions.php
├── README.md
└── LICENSE
امنیت
- جلوگیری از اجرای مستقیم فایل
- الزام
manage_optionsبرای تنظیمات - nonce برای ذخیره فرم
- پاکسازی کلید نقش
- پاکسازی کلید وضعیت
- اعتبارسنجی نقشهای ثبتشده
- اعتبارسنجی وضعیتهای ووکامرس
- کنترل transition در سمت سرور
- بدون AJAX عمومی
- بدون REST API اختصاصی
- بدون SQL مستقیم
- بدون دسترسی مستقیم به جدول سفارش
- بدون تغییر role یا capability
سازگاری با HPOS
افزونه سازگاری خود را با WooCommerce High-Performance Order Storage اعلام میکند.
تمام عملیات سفارش از طریق objectهای رسمی ووکامرس انجام میشوند و افزونه مستقیماً جدول سفارشها را تغییر نمیدهد.
عملکرد و بهینهسازی
فایلهای تنظیمات فقط در صفحه تنظیمات افزونه بارگذاری میشوند.
فایلهای محدودیت سفارش فقط زمانی بارگذاری میشوند که:
- کاربر یک سفارش موجود را ویرایش کند
- کاربر
manage_optionsنداشته باشد - حداقل یک وضعیت برای یکی از نقشهای کاربر ممنوع باشد
هیچ فایل frontend بارگذاری نمیشود.
هوکها و فیلترها
wc_osrr_rules
تغییر قوانین نرمالشده:
add_filter(
'wc_osrr_rules',
static function ( $rules ) {
return $rules;
}
);
wc_osrr_configurable_roles
تغییر نقشهای قابل نمایش:
add_filter(
'wc_osrr_configurable_roles',
static function ( $roles ) {
unset( $roles['subscriber'] );
return $roles;
}
);
wc_osrr_rules_saved
پس از ذخیره تنظیمات اجرا میشود:
add_action(
'wc_osrr_rules_saved',
static function ( $rules ) {
// اتصال یا audit اختیاری.
}
);
wc_osrr_status_change_rejected
پس از رد شدن transition غیرمجاز اجرا میشود:
add_action(
'wc_osrr_status_change_rejected',
static function ( $order_id, $user_id, $target_status, $stored_status ) {
// ثبت گزارش اختیاری.
},
10,
4
);
نکات سازگاری
selectorهای زیر مستقیماً پشتیبانی میشوند:
.fa-order-status-btn
.wc-osb-btn
رابطهای سفارشی دیگر ممکن است برای غیرفعالسازی ظاهری به integration جداگانه نیاز داشته باشند.
کنترل سمت سرور حتی در صورت پشتیبانی نشدن ظاهر رابط همچنان فعال است.
محدودیتها
- محدودیتها روی ویرایش مدیریتی سفارش اعمال میشوند.
- کاربران دارای
manage_optionsعمداً معاف هستند. - افزونه جایگزین capabilityهای ووکامرس نیست.
- سفارشها را از کاربران مخفی نمیکند.
- نام وضعیت را مخفی نمیکند.
- transition به وضعیت انتخابشده را محدود میکند.
- order editorهای شخص ثالث که WooCommerce order object را دور میزنند ممکن است به integration نیاز داشته باشند.
- رابطهای JavaScript ناشناخته ممکن است selector اضافه نیاز داشته باشند.
عیبیابی
یک نقش نمایش داده نمیشود
نقشهای دارای manage_options نمایش داده نمیشوند؛ زیرا معاف هستند. همچنین ممکن است توسعهدهنده نقش را با wc_osrr_configurable_roles حذف کرده باشد.
یک وضعیت سفارشی نمایش داده نمیشود
بررسی کنید وضعیت قبل از اجرای wc_get_order_statuses() ثبت شده باشد و در selector اصلی ووکامرس نمایش داده شود.
وضعیت ممنوع همچنان دیده میشود
وضعیتها حذف نمیشوند و فقط غیرفعال میشوند. این کار از خراب شدن مقدار فعلی فرم جلوگیری میکند.
یک دکمه سفارشی غیرفعال نمیشود
ممکن است رابط از selector دیگری استفاده کند. کنترل سمت سرور همچنان transition غیرمجاز را رد میکند.
سفارش از قبل وضعیت ممنوع دارد
کاربر میتواند سایر تغییرات سفارش را ذخیره کند، اما نمیتواند سفارش دیگری را به آن وضعیت منتقل کند.
تاریخچه تغییرات
1.0.0
- انتشار اولیه
- حذف نقشهای hardcodeشده
- افزودن شناسایی داینامیک نقشها
- افزودن تنظیم وضعیت ممنوع برای هر نقش
- معافیت کاربران دارای
manage_options - ترکیب محدودیت کاربران چندنقشی
- محدودسازی select اصلی ووکامرس
- سازگاری با
.fa-order-status-btn - سازگاری با
.wc-osb-btn - کنترل سمت سرور
- پشتیبانی از صفحه کلاسیک سفارش
- پشتیبانی از HPOS
- اعتبارسنجی تنظیمات و nonce
- افزودن پیام رد تغییر وضعیت
- افزودن hookها و filterهای عمومی
مجوز
GPL-3.0
https://www.gnu.org/licenses/gpl-3.0.html
نویسنده
Amirreza Shayesteh Far
- وبسایت: https://amirrezaa.ir/
- گیتهاب: https://github.com/amirrezashf
- مخزن افزونه: https://github.com/amirrezashf/WooCommerce-Order-Status-Role-Restrictions