---
title: Constants
---

`mantle.php` defines these constants when the plugin file loads, before any class is instantiated. Three are guarded with `if ( ! defined( … ) )` and can therefore be overridden from `wp-config.php`; the rest are unconditional.

## Overridable

<!-- wp:docspress/fields {"title":"Overridable constants","description":"Guarded by <code>if ( ! defined( … ) )</code>. Define these in <code>wp-config.php</code> before WordPress loads plugins.","fields":[{"name":"MANTLE_PLUGIN_DEBUG","type":"boolean","required":false,"defaultValue":"false","description":"Enables plugin debug behaviour.","values":"true, false","deprecated":false},{"name":"MANTLE_PLUGIN_DEV_MODE","type":"boolean","required":false,"defaultValue":"false","description":"Enables development-mode behaviour.","values":"true, false","deprecated":false},{"name":"MANTLE_SSO_PREFLIGHT_SALT","type":"string","required":false,"defaultValue":"mantle-sso-preflight-salt","description":"Salt used when signing SSO preflight requests. The default is a literal committed to the repository, so it is identical on every site that does not override it.","values":"","deprecated":false}],"searchable":false,"compact":false} /-->

<!-- wp:docspress/callout {"tone":"danger","title":"Override MANTLE_SSO_PREFLIGHT_SALT before enabling SSO","content":"<p>Because the default value ships in the source, every installation that does not override it shares the same signing salt. Define a unique random value per site — and a different one per environment — before switching the <code>sso</code> module on.</p>","collapsible":false} /-->

## Fixed

These are defined unconditionally, so a value set earlier in `wp-config.php` produces a PHP notice about redefinition rather than taking effect.

<!-- wp:docspress/fields {"title":"Fixed constants","description":"Defined unconditionally in <code>mantle.php</code>.","fields":[{"name":"MANTLE_PLUGIN_VERSION","type":"string","required":false,"defaultValue":"2.1.23","description":"Managed by release-please via an inline marker comment. Compared against the stored <code>version</code> setting to decide whether migrations run.","values":"","deprecated":false},{"name":"MANTLE_PLUGIN_NAME","type":"string","required":false,"defaultValue":"Mantle","description":"Display name.","values":"","deprecated":false},{"name":"MANTLE_PLUGIN_FILE","type":"string","required":false,"defaultValue":"","description":"Absolute path to <code>mantle.php</code> from <code>__FILE__</code>.","values":"","deprecated":false},{"name":"MANTLE_PLUGIN_PATH","type":"string","required":false,"defaultValue":"","description":"Plugin directory path from <code>plugin_dir_path()</code>. Trailing slash included.","values":"","deprecated":false},{"name":"MANTLE_PLUGIN_URL","type":"string","required":false,"defaultValue":"","description":"Plugin directory URL from <code>plugin_dir_url()</code>.","values":"","deprecated":false},{"name":"MANTLE_API_URL","type":"url","required":false,"defaultValue":"https://api.linchpin.com/api/v1","description":"Linchpin API base URL used for site reporting and connection.","values":"","deprecated":false},{"name":"MANTLE_SHOP_URI","type":"url","required":false,"defaultValue":"https://shop.linchpin.com","description":"Licence server used for activation, deactivation, and uninstall.","values":"","deprecated":false},{"name":"MANTLE_SHOP_PRODUCT_ID","type":"number","required":false,"defaultValue":"1616","description":"Mantle's product ID on the licence server.","values":"","deprecated":false}],"searchable":true,"compact":false} /-->

## WordPress constants Mantle sets

<!-- wp:docspress/fields {"title":"Core constants","description":"Not Mantle-prefixed, but set by Mantle.","fields":[{"name":"DISALLOW_FILE_EDIT","type":"boolean","required":false,"defaultValue":"true","description":"Mantle forces this to <code>true</code> unless it is already defined, disabling the plugin and theme file editors in the admin.","values":"true, false","deprecated":false}],"searchable":false,"compact":true} /-->

<!-- wp:docspress/callout {"tone":"warning","title":"DISALLOW_FILE_EDIT is a side effect of activating Mantle","content":"<p>Installing Mantle silently removes <strong>Appearance → Theme File Editor</strong> and <strong>Plugins → Plugin File Editor</strong>. This is intentional hardening, but it surprises people. To keep the editors, define <code>DISALLOW_FILE_EDIT</code> as <code>false</code> in <code>wp-config.php</code> before plugins load.</p>","collapsible":false} /-->

## Constants Mantle reads but never defines

The SSO module checks these with `defined()` at runtime. They exist nowhere in `mantle.php`, so a site that does not declare them simply takes the documented default.

