# Role Manager - Developer Guide

## What This Module Does

The role-manager filters plugin settings based on WordPress user capabilities. It hooks into both the **GET** and **UPDATE** flows of admin settings, stripping any setting key that isn't explicitly registered in the option mappings.

**If you add a new setting anywhere in SureRank (free or pro) and don't register it here, it will be silently removed from the API response.**

---

## Checklist: Adding a New Setting Key

When you add a new setting via any defaults filter (`surerank_*_defaults`), you **must** also register it in the role-manager.

### Step 1 — Add the key to `mappings.php`

Open `mappings.php` → `get_option_mappings()` and add your setting key to the appropriate capability array.

```php
// mappings.php → get_option_mappings()

'surerank_global_setting' => [
    // ... existing keys ...
    'your_new_setting_key',   // <-- add here
],
```

**That's it for most cases.** If you're only adding a new option key to an existing feature, this single step is all you need.

### Where to place the key

Add it next to related settings. For example:
- Image settings → near `auto_set_image_title`, `auto_set_image_alt`
- Sitemap settings → near `enable_xml_sitemap`, `enable_video_sitemap`
- Social settings → near `facebook_page_url`, `twitter_card_type`

---

## Checklist: Adding a New Feature / Capability

If you're adding an entirely new capability (beyond `global_setting` and `content_setting`):

### Step 1 — Register the capability

```php
// mappings.php → get_capability_map()

return [
    'content_setting'    => 'surerank_content_setting',
    'global_setting'     => 'surerank_global_setting',
    'your_new_feature'   => 'surerank_your_new_feature',  // <-- add
];
```

### Step 2 — Add a label

```php
// mappings.php → get_feature_labels()

return [
    'content_setting'    => __( 'SureRank Settings in Editor', 'surerank-pro' ),
    'global_setting'     => __( 'SureRank Global settings', 'surerank-pro' ),
    'your_new_feature'   => __( 'Your Feature Name', 'surerank-pro' ),  // <-- add
];
```

### Step 3 — Map option keys to the capability

```php
// mappings.php → get_option_mappings()

'surerank_your_new_feature' => [
    'setting_key_1',
    'setting_key_2',
],
```

### Step 4 — (If needed) Map submenu access

```php
// mappings.php → get_submenu_capability_map()

'surerank#/your-page' => [ 'your_new_feature' ],
```

### Step 5 — Update sanitization in `api.php`

Add the new feature slug to the allowed features array in `sanitize_settings()`:

```php
// api.php → sanitize_settings()

$allowed_features = [
    'content_setting',
    'global_setting',
    'role_manager',
    'your_new_feature',  // <-- add
];
```

---

## How The Filtering Works

```
API Request (GET /admin/global-settings)
    │
    ▼
Settings::get()                      ← Merges DB values with defaults
    │
    ▼
apply_filters('surerank_get_admin_settings_data', $data)
    │
    ▼
filter_settings_by_capability()      ← init.php:77
    │
    ├─ Reads allowed keys from Mappings::get_option_mappings()
    ├─ Checks current_user_can() for each capability
    ├─ Builds allowed key list
    └─ Removes any key NOT in the allowed list
    │
    ▼
API Response (filtered)
```

The same filter runs on **update** via `surerank_update_admin_settings_data`, preventing users from saving settings they don't have access to.

---

## Registering Dynamic Keys via Filter

`get_option_mappings()` is filterable via `surerank_role_manager_option_mappings`. Use this when your module generates setting keys at runtime (e.g., based on registered CPTs or taxonomies) that can't be hardcoded.

```php
// In your module's constructor:
add_filter( 'surerank_role_manager_option_mappings', [ $this, 'register_dynamic_option_keys' ] );

// Callback:
public function register_dynamic_option_keys( $mappings ) {
    $dynamic_keys = [];

    foreach ( $this->get_all_cpts() as $slug => $object ) {
        $dynamic_keys[] = $slug . '_page_title';
        $dynamic_keys[] = $slug . '_page_description';
    }

    $mappings['surerank_global_setting'] = array_merge(
        $mappings['surerank_global_setting'],
        $dynamic_keys
    );

    return $mappings;
}
```

See `extended-meta-templates/controller.php` → `register_dynamic_option_keys()` for a full example.

---

## File Reference

| File | Purpose |
|------|---------|
| `mappings.php` | Single source of truth for all capability/option/submenu mappings |
| `init.php` | Hooks registration, settings filtering (`filter_settings_by_capability`), admin capability setup |
| `menus.php` | Admin submenu visibility based on capabilities |
| `api.php` | REST API endpoints for reading/saving role-manager settings |

---

## Common Mistakes

1. **Adding a setting to defaults but not to mappings** — The setting will be saved in DB but never returned by the API. This is the most common issue.

2. **Dynamic keys (e.g., extended-meta-templates)** — Keys generated at runtime based on registered post types/taxonomies cannot be hardcoded in mappings. Use the `surerank_role_manager_option_mappings` filter to register them dynamically (see section above).

3. **Forgetting both GET and UPDATE** — The filter runs on both directions. A missing key means users can't read OR write that setting through the API.
