120 lines
3.0 KiB
PHP
120 lines
3.0 KiB
PHP
<?php
|
|||
|
|
namespace AuroraAdmin\MenuCreator;
|
||
|
|
|
||
|
|
defined("ABSPATH") || exit();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Custom admin-menu configurations: hide/rename/reorder WP's native menu
|
||
|
|
* items per role. Storage + the runtime hook that actually applies a
|
||
|
|
* published config live here; REST CRUD lives in MenuCreatorData.php.
|
||
|
|
*/
|
||
|
|
class MenuCreator
|
||
|
|
{
|
||
|
|
const TABLE = "aurora_admin_menus";
|
||
|
|
const DB_VERSION = "1";
|
||
|
|
const DB_OPTION = "aurora_admin_menus_db_version";
|
||
|
|
|
||
|
|
public function __construct()
|
||
|
|
{
|
||
|
|
add_action("init", [self::class, "maybe_install"]);
|
||
|
|
// Late priority so it runs after all other plugins have registered
|
||
|
|
// their own menu items — there's nothing left to reorder/hide otherwise.
|
||
|
|
add_action("admin_menu", [self::class, "apply"], PHP_INT_MAX);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function table_name()
|
||
|
|
{
|
||
|
|
global $wpdb;
|
||
|
|
return $wpdb->prefix . self::TABLE;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function maybe_install()
|
||
|
|
{
|
||
|
|
if (get_option(self::DB_OPTION) === self::DB_VERSION) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
global $wpdb;
|
||
|
|
$table = self::table_name();
|
||
|
|
$charset = $wpdb->get_charset_collate();
|
||
|
|
|
||
|
|
$sql = "CREATE TABLE {$table} (
|
||
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
|
|
name VARCHAR(191) NOT NULL DEFAULT '',
|
||
|
|
status VARCHAR(20) NOT NULL DEFAULT 'draft',
|
||
|
|
roles TEXT NULL,
|
||
|
|
items LONGTEXT NULL,
|
||
|
|
created_at DATETIME NOT NULL,
|
||
|
|
updated_at DATETIME NOT NULL,
|
||
|
|
PRIMARY KEY (id),
|
||
|
|
KEY idx_status (status)
|
||
|
|
) {$charset};";
|
||
|
|
|
||
|
|
require_once ABSPATH . "wp-admin/includes/upgrade.php";
|
||
|
|
dbDelta($sql);
|
||
|
|
|
||
|
|
update_option(self::DB_OPTION, self::DB_VERSION);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Applies every published config whose target roles match the current
|
||
|
|
* user: hides items marked hidden and relabels items with a custom label.
|
||
|
|
*/
|
||
|
|
public static function apply()
|
||
|
|
{
|
||
|
|
global $menu, $wpdb;
|
||
|
|
|
||
|
|
if (!is_admin() || !function_exists("wp_get_current_user")) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$user = wp_get_current_user();
|
||
|
|
if (!$user || !$user->exists()) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$table = self::table_name();
|
||
|
|
$configs = $wpdb->get_results("SELECT roles, items FROM {$table} WHERE status = 'published'");
|
||
|
|
if (!$configs) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach ($configs as $config) {
|
||
|
|
$roles = json_decode($config->roles ?: "[]", true);
|
||
|
|
if (!is_array($roles) || !$roles) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (!array_intersect((array) $user->roles, $roles)) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
$items = json_decode($config->items ?: "[]", true);
|
||
|
|
if (!is_array($items)) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach ($items as $item) {
|
||
|
|
$native_id = isset($item["native_id"]) ? $item["native_id"] : "";
|
||
|
|
if ($native_id === "") {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach ($menu as $key => $entry) {
|
||
|
|
if (!isset($entry[2]) || $entry[2] !== $native_id) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!empty($item["hidden"])) {
|
||
|
|
unset($menu[$key]);
|
||
|
|
continue 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!empty($item["label"])) {
|
||
|
|
$menu[$key][0] = sanitize_text_field($item["label"]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|