Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 57
0.00% covered (danger)
0.00%
0 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
JCValue
0.00% covered (danger)
0.00%
0 / 57
0.00% covered (danger)
0.00%
0 / 13
1892
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getValue
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setValue
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 status
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 sameAsDefault
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 defaultUsed
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 isMissing
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isUnchecked
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 error
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 setField
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
42
 deleteField
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
72
 fieldExists
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
42
 getField
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2namespace JsonConfig;
3
4use InvalidArgumentException;
5use Message;
6
7/**
8 * A class with validation state that wraps each accessed value in the JCObjContent::validationData
9 * @package JsonConfig
10 */
11final class JCValue {
12
13    /** @var int */
14    private $status;
15    /** @var mixed */
16    private $value;
17    /** @var bool|null */
18    private $sameAsDefault = false;
19    /** @var bool|null */
20    private $defaultUsed = false;
21    /** @var bool|Message */
22    private $error = false;
23
24    /** Value has not been checked */
25    public const UNCHECKED = 0;
26    /** Value was explicitly checked (might be an error) */
27    public const CHECKED = 1;
28    /** field is missing in the data, but is being explicitly tested for.
29     * This value should never be stored in JCObjContent::validationData.
30     * Setting this value for any field in validator will delete it.
31     */
32    public const MISSING = 2;
33    /** field was not explicitly tested, but it was listed as a parent of one of the tested fields */
34    public const VISITED = 3;
35
36    /**
37     * @param int $status
38     * @param mixed $value
39     */
40    public function __construct( $status, $value ) {
41        $this->status = $status;
42        $this->value = $value;
43    }
44
45    /** @return mixed */
46    public function & getValue() {
47        return $this->value;
48    }
49
50    public function setValue( $value, $status = null ) {
51        $this->value = $value;
52        if ( $status !== null ) {
53            $this->status( $status );
54        } elseif ( $this->isMissing() ) {
55            // Convenience - if we are setting a new value, assume we are setting a default
56            $this->status( self::UNCHECKED );
57            $this->defaultUsed( true );
58        }
59    }
60
61    public function status( $status = null ) {
62        $val = $this->status;
63        if ( $status !== null ) {
64            $this->status = $status;
65        }
66        return $val;
67    }
68
69    public function sameAsDefault( $sameAsDefault = null ) {
70        $val = $this->sameAsDefault;
71        if ( $sameAsDefault !== null ) {
72            $this->sameAsDefault = $sameAsDefault;
73        }
74        return $val;
75    }
76
77    public function defaultUsed( $defaultUsed = null ) {
78        $val = $this->defaultUsed;
79        if ( $defaultUsed !== null ) {
80            $this->defaultUsed = $defaultUsed;
81        }
82        return $val;
83    }
84
85    public function isMissing() {
86        return $this->status === self::MISSING;
87    }
88
89    public function isUnchecked() {
90        return $this->status === self::UNCHECKED;
91    }
92
93    /** Helper function - same arguments as wfMessage, or true if message was already added.
94     * false clears this message status, and null returns current state without changing it
95     * @param null|bool|string $key message id, or if bool, sets/removes error status
96     * @param array|null $fieldPath path to the erroneous field. Will be converted to a/b/c[0]/d style
97     * @param mixed ...$params
98     * @return bool|Message
99     */
100    public function error( $key = null, $fieldPath = null, ...$params ) {
101        if ( is_bool( $key ) ) {
102            $this->error = $key;
103        } elseif ( $key !== null ) {
104            $args = func_get_args();
105            if ( is_array( $fieldPath ) ) {
106                // Convert field path to a printable string
107                $args[1] = JCUtils::fieldPathToString( $fieldPath );
108            }
109            // @phan-suppress-next-line PhanParamTooFewUnpack
110            $this->error = wfMessage( ...$args );
111        }
112        return $this->error;
113    }
114
115    /**
116     * @param string|int $fld
117     * @param mixed $value
118     */
119    public function setField( $fld, $value ) {
120        if ( is_object( $this->value ) && is_string( $fld ) ) {
121            $this->value->$fld = $value;
122        } elseif ( is_array( $this->value ) && ( is_string( $fld ) || is_int( $fld ) ) ) {
123            $this->value[$fld] = $value;
124        } else {
125            throw new InvalidArgumentException( 'Type mismatch for field ' . $fld );
126        }
127    }
128
129    /**
130     * @param string|int $fld
131     * @return mixed
132     */
133    public function deleteField( $fld ) {
134        $tmp = null;
135        if ( is_object( $this->value ) && is_string( $fld ) ) {
136            if ( isset( $this->value->$fld ) ) {
137                $tmp = $this->value->$fld;
138                unset( $this->value->$fld );
139            }
140        } elseif ( is_array( $this->value ) && ( is_string( $fld ) || is_int( $fld ) ) ) {
141            if ( isset( $this->value[$fld] ) ) {
142                $tmp = $this->value[$fld];
143                unset( $this->value[$fld] );
144            }
145        } else {
146            throw new InvalidArgumentException( 'Type mismatch for field ' . $fld );
147        }
148        return $tmp;
149    }
150
151    /**
152     * @param string|int $fld
153     * @return bool
154     */
155    public function fieldExists( $fld ) {
156        if ( is_object( $this->value ) && is_string( $fld ) ) {
157            return property_exists( $this->value, $fld );
158        } elseif ( is_array( $this->value ) && ( is_string( $fld ) || is_int( $fld ) ) ) {
159            return array_key_exists( $fld, $this->value );
160        }
161        throw new InvalidArgumentException( 'Type mismatch for field ' . $fld );
162    }
163
164    /**
165     * @param string|int $fld
166     * @return mixed
167     */
168    public function getField( $fld ) {
169        if ( is_object( $this->value ) && is_string( $fld ) ) {
170            return $this->value->$fld;
171        } elseif ( is_array( $this->value ) && ( is_string( $fld ) || is_int( $fld ) ) ) {
172            return $this->value[$fld];
173        }
174        throw new InvalidArgumentException( 'Type mismatch for field ' . $fld );
175    }
176}