[ 'read.wp' => [ __( 'Read posts, terms, meta, settings', 'aicom' ), 'low' ], 'write.wp.posts' => [ __( 'Create & edit posts/pages', 'aicom' ), 'med' ], 'delete.wp.posts' => [ __( 'Trash & delete posts', 'aicom' ), 'med' ], 'manage.meta' => [ __( 'Post meta read/write', 'aicom' ), 'med' ], 'manage.taxonomies' => [ __( 'Categories, tags, taxonomies', 'aicom' ), 'med' ], 'manage.menus' => [ __( 'Navigation menus', 'aicom' ), 'med' ], ], __( 'Media & Files', 'aicom' ) => [ 'manage.media' => [ __( 'Upload & manage media library', 'aicom' ), 'med' ], 'manage.files' => [ __( 'Direct file system access', 'aicom' ), 'high' ], ], __( 'Users & Roles', 'aicom' ) => [ 'read.users' => [ __( 'List & read user profiles', 'aicom' ), 'med' ], 'manage.users' => [ __( 'Create & update users', 'aicom' ), 'high' ], 'delete.users' => [ __( 'Delete users', 'aicom' ), 'high' ], 'manage.roles' => [ __( 'Manage roles & capabilities', 'aicom' ), 'high' ], ], __( 'Site Configuration', 'aicom' ) => [ 'manage.wordpress.settings' => [ __( 'WordPress options/settings', 'aicom' ), 'critical' ], 'manage.plugins' => [ __( 'Plugin management & updates', 'aicom' ), 'critical' ], 'manage.backups' => [ __( 'Backup & restore data', 'aicom' ), 'high' ], ], __( 'Integrations', 'aicom' ) => [ 'manage.woocommerce.products' => [ __( 'WooCommerce products', 'aicom' ), 'med' ], 'manage.woocommerce.settings' => [ __( 'WooCommerce settings', 'aicom' ), 'high' ], 'manage.elementor' => [ __( 'Elementor pages & widgets', 'aicom' ), 'med' ], 'manage.polylang' => [ __( 'Polylang translations', 'aicom' ), 'med' ], 'manage.yoast' => [ __( 'Yoast SEO fields', 'aicom' ), 'med' ], 'manage.clautron' => [ __( 'Clautron blueprints', 'aicom' ), 'med' ], ], ]; $scope_tree_flat = array_merge( ...array_values( $scope_tree ) ); $all_scope_keys = array_keys( $scope_tree_flat ); // ── System presets ───────────────────────────────────────────────────────── $presets = [ 'read-only' => [ 'name' => __( 'Read-only', 'aicom' ), 'scopes' => [ 'read.wp', 'read.users' ], 'risk' => 'low', 'desc' => __( 'Safe browsing only', 'aicom' ), ], 'content-assistant' => [ 'name' => __( 'Content Assistant', 'aicom' ), 'scopes' => [ 'read.wp', 'write.wp.posts', 'manage.meta', 'manage.taxonomies' ], 'risk' => 'med', 'desc' => __( 'Write & publish content', 'aicom' ), ], 'elementor-editor' => [ 'name' => __( 'Elementor Editor', 'aicom' ), 'scopes' => [ 'read.wp', 'write.wp.posts', 'manage.meta', 'manage.elementor', 'manage.media' ], 'risk' => 'med', 'desc' => __( 'Build Elementor pages', 'aicom' ), ], 'woocommerce-catalog' => [ 'name' => __( 'WooCommerce Catalog', 'aicom' ), 'scopes' => [ 'read.wp', 'write.wp.posts', 'manage.meta', 'manage.woocommerce.products' ], 'risk' => 'med', 'desc' => __( 'Manage products', 'aicom' ), ], 'site-maintenance' => [ 'name' => __( 'Site Maintenance', 'aicom' ), 'scopes' => [ 'read.wp', 'manage.plugins', 'manage.backups', 'manage.wordpress.settings' ], 'risk' => 'high', 'desc' => __( 'Updates, backups, settings', 'aicom' ), ], 'full-admin' => [ 'name' => __( 'Full Admin', 'aicom' ), 'scopes' => $all_scope_keys, 'risk' => 'critical', 'desc' => __( 'All permissions', 'aicom' ), ], ]; // ── Custom presets from DB ───────────────────────────────────────────────── $custom_presets = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "SELECT id, name, scopes_json FROM {$wpdb->prefix}aicom_presets ORDER BY created_at ASC", ARRAY_A ) ?: []; // ── Edit mode ───────────────────────────────────────────────────────────── $edit_key_id = ( isset( $_GET['action'], $_GET['key_id'] ) && $_GET['action'] === 'edit_key' ) ? absint( wp_unslash( $_GET['key_id'] ) ) : 0; $edit_key = $edit_key_id ? $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}aicom_api_keys WHERE id = %d", $edit_key_id ), ARRAY_A ) : null; $show_archived = ! empty( $_GET['show_archived'] ); $archived_sql = $show_archived ? '' : "AND status != 'archived'"; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $keys = $wpdb->get_results( "SELECT id, label, key_prefix, scopes_json, restrictions_json, status, last_used_at, created_at, expires_at FROM {$wpdb->prefix}aicom_api_keys WHERE 1=1 $archived_sql ORDER BY created_at DESC", ARRAY_A ); ?>

$scopes ) : ?>
▼
[ $scope_label, $scope_risk ] ) : ?>

$p ) : ?>
$scopes ) : ?>
▼
[ $scope_label, $scope_risk ] ) : ?>

Authorization: Bearer <your-api-key>

'aicom-status-active', 'suspended' => 'aicom-status-suspended', 'expired' => 'aicom-status-expired', 'archived' => 'aicom-status-archived', default => 'aicom-status-revoked', }; ?>
…
—
✎