$new Previously unseen ability names. * @param list $modified Abilities whose definition changed. * @param array $details Definitions either side of each change, * and the WordPress version at this scan * and the last. */ public function record( array $new, array $modified, array $details = array() ): void { $wp = isset( $details['wp'] ) && is_array( $details['wp'] ) ? $details['wp'] : array(); $changed = isset( $details['changed'] ) && is_array( $details['changed'] ) ? $details['changed'] : array(); foreach ( $changed as $name => $sides ) { if ( ! is_array( $sides ) ) { continue; } $this->append( (string) $name, array( 'drift' => 'changed', 'before' => isset( $sides['before'] ) && is_array( $sides['before'] ) ? $sides['before'] : null, 'after' => isset( $sides['after'] ) && is_array( $sides['after'] ) ? $sides['after'] : array(), 'wp' => $wp, ) ); } $fresh = isset( $details['new'] ) && is_array( $details['new'] ) ? $details['new'] : array(); foreach ( $fresh as $name => $definition ) { if ( ! is_array( $definition ) ) { continue; } $this->append( (string) $name, array( 'drift' => 'new', // Nothing preceded it; the field is present so every // drifted row reads the same way. 'before' => null, 'after' => $definition, 'wp' => $wp, ) ); } } /** * Append one drift row through the chained writer. * * @param string $ability_name Namespaced ability name. * @param array $result What drifted, and into what. */ private function append( string $ability_name, array $result ): void { try { $this->writer->append( array( 'ts' => new DateTimeImmutable( 'now' ), // No agent and no user: a scan on wp_loaded noticed this, and // crediting whoever happened to be browsing would be a lie. 'agent_id' => 0, 'wp_user_id' => 0, 'source' => self::SOURCE, 'action_cat' => 'read', 'entity_type' => 'ability', // The ability is named by ability_name; entity_id is numeric. 'entity_id' => null, 'ability_name' => $ability_name, 'status' => self::STATUS, 'input' => null, 'result' => $result, 'policy_id' => null, 'rule_index' => null, ) ); } catch ( LedgerUnavailable $busy ) { // What this row records has already happened, so failing the // request would not undo it. The row is skipped, as it was before // ADR-17 whenever an insert failed. return; } } }