'read_only', 'variant' => 'success', 'label' => __( 'Read-only', 'agent-abilities-for-mcp' ), ); } if ( aafm_high_risk_unlocked() ) { return array( 'state' => 'high_risk_unlocked', 'variant' => 'warn', 'label' => __( 'Read + write, high-risk unlocked', 'agent-abilities-for-mcp' ), ); } return array( 'state' => 'read_write', 'variant' => 'neutral', 'label' => __( 'Read + write', 'agent-abilities-for-mcp' ), ); } /** * Record a change to the read-only mode switch. * * Mirrors aafm_log_high_risk_switch_change(): the ability column carries a synthetic ability-like * name because both the admin table and its AJAX re-render put that value straight into the Event * cell, so a blank one renders as a blank row. * * @param bool $before Previous value. * @param bool $after New value. * @param bool $persisted Whether the write actually took (aafm_persist_operator_switch()). * @return void */ function aafm_log_read_only_switch_change( bool $before, bool $after, bool $persisted = true ): void { if ( $before === $after && $persisted ) { return; } $user = wp_get_current_user(); if ( $persisted ) { $detail = $after ? __( 'Read-only mode turned on', 'agent-abilities-for-mcp' ) : __( 'Read-only mode turned off', 'agent-abilities-for-mcp' ); } else { // The write did not take (a stale persistent object cache, see // aafm_persist_operator_switch()). Recording "turned off" here would be the silent wrong // answer this log exists to prevent, so the row says what actually happened. $detail = $after ? __( 'Read-only mode could not be turned on: object cache stale', 'agent-abilities-for-mcp' ) : __( 'Read-only mode could not be turned off: object cache stale', 'agent-abilities-for-mcp' ); } $row_id = aafm_log_activity( array( 'ability' => 'aafm/read-only-mode', 'principal_user_id' => (int) $user->ID, 'principal_login' => $user->user_login ? (string) $user->user_login : '', 'status' => $persisted ? 'success' : 'error', 'event_type' => 'setting_changed', 'detail' => $detail, ) ); if ( $persisted && $before !== $after ) { aafm_notify_switch_flip( $after ? 'read_only_on' : 'read_only_off', $row_id ); } } /** * Persist the read-only mode switch. * * Off deletes the row rather than storing a falsy value: off is the option's out-of-the-box state, * and an explicit false is a state a fresh install can never be in. Same reasoning, and the same * fix, as the high-risk switch in 1.5.0. The write goes through aafm_persist_operator_switch(), which * also clears any stale persistent-cache copy and reads the value back. * * @param bool $on Whether read-only mode should be on. * @return bool True when the mode now reads back as $on. */ function aafm_set_read_only_mode( bool $on ): bool { return aafm_persist_operator_switch( 'aafm_read_only_mode', $on ); }