Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
11 / 11
CRAP
100.00% covered (success)
100.00%
1 / 1
Schema
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
11 / 11
12
100.00% covered (success)
100.00%
1 / 1
 as_string
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 as_array
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 as_assoc_array
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 as_boolean
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 as_number
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 as_float
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 enum
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 any_json_data
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 as_void
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 as_unsafe_any
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 either
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace Automattic\Jetpack\Schema;
4
5use Automattic\Jetpack\Schema\Modifiers\Modifier_Fallback;
6use Automattic\Jetpack\Schema\Types\Type_Any;
7use Automattic\Jetpack\Schema\Types\Type_Any_JSON;
8use Automattic\Jetpack\Schema\Types\Type_Array;
9use Automattic\Jetpack\Schema\Types\Type_Assoc_Array;
10use Automattic\Jetpack\Schema\Types\Type_Boolean;
11use Automattic\Jetpack\Schema\Types\Type_Enum;
12use Automattic\Jetpack\Schema\Types\Type_Float;
13use Automattic\Jetpack\Schema\Types\Type_Number;
14use Automattic\Jetpack\Schema\Types\Type_String;
15use Automattic\Jetpack\Schema\Types\Type_Void;
16
17/**
18 * The Schema class is a factory for creating and managing validation rules based on specific
19 * schema types. It is a central point for defining the structure of your data
20 * and ensuring that it conforms to the expected format.
21 *
22 * The class provides static methods for creating Schema instances with different data types,
23 * making it easy to build complex validation rules with a clean and readable syntax.
24 *
25 * The purpose of the Schema class is to provide a consistent way to parse structured data.
26 *
27 * Use this to ensure that your data adheres to the defined schema and avoid issues
28 * caused by incorrect data types or missing properties.
29 *
30 * How to use the Schema class:
31 *
32 * 1. Define your schema structure using the static methods provided by the Schema
33 *    class, such as `as_string()`, `as_array()`, `as_boolean()`, `as_number()`,
34 *    `as_float()`, and `enum()`. These methods return Schema instances
35 *    for the respective data types.
36 *
37 * 2. Optionally, you can chain additional methods on the Schema instances
38 *    to further customize the validation behavior. For example, you can use
39 *    `fallback()` to specify a default value when the input data is invalid or
40 *    `nullable()` to allow null values.
41 *
42 * 3. Parse your data using the Schema instances. Call the `parse()` method on the
43 *    Schema instance, passing in the input data to be parsed.
44 *    The method will return the parsed data or a default
45 *    value (if specified) when the input data is invalid.
46 *
47 * Example:
48 *
49 * $my_schema = Schema::as_array(
50 *     [
51 *         'name' => Schema::as_string(),
52 *         'age' => Schema::as_number()->fallback(0),
53 *         'is_active' => Schema::as_boolean()->nullable(),
54 *         'tags' => Schema::as_array(Schema::as_string())
55 *     ]
56 * );
57 *
58 * $input_data = [
59 *     'name' => 'John Doe',
60 *     'age' => 30,
61 *     'is_active' => null,
62 *     'tags' => ['tag1', 'tag2']
63 * ];
64 *
65 * $parsed_data = $my_schema->parse($input_data);
66 */
67class Schema {
68    const PACKAGE_VERSION = '0.3.0';
69
70    public static function as_string() {
71        return new Schema_Parser( new Type_String() );
72    }
73
74    /**
75     * @param Parser $parser - The parser to apply to each array item when $data is parsed.
76     *
77     * @return Schema_Parser
78     */
79    public static function as_array( Parser $parser ) {
80        return new Schema_Parser( new Type_Array( $parser ) );
81    }
82
83    /**
84     * @param array $assoc_parser_array - An associative array of ["key" => "Parser"] pairs
85     *
86     * @return Schema_Parser
87     */
88    public static function as_assoc_array( $assoc_parser_array ) {
89        return new Schema_Parser( new Type_Assoc_Array( $assoc_parser_array ) );
90    }
91
92    public static function as_boolean() {
93        return new Schema_Parser( new Type_Boolean() );
94    }
95
96    public static function as_number() {
97        return new Schema_Parser( new Type_Number() );
98    }
99
100    public static function as_float() {
101        return new Schema_Parser( new Type_Float() );
102    }
103
104    /**
105     * @param array $allowed_values - An array of values that are allowed for this enum.
106     *
107     * @return Schema_Parser
108     */
109    public static function enum( $allowed_values ) {
110        return new Schema_Parser( new Type_Enum( $allowed_values ) );
111    }
112
113    public static function any_json_data() {
114        return new Schema_Parser( new Type_Any_JSON() );
115    }
116
117    /**
118     * Mark a schema as void - it should have no data worth keeping, and
119     * will always parse to null.
120     */
121    public static function as_void() {
122        return new Schema_Parser( new Type_Void() );
123    }
124
125    /**
126     * Use With Caution! This will not parse the data - it will simply return it as-is.
127     * This is useful for delivering read-only data that we don't need to parse server-side.
128     *
129     * @see Type_Any
130     */
131    public static function as_unsafe_any() {
132        return new Schema_Parser( new Type_Any() );
133    }
134
135    /**
136     * @var \Automattic\Jetpack\Schema\Parser $parser - The parser to apply to each array item when $data is parsed.
137     */
138    public static function either( ...$parsers ) {
139        $or = new Modifier_Fallback();
140        foreach ( $parsers as $parser ) {
141            $or->add_fallback_parser( $parser );
142        }
143        return new Schema_Parser( $or );
144    }
145}