<!-- wp:docspress/fields {"title":"SSO constants","description":"Declare these in <code>wp-config.php</code>. Each one overrides the equivalent stored setting, which is what makes them usable to recover a site whose settings are wrong.","fields":[{"name":"MANTLE_SSO_DISABLE","type":"boolean","required":false,"defaultValue":"false","description":"Registers none of the SSO hooks, whatever the module state says. The last resort when SSO itself is what is broken.","values":"true, false","deprecated":false},{"name":"MANTLE_SSO_AUTO_REDIRECT","type":"boolean","required":false,"defaultValue":"false","description":"Pins the automatic wp-login.php to SSO redirect on or off, overriding the sso_auto_redirect setting. Ignored when the site has no site_secret.","values":"true, false","deprecated":false},{"name":"MANTLE_SSO_BYPASS_TOKEN","type":"string","required":false,"defaultValue":"linchpin","description":"Value the bypass query parameter must carry to reach the standard login form while the automatic redirect is on.","values":"","deprecated":false},{"name":"MANTLE_SSO_DISALLOW_ALL_DIRECT_LOGIN","type":"boolean","required":false,"defaultValue":"false","description":"Rejects username and password authentication for every account and disables password resets. SSO becomes the only way in.","values":"true, false","deprecated":false},{"name":"MANTLE_SSO_DEFAULT_ROLE","type":"string","required":false,"defaultValue":"subscriber","description":"Role given to an SSO user that org-unit mapping and the domain allowlist both decline to match.","values":"","deprecated":false},{"name":"MANTLE_SSO_GRANT_SUPER_ADMIN","type":"boolean","required":false,"defaultValue":"false","description":"Multisite only. Grants super admin to newly provisioned SSO users.","values":"true, false","deprecated":false}],"searchable":true,"compact":false} /-->

<!-- wp:docspress/callout {"tone":"warning","title":"Know the way back in before switching the redirect on","content":"<p>With <code>sso_auto_redirect</code> active, <code>wp-login.php</code> no longer renders a form — every anonymous visit is handed to Google. The escape hatch is <code>wp-login.php?bypass=linchpin</code>, and it is deliberately a plain query parameter so it still works when nothing else does. If SSO is broken badly enough that even the handoff fails, define <code>MANTLE_SSO_AUTO_REDIRECT</code> as <code>false</code> in <code>wp-config.php</code>.</p>","collapsible":false} /-->

## Overriding constants

<!-- wp:docspress/colorful-code {"language":"php","filename":"wp-config.php","code":"// Unique per site and per environment.\ndefine( 'MANTLE_SSO_PREFLIGHT_SALT', 'replace-with-a-unique-random-string' );\n\n// Optional: verbose plugin debugging on a staging site.\ndefine( 'MANTLE_PLUGIN_DEBUG', true );\n\n// Optional: keep the WordPress file editors.\ndefine( 'DISALLOW_FILE_EDIT', false );\n\n/* That's all, stop editing! Happy publishing. */\nrequire_once ABSPATH . 'wp-settings.php';","highlightedLines":"2,11","showLineNumbers":true,"caption":"Definitions must appear above the wp-settings.php require.","copyMode":"all","diffMode":"none","annotations":[{"line":2,"content":"Generate this with a password manager or <code>wp eval 'echo wp_generate_password( 64, false );'</code>."},{"line":11,"content":"Anything defined after this line is too late — plugins have already loaded."}]} /-->

## Dependency loading

Two further behaviours in `mantle.php` are worth knowing when debugging a fatal error on boot.

<!-- wp:docspress/flow {"start":1,"steps":[{"title":"Composer autoloader","content":"<p>If <code>vendor/autoload.php</code> exists it is included and the returned <code>ClassLoader</code> is retained.</p>"},{"title":"AI Client de-shadowing","content":"<p>When WordPress core ships <code>wp-includes/php-ai-client/src/AiClient.php</code> and the plugin also has a copy, Mantle calls <code>setPsr4( 'WordPress\\\\AiClient\\\\', [] )</code> to unregister its own prefix so core's copy wins. Loading both causes class and interface conflicts.</p>"},{"title":"Scoped dependencies","content":"<p>If <code>third-party/vendor/autoload.php</code> exists it is required. These are PHP-Scoper-prefixed dependencies, isolated to avoid clashing with other plugins.</p>"},{"title":"Boot","content":"<p><code>mantle_init()</code> runs on <code>plugins_loaded</code>, instantiates <code>Core\\Bootstrap</code>, and calls <code>run()</code>.</p>"}]} /-->

<!-- wp:docspress/callout {"tone":"note","title":"PHP-Scoper does not copy Composer files autoload entries","content":"<p>Because scoping drops <code>files</code> autoload entries, bootstraps that would normally load automatically are required by hand in <code>mantle.php</code>. If you add a dependency whose bootstrap relies on a <code>files</code> entry, load it explicitly.</p>","collapsible":false} /-->

## See also

- [Configuration](../getting-started/configuration.md) — how these relate to the settings option.
