dbname.'|'.$wpdb->prefix),0,40); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- OrderGuard's own tables or exact transactional reads/writes; no WordPress API covers these; must read current database state (locks, claims, delete checks); caching would be wrong if((string)$wpdb->get_var($wpdb->prepare('SELECT GET_LOCK(%s, 0)',$lock))!=='1' || $wpdb->last_error!==''){ self::saveDiagnostic('installation_unconfirmed','unavailable'); return array('status'=>'unavailable','code'=>'installation_unconfirmed','dispatch_enabled'=>false); } try{return self::executeLocked($mode);} // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- OrderGuard's own tables or exact transactional reads/writes; no WordPress API covers these; must read current database state (locks, claims, delete checks); caching would be wrong finally{$wpdb->get_var($wpdb->prepare('SELECT RELEASE_LOCK(%s)',$lock));} } private static function executeLocked(string $mode): array { global $wpdb; if($mode==='upgrade' && OG_Native_Legacy_Gate::state()==='legacy'){self::preserveLegacyManualFlagDefault();} $blog=get_current_blog_id();$prefix=$wpdb->prefix;$db=$wpdb; try {$context=new OG_Owned_WordPress_Context($wpdb,false);$result=$mode==='upgrade'?$context->prepareUpgrade():$context->installFresh();} catch(Throwable $e) {$result=array('status'=>'unavailable','reason'=>'installation_unconfirmed');} $reason=$result['reason']??null; $allowed=array('migration_required','existing_composition_refused','connection_unavailable','wordpress_prefix_mismatch'); $code=$result['status']==='installed'?'installed_sources_pending':($result['status']==='active'?'already_active':($result['status']==='prepared'?'upgrade_prepared_cutover_pending': ($result['status']==='unknown'?'installation_outcome_unknown':(in_array($reason,$allowed,true)?$reason:'installation_unconfirmed')))); // Bounded operational diagnostic only; never consulted for admission. // Failure to persist it cannot turn a storage refusal into success. $saved=false; if ($wpdb===$db && get_current_blog_id()===$blog && $wpdb->prefix===$prefix) { $saved=self::saveDiagnostic($code,$result['status']); } return array('status'=>$result['status'],'code'=>$code,'diagnostic_saved'=>$saved,'dispatch_enabled'=>false,'lifecycle'=>$result['lifecycle']??null); } private static function saveDiagnostic(string $code,string $status): bool { $previous=get_option(self::OPTION); $record=array('version'=>1,'code'=>$code); if(is_array($previous) && ($previous['activation_pending']??false)===true && !in_array($status,array('installed','prepared','active'),true)){ $record['activation_pending']=true; } return update_option(self::OPTION,$record,false) || get_option(self::OPTION)===$record; } private static function run($nonce,string $mode): array { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- request method is only compared with the fixed string 'POST' if (($_SERVER['REQUEST_METHOD']??'')!=='POST' || !is_user_logged_in() || !current_user_can('activate_plugins') || !current_user_can('manage_options') || !is_string($nonce) || !wp_verify_nonce($nonce,'orderguard_owned_install:'.get_current_blog_id())) { return array('status'=>'forbidden'); } return self::execute($mode); } public static function request($nonce): array {return self::run($nonce,'fresh');} public static function requestUpgrade($nonce): array {return self::run($nonce,'upgrade');} /** WordPress activation is already a privileged core lifecycle event. */ public static function activate($networkWide=false): array { if($networkWide===true || (function_exists('is_multisite') && is_multisite())){ return array('status'=>'unavailable','code'=>'multisite_not_supported','dispatch_enabled'=>false,'lifecycle'=>null); } // Retry intent only: installFresh still proves no legacy data/work exists. // Reuse the setup diagnostic excluded from the fresh-install inventory. update_option(self::OPTION,array('version'=>1,'code'=>'installation_unconfirmed','activation_pending'=>true),false); $result=self::execute('fresh'); if(($result['code']??null)==='migration_required'){$result=self::execute('upgrade');} self::recordVersion($result); return $result; } /** Normal setup outcomes (Astra, 6 October 2026): never a global warning. * They are historical records, not proof of current readiness. */ const ROUTINE_CODES=array('installed_sources_pending','already_active','upgrade_prepared_cutover_pending'); /** Real setup problems: plain-language warning on the relevant screens. */ const PROBLEM_CODES=array('migration_required','multisite_not_supported','existing_composition_refused','connection_unavailable', 'wordpress_prefix_mismatch','installation_outcome_unknown','installation_unconfirmed'); /** The stored diagnostic code, or null. Presentation only; never authority. */ public static function recordedCode(): ?string { $record=get_option(self::OPTION); if(!is_array($record) || ($record['version']??null)!==1 || !is_string($record['code']??null)){return null;} return in_array($record['code'],array_merge(self::ROUTINE_CODES,self::PROBLEM_CODES),true)?$record['code']:null; } public static function outcomeText(string $code): string { $texts=array( 'installed_sources_pending'=>__('Setup finished on this site. Waiting for: OrderGuard to confirm this store’s privacy setup. This record does not mean sharing with the OrderGuard network is ready, and nothing is shared because of it. Next step: nothing to do now; if OrderGuard support asks, give them the support reference below.','orderguard'), 'already_active'=>__('OrderGuard’s storage was already set up when OrderGuard was activated again. This is a record of that earlier setup, not a check that everything works now.','orderguard'), 'upgrade_prepared_cutover_pending'=>__('This store was updated from an earlier OrderGuard version and its new storage is prepared. It keeps using the earlier erasure system until a supervised switch-over, which never starts by itself. This is a record of the update, not a confirmation that sharing is ready.','orderguard'), 'migration_required'=>__('OrderGuard could not finish preparing data from an earlier version on this site. Nothing was removed. Contact OrderGuard support.','orderguard'), 'multisite_not_supported'=>__('OrderGuard does not support WordPress multisite networks. Use it on a single WordPress site.','orderguard'), 'existing_composition_refused'=>__('OrderGuard found its storage in an unexpected state and stopped setup. Nothing was removed. Contact OrderGuard support before changing anything.','orderguard'), 'connection_unavailable'=>__('OrderGuard could not use the database during setup. Nothing was removed. Ask your host to check the database, then reload this page to try again.','orderguard'), 'wordpress_prefix_mismatch'=>__('OrderGuard’s storage does not match this site’s database table prefix. Nothing was removed. Contact OrderGuard support before changing anything.','orderguard'), 'installation_outcome_unknown'=>__('OrderGuard could not confirm whether setup finished. Nothing was removed. Reload this page to try again; if this message stays, contact OrderGuard support.','orderguard'), 'installation_unconfirmed'=>__('OrderGuard setup has not finished on this site, and nothing is shared until it does. Reload this page to try again; if this message stays, contact OrderGuard support.','orderguard'), ); return $texts[$code]??''; } public static function registerNotices(): void { static $registered=false;if($registered){return;}$registered=true; add_action('admin_init',array(self::class,'guardPendingAdminWrites'),0); $notice=static function() { if(!current_user_can('manage_options') && !current_user_can('manage_network_options')){return;} $code=self::recordedCode(); // Normal outcomes show only as status on the OrderGuard Account tab. if($code===null || !in_array($code,self::PROBLEM_CODES,true)){return;} // Real problems: Dashboard, Plugins and OrderGuard's own screens. $screen=function_exists('get_current_screen')?get_current_screen():null; $id=is_object($screen)?(string)$screen->id:''; if($id!=='' && !in_array($id,array('dashboard','dashboard-network','plugins','plugins-network'),true) && strpos($id,'orderguard')===false){return;} /* translators: %s: support reference code */ echo '
'.esc_html__('OrderGuard setup:','orderguard').' '.esc_html(self::outcomeText($code)).' '.esc_html(sprintf(__('Support reference: %s','orderguard'),$code)).'
'.esc_html__('Erasure system now:','orderguard').' '.esc_html(OG_Native_Erasure_Text::lifecycle($state)).'
'; if($code!==null){ echo ''.esc_html__('Last recorded setup outcome:','orderguard').' '.esc_html(self::outcomeText($code)).'
'; /* translators: %s: support reference code */ echo ''.esc_html(sprintf(__('Support reference: %s','orderguard'),$code)).'
'; } echo '