Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.94% covered (success)
93.94%
31 / 33
66.67% covered (warning)
66.67%
4 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Type_Assoc_Array
93.94% covered (success)
93.94%
31 / 33
66.67% covered (warning)
66.67%
4 / 6
19.08
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 parse
94.12% covered (success)
94.12%
16 / 17
0.00% covered (danger)
0.00%
0 / 1
10.02
 is_sequential_array
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 __toString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 jsonSerialize
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 schema
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace Automattic\Jetpack\Schema\Types;
4
5use Automattic\Jetpack\Schema\Parser;
6use Automattic\Jetpack\Schema\Schema_Error;
7use Automattic\Jetpack\Schema\Utils;
8
9class Type_Assoc_Array implements Parser {
10    private $parser;
11
12    /**
13     * Assoc Array type takes in a parser in the constructor and
14     * will parse each keyed value in the array using the parser.
15     *
16     * @param Parser[] $assoc_parser_array - An associative array of parsers to use.
17     * @throws Schema_Error - Only in Debug mode: if the $assoc_parser_array is not an associative array.
18     */
19    public function __construct( $assoc_parser_array ) {
20        $this->parser = $assoc_parser_array;
21        if ( ! is_array( $assoc_parser_array ) && Utils::is_debug() ) {
22            $message = "Expected an associative array of parsers, received '" . gettype( $assoc_parser_array ) . "'";
23            throw new Schema_Error( $message, $assoc_parser_array );
24        }
25    }
26
27    /**
28     * This parse method expects that the $data passed to it is
29     * an associative array of values.
30     *
31     * It will then loop over each key that was provided in the constructor
32     * and pull the value based on that key from the $data array.
33     *
34     * @param array|object $value
35     *
36     * @return array
37     * @throws Schema_Error - If the $data passed to it is not an associative array.
38     */
39    public function parse( $value, $context ) {
40        // Allow coercing stdClass objects (often returned from json_decode) to an assoc array.
41        if ( is_object( $value ) && $value instanceof \stdClass ) {
42            $value = (array) $value;
43        }
44
45        if ( ! is_array( $value ) || $this->is_sequential_array( $value ) ) {
46            $message = "Expected an associative array, received '" . gettype( $value ) . "'";
47            throw new Schema_Error( $message, $value );
48        }
49        $output = array();
50        foreach ( $this->parser as $key => $parser ) {
51
52            if ( null !== $context ) {
53                $context->add_to_path( $key );
54            }
55
56            if ( ! isset( $value[ $key ] ) ) {
57                $value[ $key ] = null;
58            }
59
60            $parsed = $parser->parse( $value[ $key ], $context );
61            // @TODO Document this behavior.
62            // At the moment, values that are null are dropped from assoc arrays.
63            // to match the Zod behavior.
64            if ( $parsed !== null ) {
65                $output[ $key ] = $parsed;
66            }
67
68            if ( null !== $context ) {
69                $context->remove_path( $key );
70            }
71        }
72
73        return $output;
74    }
75
76    private function is_sequential_array( $arr ) {
77        if ( array() === $arr ) {
78            return false;
79        }
80        return array_keys( $arr ) === range( 0, count( $arr ) - 1 );
81    }
82
83    public function __toString() {
84        return 'assoc_array';
85    }
86
87    /**
88     * @return string
89     */
90    #[\ReturnTypeWillChange]
91    public function jsonSerialize() {
92        return $this->schema();
93    }
94
95    public function schema() {
96        $results = array();
97        foreach ( $this->parser as $key => $parser ) {
98            $results[ $key ] = $parser->schema();
99        }
100        return array(
101            'type'  => 'assoc_array',
102            'value' => $results,
103        );
104    }
105}