set_basename( false, __FILE__ );
} else {
// DO NOT REMOVE THIS IF — essential for the function_exists() call above.
if ( !function_exists( 'answerrails_fs' ) ) {
/**
* Freemius SDK accessor (#95). Snippet taken VERBATIM from the
* dashboard SDK Integration page (product 35635, 2026-08-10) with
* ONE deliberate divergence: the require path is ours — the SDK is
* vendored at includes/lib/vendor/freemius/ (FREEMIUS_SDK_PATH_DESIGN
* D1, #354, superseding DD1's includes/lib/freemius/). The `vendor`
* segment is what Plugin Check's directory ignore keys on; a ROOT
* vendor/freemius would be excluded from the shipped zip by
* release.yml's anchored /vendor rule. Pinned SDK — see the
* AGENTS.md release-checklist rider.
*/
function answerrails_fs() {
global $answerrails_fs;
if ( !isset( $answerrails_fs ) ) {
// Include Freemius SDK (#354 D1 path — see accessor doc above).
require_once dirname( __FILE__ ) . '/includes/lib/vendor/freemius/start.php';
// The SDK's STANDARD FREEMIUM CONFIGURATION — the snippet
// Freemius's own documentation gives for a product with a
// WordPress.org edition and a separately sold one, shipped
// unchanged by many directory plugins.
//
// What it does NOT do: no value here is consulted by any
// feature in this plugin. Nothing in this codebase asks the
// SDK what the site has bought in order to decide what to
// run, and the four values below configure the SDK's own
// account and update screens, nothing else.
//
// AnswerRails Pro is a SEPARATE PLUGIN, downloaded from
// answerrails.com; `premium_suffix` is the name the SDK gives
// that download, and `has_paid_plans` tells the SDK that
// download is sold. `is_org_compliant` is true because this
// source also produces the WordPress.org edition — the
// deployment processor generates it from here, which is also
// what removes `wp_org_gatekeeper` below and the one
// module-loading block in class-answerrails-plugin.php.
$answerrails_fs = fs_dynamic_init( array(
'id' => '35635',
'slug' => 'answerrails',
'type' => 'plugin',
'public_key' => 'pk_55ddcf8a369e6a30b6596d56fbaf2',
'is_premium' => false,
'premium_suffix' => '(Pro)',
'has_addons' => false,
'has_paid_plans' => true,
'is_org_compliant' => true,
'menu' => array(
'slug' => 'answerrails',
'support' => false,
),
'is_live' => true,
) );
}
return $answerrails_fs;
}
// Init Freemius.
answerrails_fs();
/**
* Opt-in screen copy (#95 — D2 Option A, customised).
* The CLAIMS are fixed here for the #101 consistency set: names
* Freemius and the exact data categories, never claims or implies
* "no external calls" (AI providers are called on every grounded
* turn regardless of opt-in state), states skippability plainly,
* no invented numbers, no "anonymous" claim (a site URL is
* identifying). Final wording lands with solicitor-reviewed #101
* text. Same message on install and update: the categories are
* identical either way.
*/
function answerrails_fs_connect_message(
$message,
$user_first_name,
$product_title,
$user_login,
$site_link,
$freemius_link
) {
return sprintf(
'%1$s
%2$s
%3$s',
esc_html__( 'Help improve AnswerRails — your choice.', 'answerrails' ),
esc_html__( 'Opt in to share diagnostic data with Freemius, the licensing platform AnswerRails is built on: your site address, WordPress and PHP versions, and plugin activation events. This helps us support your configuration and know which WordPress versions to test. No visitor conversations, no knowledge-base content, and no chat data are ever included.', 'answerrails' ),
esc_html__( 'Skip this and AnswerRails works exactly the same.', 'answerrails' )
);
}
answerrails_fs()->add_filter(
'connect_message',
'answerrails_fs_connect_message',
10,
6
);
answerrails_fs()->add_filter(
'connect_message_on_update',
'answerrails_fs_connect_message',
10,
6
);
/**
* Plugin icon for the SDK's screens (opt-in / activation / notices).
* Without this the SDK copies its grey-plug placeholder to
* includes/lib/vendor/freemius/assets/img/answerrails.png at runtime (that
* path is gitignored — it is a runtime artefact either way; the SDK
* copies whatever this filter returns there). The brand icon lives
* in OUR assets so SDK upgrades never touch it.
*/
function answerrails_fs_plugin_icon() {
return dirname( __FILE__ ) . '/assets/images/answerrails-icon-256.png';
}
answerrails_fs()->add_filter( 'plugin_icon', 'answerrails_fs_plugin_icon' );
// Signal that the SDK was initiated.
do_action( 'answerrails_fs_loaded' );
}
// Define plugin constants (inside the else deliberately: during the
// free↔paid swap the first-loaded build's constants win, and the
// second main file never reaches this branch).
define( 'ANSWERRAILS_VERSION', '1.0.1' );
define( 'ANSWERRAILS_PLUGIN_FILE', __FILE__ );
define( 'ANSWERRAILS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'ANSWERRAILS_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'ANSWERRAILS_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
define( 'ANSWERRAILS_DIR', ANSWERRAILS_PLUGIN_DIR );
// For compatibility
define( 'ANSWERRAILS_URL', ANSWERRAILS_PLUGIN_URL );
// For compatibility
// LOAD CRITICAL UTILITIES IMMEDIATELY - before any class definitions
require_once ANSWERRAILS_PLUGIN_DIR . 'includes/class-answerrails-utils.php';
require_once ANSWERRAILS_PLUGIN_DIR . 'includes/class-answerrails-retrieval.php';
// #92 engine resolver (depends on Utils)
// Main plugin class + accessor (extracted per #95 — the
// step-18 double-load must never redeclare a top-level class).
require_once ANSWERRAILS_PLUGIN_DIR . 'includes/class-answerrails-plugin.php';
// Uninstall lifecycle (#127): cleanup rides the SDK's after_uninstall
// action — NEVER uninstall.php. WP core gives that file absolute
// precedence: it would delete the SDK's registered uninstall hook,
// silencing the Freemius uninstall event and the free/premium
// sibling-build guard. UninstallLifecycleTest pins both halves
// (this registration present; uninstall.php absent).
// Design: docs/design/UNINSTALL_LIFECYCLE_DESIGN.md (D1).
require_once ANSWERRAILS_PLUGIN_DIR . 'includes/class-answerrails-uninstall.php';
answerrails_fs()->add_action( 'after_uninstall', array('AnswerRails_Uninstall', 'run') );
// Start the plugin.
answerrails();
}