12use UnexpectedValueException;
102 return get_called_class();
177 $fields = array_filter( $this->
getFieldInfo(),
static function ( $info ) {
178 return $info[
'type'] !==
'null';
184 foreach ( $fields as $field => $info ) {
189 if ( $info[
'type'] ===
'checkbox' || $info[
'type'] ===
'button' ) {
190 $this->$field = ( isset( $data[$field] ) && $data[$field] !== false )
191 || ( isset( $data[
"{$field}_x"] ) && $data[
"{$field}_x"] !== false );
192 if ( !$this->$field && empty( $info[
'optional'] ) ) {
199 if ( !isset( $data[$field] ) && $info[
'type'] ===
'multiselect' ) {
203 if ( !isset( $data[$field] ) ) {
206 if ( $data[$field] ===
'' || $data[$field] === [] ) {
207 if ( empty( $info[
'optional'] ) ) {
211 switch ( $info[
'type'] ) {
213 if ( !isset( $info[
'options'][$data[$field]] ) ) {
219 $data[$field] = (array)$data[$field];
221 $allowed = array_keys( $info[
'options'] );
222 if ( array_diff( $data[$field], $allowed ) !== [] ) {
229 $this->$field = $data[$field];
256 return StatusValue::newGood();
279 'provider' =>
new RawMessage(
'$1', [ get_called_class() ] ),
293 foreach ( $reqs as $req ) {
294 if ( $req->loadFromSubmission( $data ) ) {
313 $requests = array_filter( $reqs,
static function ( $req ) use ( $class, $allowSubclasses ) {
314 if ( $allowSubclasses ) {
315 return is_a( $req, $class,
false );
317 return get_class( $req ) === $class;
321 return count( $requests ) === 1 ? reset( $requests ) :
null;
336 foreach ( $reqs as $req ) {
337 $info = $req->getFieldInfo();
338 if ( $info && array_key_exists(
'username', $info ) && $req->username !==
null ) {
341 $otherClass = get_class( $req );
342 } elseif (
$username !== $req->username ) {
343 $requestClass = get_class( $req );
344 throw new UnexpectedValueException(
"Conflicting username fields: \"{$req->username}\" from "
346 .
"$requestClass::\$username vs. \"$username\" from $otherClass::\$username" );
364 $sharedRequiredPrimaryFields =
null;
365 foreach ( $reqs as $req ) {
366 if ( $req->required !== self::PRIMARY_REQUIRED ) {
370 foreach ( $req->getFieldInfo() as $fieldName => $options ) {
371 if ( empty( $options[
'optional'] ) ) {
375 if ( $sharedRequiredPrimaryFields ===
null ) {
376 $sharedRequiredPrimaryFields =
$required;
378 $sharedRequiredPrimaryFields = array_intersect( $sharedRequiredPrimaryFields,
$required );
382 foreach ( $reqs as $req ) {
383 $info = $req->getFieldInfo();
388 foreach ( $info as $name => $options ) {
391 $req->required === self::OPTIONAL
394 || ( $req->required === self::PRIMARY_REQUIRED
396 && !in_array( $name, $sharedRequiredPrimaryFields,
true ) )
398 $options[
'optional'] =
true;
400 $options[
'optional'] = !empty( $options[
'optional'] );
403 $options[
'sensitive'] = !empty( $options[
'sensitive'] );
404 $type = $options[
'type'];
406 if ( !array_key_exists( $name, $merged ) ) {
407 $merged[$name] = $options;
408 } elseif ( $merged[$name][
'type'] !== $type ) {
409 throw new UnexpectedValueException(
"Field type conflict for \"$name\", " .
410 "\"{$merged[$name]['type']}\" vs \"$type\""
413 if ( isset( $options[
'options'] ) ) {
414 if ( isset( $merged[$name][
'options'] ) ) {
415 $merged[$name][
'options'] += $options[
'options'];
418 $merged[$name][
'options'] = $options[
'options'];
423 $merged[$name][
'optional'] = $merged[$name][
'optional'] && $options[
'optional'];
424 $merged[$name][
'sensitive'] = $merged[$name][
'sensitive'] || $options[
'sensitive'];
443 foreach ( $data as $k => $v ) {
Generic operation result class Has warning/error list, boolean status and arbitrary value.