Trong quá trình vận hành hệ thống WHMCS, việc có hàng trăm đến hàng nghìn tài khoản khách hàng không còn sử dụng, không có dịch vụ hoặc chỉ đăng ký thử nghiệm là điều không thể tránh khỏi. Điều này không chỉ làm cơ sở dữ liệu trở nên cồng kềnh, mà còn gây khó khăn trong việc quản lý, tìm kiếm và báo cáo.
Đó là lý do GizaData phát triển công cụ User Cleanup Tool – một addon tiện ích, giúp lọc và xoá nhanh những người dùng không còn liên quan chỉ với vài thao tác.
Addon sẽ tự động liệt kê tất cả các khách hàng trong hệ thống WHMCS. Bạn có thể:
Giao diện hiển thị rõ ràng:
Chỉ với một cú click, addon sẽ xoá sạch các dữ liệu liên quan đến khách hàng được chọn:
tblclients
)tblhosting
)tblorders
)tblinvoices
, tblinvoiceitems
)tblusers
, tbluserclients
)⚠️ Lưu ý: Tính năng này không ảnh hưởng đến dịch vụ thật sự đang chạy như VPS hoặc hosting đã được tạo trên các nền tảng ngoài (Virtualizor, DirectAdmin, v.v.). Tuy nhiên, WHMCS sẽ không còn ghi nhận các dịch vụ đó sau khi khách hàng bị xoá.
Addon có thể được mở rộng để chỉ xoá khách hàng không có dịch vụ, tránh ảnh hưởng đến những tài khoản vẫn đang hoạt động.
Bạn có thể bổ sung logic kiểm tra trước khi xoá
$hostingCount = Capsule::table('tblhosting')->where('userid', $id)->count();
if ($hostingCount === 0) {
// Tiến hành xoá
}
modules/addons/usercleanup
tbluserclients
nếu có)User Cleanup Tool là giải pháp tối ưu dành cho các quản trị viên WHMCS muốn:
Hãy trải nghiệm ngay hôm nay để tăng hiệu quả quản trị hệ thống WHMCS của bạn!
<?php
if (!defined("WHMCS")) {
die("This file cannot be accessed directly");
}
use WHMCS\Database\Capsule;
function usercleanup_config() {
return [
"name" => "User Cleanup Tool",
"description" => "Hiển thị danh sách người dùng và xóa những người dùng được chọn.",
"version" => "1.2",
"author" => "GizaData",
"fields" => []
];
}
function usercleanup_output($vars) {
// Xử lý xóa trước khi render giao diện
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['delete_ids']) && is_array($_POST['delete_ids'])) {
foreach ($_POST['delete_ids'] as $id) {
Capsule::table('tblhosting')->where('userid', $id)->delete();
Capsule::table('tblorders')->where('userid', $id)->delete();
Capsule::table('tblinvoices')->where('userid', $id)->delete();
Capsule::table('tblinvoiceitems')->where('userid', $id)->delete();
Capsule::table('tblemails')->where('userid', $id)->delete();
Capsule::table('tblnotes')->where('userid', $id)->delete();
Capsule::table('tbldomains')->where('userid', $id)->delete();
Capsule::table('tbltickets')->where('userid', $id)->delete();
$client = Capsule::table('tblclients')->where('id', $id)->first();
$email = $client ? $client->email : null;
Capsule::table('tblclients')->where('id', $id)->delete();
if ($email) {
$user = Capsule::table('tblusers')->where('email', $email)->first();
if ($user) {
if (Capsule::schema()->hasTable('tbluserclients')) {
$userClientCount = Capsule::table('tbluserclients')->where('auth_user_id', $user->id)->count();
if ($userClientCount <= 1) {
Capsule::table('tbluserclients')->where('auth_user_id', $user->id)->delete();
Capsule::table('tblusers')->where('id', $user->id)->delete();
}
} else {
Capsule::table('tblusers')->where('id', $user->id)->delete();
}
}
}
}
echo '<div style="color:green; font-weight:bold; margin-bottom:10px">✔ Đã xoá ' . count($_POST['delete_ids']) . ' khách hàng và người dùng liên quan.</div>';
echo '<meta http-equiv="refresh" content="2">';
return;
}
$limit = isset($_GET['limit']) ? (int) $_GET['limit'] : 10;
$page = isset($_GET['page']) ? (int) $_GET['page'] : 1;
$offset = ($page - 1) * $limit;
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
$query = Capsule::table('tblclients');
if ($search !== '') {
$query->where(function ($q) use ($search) {
$q->where('firstname', 'like', "%$search%")
->orWhere('lastname', 'like', "%$search%")
->orWhere('email', 'like', "%$search%");
});
}
$totalClients = $query->count();
$clients = $query->skip($offset)->take($limit)->get();
echo '<style>
form.usercleanup-wrapper { font-family: sans-serif; }
form.usercleanup-wrapper table { border-collapse: collapse; width: 100%; margin-top: 10px; }
form.usercleanup-wrapper th, form.usercleanup-wrapper td { border: 1px solid #ccc; padding: 8px; text-align: left; }
form.usercleanup-wrapper th { background-color: #f4f4f4; }
form.usercleanup-wrapper input[type="text"] { padding: 6px; width: 250px; }
form.usercleanup-wrapper select, form.usercleanup-wrapper button { padding: 6px 10px; margin-left: 10px; }
</style>';
echo '<form method="get" class="usercleanup-wrapper">
<input type="hidden" name="module" value="usercleanup" />
<input type="text" name="search" value="' . htmlspecialchars($search) . '" placeholder="Tìm theo tên hoặc email..." />
<button type="submit">Tìm kiếm</button>
<label>Hiển thị:</label>
<select name="limit" onchange="this.form.submit()">';
foreach ([10, 20, 50, 100, 200, 500] as $opt) {
$selected = ($limit == $opt) ? ' selected' : '';
echo "<option value='$opt'$selected>$opt</option>";
}
echo '</select>';
echo '</form>';
echo '<form method="post" class="usercleanup-wrapper">
<h2>Danh sách khách hàng</h2>
<button type="submit" name="delete" onclick="return confirm(\'Xoá những khách hàng đã chọn?\')">Xóa đã chọn</button>
<table>
<tr><th><input type="checkbox" id="checkAll"></th><th>ID</th><th>Tên</th><th>Email</th><th>Số dịch vụ</th></tr>';
foreach ($clients as $client) {
$hostingCount = Capsule::table('tblhosting')->where('userid', $client->id)->count();
echo "<tr>
<td><input type='checkbox' name='delete_ids[]' value='{$client->id}'></td>
<td>{$client->id}</td>
<td>{$client->firstname} {$client->lastname}</td>
<td>{$client->email}</td>
<td>$hostingCount</td>
</tr>";
}
echo '</table>
</form>';
echo <<<HTML
<script>
document.getElementById("checkAll").addEventListener("click", function() {
var checkboxes = document.querySelectorAll("input[name='delete_ids[]']");
checkboxes.forEach(function(cb) {
cb.checked = this.checked;
}, this);
});
</script>
HTML;
}
dịch vụ chất lượng khách hàng tin tưởng