> For the complete documentation index, see [llms.txt](https://playground.e107sk.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://playground.e107sk.com/plugin-dev-quick-notes/admin-ui/raw-code-in-admin-fields.md).

# Raw code in admin fields

## The 'code' data type

Notes on `e_admin_ui` / `e_admin_dispatcher` behaviour that is not obvious from the documentation, and that cost time to work out. Everything below was verified against the e107 core source (`e107inc/e107`, 2.4.x branch); line numbers are approximate and given as a pointer, not a promise.

***

### 1. Storing raw HTML/JS in a field: `'data' => 'code'`

**Symptom.** You paste a `<script>` snippet into an admin field and e107 refuses it:

> You don't have permission to use `<script>` tags. If you believe this is an error, please ask the main administrator to grant you script access via Preferences > Content Filters.

**Do not fix this by granting site-wide script access.** That loosens the content filter for the entire site because of one field.

#### Why it happens

A field declared `'data' => 'str'` goes through `e107_model::sanitize()` (`e107_handlers/model_class.php`):

```php
case 'str':
case 'string':
case 'array':
    $ret = $tp->toDB($value, false, false, 'model', ...);
```

`toDB()` calls `cleanHtml()`, which consults the site-wide `post_script` preference and strips script tags unless the current user's userclass passes `check_class()`.

#### The trap behind the trap

Granting script access **still would not work** for an AdSense-style snippet. The set of attributes e107 allows on a `<script>` tag is hardcoded in `e_parse_class.php`:

```php
'script' => array('type', 'src', 'language', 'async'),
```

`crossorigin` is not in that list, so `crossorigin="anonymous"` gets stripped anyway. There is no pref that changes this.

#### The fix

Use the `'code'` data type. It exists for exactly this purpose (`model_class.php`):

```php
case 'code':
    $ret = $tp->toDB($value, false, false, 'pReFs');
    break;
```

And in `toDB()` (`e_parse_class.php`):

```php
if ($mod !== 'pReFs') // XXX We're not saving prefs.
{
    $data = $this->preFilter($data);
    $data = $this->cleanHtml($data);   // skipped entirely for 'pReFs'
    ...
}
```

The core docblock above `toDB()` says it directly: the `'pReFs'` value is for internal use when saving prefs, to prevent sanitisation of HTML.

```php
'googleads_script' => array(
    'title' => LAN_..._SCRIPT,
    'type'  => 'textarea',
    'data'  => 'code',      // raw, unsanitised — see security note below
    'help'  => LAN_..._SCRIPT_HELP,
),
```

#### Security note

`'code'` means **zero sanitisation** on that field. It is stored-XSS-as-a-feature. Use it only when:

* the field genuinely has to hold raw markup (ad code, tracking snippets, embeds), **and**
* write access to the admin page is restricted to the main admin (`getperms('0')`).

Those two decisions depend on each other. If the permission is ever relaxed, `'code'` has to go with it. Say so in a comment above the field — the next person will not know.

***

### &#x20;
