HEX
Server: LiteSpeed
System: Linux node612.namehero.net 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64
User: dfwparty (1186)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: //home/dfwparty/dfwchat.net/wp-content/plugins/buddyboss-tools/includes/class-bb-tools.php
<?php
/**
 * BuddyBoss Tools — main singleton.
 *
 * @package BuddyBoss\Tools
 * @since 1.0.0
 */

defined( 'ABSPATH' ) || exit;

/**
 * Main BuddyBoss Tools class.
 *
 * @since 1.0.0
 */
final class BB_Tools {

	/**
	 * Singleton instance.
	 *
	 * @var BB_Tools|null
	 */
	private static $instance = null;

	/**
	 * Whether boot has run.
	 *
	 * @var bool
	 */
	private $booted = false;

	/**
	 * Get the singleton instance.
	 *
	 * @since 1.0.0
	 *
	 * @return BB_Tools
	 */
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Boot the plugin.
	 *
	 * Attempted on `plugins_loaded @ 10` and again on `bp_loaded` (which fires
	 * after Platform is fully up, e.g. under BUDDYPRESS_LATE_LOAD). Loads
	 * dependencies, runs the Platform-version probe, and registers hooks.
	 *
	 * Idempotent: the `$booted` flag is only set once the probe passes, so a
	 * failed early attempt can be retried by a later hook while a successful
	 * boot never runs its real work twice. If the probe fails, an admin notice
	 * is registered (self-suppressing if a later attempt succeeds) and the
	 * method returns without registering anything else.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function boot() {
		if ( $this->booted ) {
			return;
		}

		require_once BB_TOOLS_PLUGIN_DIR . 'includes/class-bb-tools-requirements.php';

		if ( ! BB_Tools_Requirements::check() ) {
			// Platform missing, too old, or lacks the Settings 2.0 Tools
			// panel slot probe. Don't mark as booted — a later hook
			// (bp_loaded) may retry once Platform has finished loading.
			// Surface an admin notice in case no attempt ever succeeds; the
			// notice re-checks requirements at render time and self-suppresses
			// if a later attempt boots successfully.
			BB_Tools_Requirements::register_admin_notice();
			return;
		}

		$this->booted = true;

		require_once BB_TOOLS_PLUGIN_DIR . 'includes/class-bb-tools-migration-registry.php';
		require_once BB_TOOLS_PLUGIN_DIR . 'includes/bb-tools-functions.php';
		require_once BB_TOOLS_PLUGIN_DIR . 'includes/bb-tools-filters.php';

		require_once BB_TOOLS_PLUGIN_DIR . 'sample-data/class-bb-tools-sample-data.php';
		BB_Tools_Sample_Data::instance();

		// Forum-import orchestrator (BB_Tools_BBP_Converter + base class +
		// bb_tools_bbp_new_converter factory). The 22 vendor converter classes in
		// migration/buddyboss-forums/converters/ are autoload-style — bb_tools_bbp_new_converter()
		// require_once's each one on demand. Load order matters — must be loadable
		// before migration source bootstraps (which register cards referencing vendor names)
		// run via the bb_tools_after_register_migration_sources hook.
		require_once BB_TOOLS_PLUGIN_DIR . 'migration/buddyboss-forums/class-bb-tools-bbp-converter.php';

		// BB_Tools_Forum_Import — subclass that owns the new AJAX surface
		// (status / save_settings / tick / halt / reset) and the buffered
		// converter_response() override. Instance call wires hooks via setup_actions().
		require_once BB_TOOLS_PLUGIN_DIR . 'migration/buddyboss-forums/class-bb-tools-forum-import.php';
		BB_Tools_Forum_Import::instance();

		$this->discover_migration_sources();

		/**
		 * Fires after all bundled and third-party migration sources are loaded.
		 *
		 * @since 1.0.0
		 */
		do_action( 'bb_tools_after_register_migration_sources' );
	}

	/**
	 * Discover migration sources by scanning migration/{vendor}/{vendor}.php.
	 *
	 * One-level flat scan. Each bootstrap file is `require_once`'d inside a
	 * try/catch so a single broken vendor cannot take down all of Tools.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	private function discover_migration_sources() {
		$vendor_dirs = glob( BB_TOOLS_PLUGIN_DIR . 'migration/*', GLOB_ONLYDIR );
		if ( false === $vendor_dirs || empty( $vendor_dirs ) ) {
			return;
		}

		foreach ( $vendor_dirs as $vendor_dir ) {
			$bootstrap = $vendor_dir . '/' . basename( $vendor_dir ) . '.php';
			if ( ! is_readable( $bootstrap ) ) {
				continue;
			}
			try {
				require_once $bootstrap;
			} catch ( \Throwable $e ) {
				if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
					// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Gated on WP_DEBUG; surfaces broken migration vendors without taking down Tools.
					error_log(
						sprintf(
							'BB Tools: failed to load migration "%s": %s',
							basename( $vendor_dir ),
							$e->getMessage()
						)
					);
				}
				continue;
			}
		}
	}
}