*/ private array $sync_pairs; private string $logging_level; private bool $automatic_url_replacement; private string $conflict_strategy; /** * @param array $sync_pairs Sync pairs. */ private function __construct( array $sync_pairs, string $logging_level, bool $automatic_url_replacement, string $conflict_strategy ) { $this->sync_pairs = $sync_pairs; $this->logging_level = $logging_level; $this->automatic_url_replacement = $automatic_url_replacement; $this->conflict_strategy = $conflict_strategy; } /** * @param array $data Raw settings data. */ public static function fromArray( array $data ): self { $logging_level = self::sanitizeChoice( $data['logging_level'] ?? 'warning', self::LOGGING_LEVELS, 'warning' ); $conflict_strategy = self::sanitizeChoice( $data['conflict_strategy'] ?? 'last_write_wins', self::CONFLICT_STRATEGIES, 'last_write_wins' ); $automatic_url_replacement = array_key_exists( 'automatic_url_replacement', $data ) ? self::sanitizeBoolean( $data['automatic_url_replacement'] ) : true; return new self( self::sanitizeSyncPairs( $data['sync_pairs'] ?? array() ), $logging_level, $automatic_url_replacement, $conflict_strategy ); } /** * @return array */ public function syncPairs(): array { return $this->sync_pairs; } public function loggingLevel(): string { return $this->logging_level; } public function automaticUrlReplacementEnabled(): bool { return $this->automatic_url_replacement; } public function conflictStrategy(): string { return $this->conflict_strategy; } /** * @return array */ public function toArray(): array { return array( 'sync_pairs' => $this->sync_pairs, 'logging_level' => $this->logging_level, 'automatic_url_replacement' => $this->automatic_url_replacement, 'conflict_strategy' => $this->conflict_strategy, ); } /** * @param mixed $value Value to sanitize. * @param array $allowed Allowed values. */ private static function sanitizeChoice( $value, array $allowed, string $fallback ): string { $sanitized = sanitize_text_field( (string) $value ); return in_array( $sanitized, $allowed, true ) ? $sanitized : $fallback; } /** * @param mixed $value Value to normalize. */ private static function sanitizeBoolean( $value ): bool { if ( is_bool( $value ) ) { return $value; } $normalized = strtolower( sanitize_text_field( (string) $value ) ); return in_array( $normalized, array( '1', 'true', 'yes', 'on' ), true ); } /** * @param mixed $pairs Raw sync pairs. * @return array */ private static function sanitizeSyncPairs( $pairs ): array { if ( ! is_array( $pairs ) ) { return array(); } $sanitized = array(); foreach ( $pairs as $pair ) { if ( ! is_array( $pair ) ) { continue; } $name = sanitize_text_field( (string) ( $pair['name'] ?? '' ) ); $source_url = esc_url_raw( (string) ( $pair['source_url'] ?? '' ) ); $destination_url = esc_url_raw( (string) ( $pair['destination_url'] ?? '' ) ); if ( '' === $name || '' === $source_url || '' === $destination_url ) { continue; } $sanitized[] = array( 'name' => $name, 'source_url' => $source_url, 'destination_url' => $destination_url, ); } return $sanitized; } }