set_basename( false, __FILE__ ); } elseif ( function_exists( 'dal_fs' ) ) { // A pre-2.5.15 build (legacy 3-letter prefix) of the paired free/premium // plugin is already loaded in this request. Both declare the same classes, // so continuing would fatal with "Cannot redeclare class". Stand down until // that build is updated. return; } else { /** * DO NOT REMOVE THIS IF, IT IS ESSENTIAL FOR THE * `function_exists` CALL ABOVE TO PROPERLY WORK. * * This whole plugin body — the Freemius bootstrap AND everything below it, * including the plugin class declarations — must live inside * this `else`. If the paired free/premium build has already loaded and defined * dawnal_fs() (both are the same PHP source, so they declare an identically-named * class), reaching the class declaration a second time in the same request is * a fatal "Cannot redeclare class" error, not a no-op. Freemius' own generated * integration instructions show exactly this nesting for that reason: only the * plugin variant that loaded FIRST keeps running until set_basename() lets * Freemius deactivate the other one on the next request. See v2.5.9 changelog. */ if ( !function_exists( 'dawnal_fs' ) ) { // Create a helper function for easy SDK access. function dawnal_fs() { global $dawnal_fs; if ( !isset( $dawnal_fs ) ) { // Include Freemius SDK. require_once dirname( __FILE__ ) . '/vendor/freemius/start.php'; $dawnal_fs = fs_dynamic_init( array( 'id' => '22620', 'slug' => 'rootlinkd', 'type' => 'plugin', 'public_key' => 'pk_bec5b92ce58e3ca90a289c5523e74', 'is_premium' => false, 'has_addons' => false, 'has_paid_plans' => true, 'is_org_compliant' => true, 'has_affiliation' => 'all', 'menu' => array( 'slug' => 'rootlinkd', 'support' => false, ), 'is_live' => true, ) ); } return $dawnal_fs; } // Init Freemius. dawnal_fs(); // Signal that SDK was initiated. do_action( 'dawnal_fs_loaded' ); } define( 'DAWNAL_VERSION', '2.5.24' ); define( 'DAWNAL_TIER_FREE', 'free' ); define( 'DAWNAL_TIER_PRO', 'pro' ); define( 'DAWNAL_TIER_BUSINESS', 'business' ); define( 'DAWNAL_TIER_DEVELOPER', 'developer' ); define( 'DAWNAL_OPT_PREFIX', 'dawnal_' ); define( 'DAWNAL_CACHE_KEY_RULES', 'dawnal_active_rules' ); define( 'DAWNAL_CACHE_TTL', 300 ); // ============================================================================= // Logging (NO OUTPUT EVER from activation) // ============================================================================= if ( !function_exists( 'dawnal_log' ) ) { function dawnal_log( $message, $context = [] ) { // Diagnostics only: writes nothing unless the site has WP_DEBUG and WP_DEBUG_LOG enabled. if ( !defined( 'WP_DEBUG' ) || !WP_DEBUG || !defined( 'WP_DEBUG_LOG' ) || !WP_DEBUG_LOG ) { return; } if ( !is_string( $message ) ) { $message = (string) wp_json_encode( $message ); } $line = '[rootlinkd] ' . $message; if ( !empty( $context ) ) { $line .= ' | ' . wp_json_encode( $context ); } // phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_error_log error_log( $line ); // phpcs:enable WordPress.PHP.DevelopmentFunctions.error_log_error_log } } if ( !function_exists( 'dawnal_set_activation_error' ) ) { function dawnal_set_activation_error( $message, $data = [] ) { update_option( 'dawnal_last_activation_error', sanitize_text_field( $message ), false ); update_option( 'dawnal_last_activation_error_data', wp_json_encode( $data ), false ); update_option( 'dawnal_last_activation_error_time', current_time( 'mysql' ), false ); dawnal_log( 'Activation error: ' . $message, $data ); } } // ============================================================================= // Main Plugin // ============================================================================= // ============================================================================= // Free / Premium code split // ============================================================================= require_once __DIR__ . '/includes/class-rootlinkd-free.php'; $dawnal_plugin_class = 'Dawnal_Free_Plugin'; /** * One-time migration from the legacy `dal_` prefix (pre-2.5.15) to `dawnal_`. * Copies stored options and post meta to the new names, then removes the old * rows. The rules table name (dawn_auto_links) is unchanged. Runs once per site. */ if ( !function_exists( 'dawnal_migrate_legacy_prefix' ) ) { function dawnal_migrate_legacy_prefix() { if ( get_option( 'dawnal_prefix_migrated' ) ) { return; } global $wpdb; // Explicit list so options belonging to any other plugin are never touched. $legacy_names = array( 'activated_successfully', 'activation_version', 'affiliate_tags', 'exclude_current_page', 'last_activation_error', 'last_activation_error_data', 'last_activation_error_time', 'link_chance', 'link_style', 'max_links_per_post', 'once_per_keyword', 'skip_first_paragraphs', 'trusted_domains' ); foreach ( $legacy_names as $name ) { $old_name = 'dal_' . $name; $value = get_option( $old_name, null ); if ( null === $value ) { continue; } if ( null === get_option( 'dawnal_' . $name, null ) ) { add_option( 'dawnal_' . $name, $value ); } delete_option( $old_name ); } delete_transient( 'dal_admin_notice' ); // Rename the per-post "disable auto-links" flag. One-time, runs once per site. // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.SlowDBQuery.slow_db_query_meta_key $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s", '_dal_disable' ) ); if ( !empty( $post_ids ) ) { $wpdb->update( $wpdb->postmeta, array( 'meta_key' => '_dawnal_disable', ), array( 'meta_key' => '_dal_disable', ), array('%s'), array('%s') ); foreach ( $post_ids as $post_id ) { wp_cache_delete( (int) $post_id, 'post_meta' ); } } // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.SlowDBQuery.slow_db_query_meta_key update_option( 'dawnal_prefix_migrated', DAWNAL_VERSION, false ); } } register_activation_hook( __FILE__, array($dawnal_plugin_class, 'activate_static') ); register_deactivation_hook( __FILE__, array($dawnal_plugin_class, 'deactivate_static') ); add_action( 'plugins_loaded', function () use($dawnal_plugin_class) { dawnal_migrate_legacy_prefix(); new $dawnal_plugin_class(); } ); // Deliberately no uninstall hook. Free and premium builds share the same table // and dawnal_* options so a normal upgrade cannot destroy the other build's data. } // end: Freemius basename guard — DO NOT hoist runtime code outside this else.