1, 'parser' => 1 ); foreach ( array( 'declared_source' => self::SOURCES, 'declared_edition' => self::EDITIONS, 'family' => self::FAMILIES, 'encoding' => array( 'utf8', 'unknown' ), 'delimiter' => array( 'comma', 'semicolon', 'tab', 'none' ), 'size' => self::BUCKETS, 'rows' => self::BUCKETS ) as $key => $enum ) { $out[ $key ] = self::member( $input[ $key ], $enum ); } $out['bom'] = $input['bom']; $out['incomplete'] = $input['incomplete']; $out['issues'] = array(); $out['nodes'] = array(); if ( ! is_array( $input['issues'] ) || array_values( $input['issues'] ) !== $input['issues'] || count( $input['issues'] ) > 9 || count( array_unique( $input['issues'], SORT_REGULAR ) ) !== count( $input['issues'] ) ) { throw new \InvalidArgumentException( 'report_issues' ); } foreach ( $input['issues'] as $issue ) { $out['issues'][] = self::member( $issue, self::ISSUES ); } if ( ! is_array( $input['nodes'] ) || array_values( $input['nodes'] ) !== $input['nodes'] || count( $input['nodes'] ) > 30 ) { throw new \InvalidArgumentException( 'report_nodes' ); } foreach ( $input['nodes'] as $i => $node ) { if ( ! is_array( $node ) ) { throw new \InvalidArgumentException( 'report_node' ); } self::keys( $node, array( 'ordinal', 'semantic', 'types', 'email_like', 'phone_like', 'date_like', 'count' ) ); if ( $node['ordinal'] !== $i + 1 || ! is_array( $node['types'] ) || array_values( $node['types'] ) !== $node['types'] || count( $node['types'] ) > 7 || count( array_unique( $node['types'], SORT_REGULAR ) ) !== count( $node['types'] ) ) { throw new \InvalidArgumentException( 'report_node' ); } $safe = array( 'ordinal' => $i + 1, 'semantic' => self::member( $node['semantic'], self::SEMANTICS ), 'types' => array(), 'count' => self::member( $node['count'], self::BUCKETS ) ); foreach ( $node['types'] as $type ) { $safe['types'][] = self::member( $type, self::TYPES ); } foreach ( array( 'email_like', 'phone_like', 'date_like' ) as $flag ) { if ( ! is_bool( $node[ $flag ] ) ) { throw new \InvalidArgumentException( 'report_flag' ); } $safe[ $flag ] = $node[ $flag ]; } $out['nodes'][] = $safe; } return $out; } public static function decode( string $json ): array { if ( strlen( $json ) > self::LIMIT ) { throw new \InvalidArgumentException( 'report_size' ); } $decoded = json_decode( $json, false, 10, JSON_THROW_ON_ERROR ); if ( ! $decoded instanceof \stdClass || ! is_array( $decoded->issues ?? null ) || ! is_array( $decoded->nodes ?? null ) ) { throw new \InvalidArgumentException( 'report_shape' ); } $value = (array) $decoded; foreach ( $value['nodes'] as $i => $node ) { if ( ! $node instanceof \stdClass ) { throw new \InvalidArgumentException( 'report_node' ); } $value['nodes'][ $i ] = (array) $node; } return self::validate( $value ); } public static function body( array $report ): string { return "Abientot compatibility report\n" . wp_json_encode( self::validate( $report ), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . "\n"; } }