* - select: <select>
* - checkbox: <input type="checkbox">
* - multiselect: More a grid of checkboxes than <select multi>
- * - button: <input type="image"> if 'image' is set, otherwise <input type="submit">
- * (uses 'label' as button text)
+ * - button: <input type="submit"> (uses 'label' as button text)
* - hidden: Not visible to the user, but needs to be preserved for the next request
* - null: No widget, just display the 'label' message.
* - options: (array) Maps option values to Messages for the
* 'select' and 'multiselect' types.
* - value: (string) Value (for 'null' and 'hidden') or default value (for other types).
- * - image: (string) URL of an image to use in connection with the input
* - label: (Message) Text suitable for a label in an HTML form
* - help: (Message) Text suitable as a description of what the field is
* - optional: (bool) If set and truthy, the field may be left empty
public static function mergeFieldInfo( array $reqs ) {
$merged = [];
+ // fields that are required by some primary providers but not others are not actually required
+ $primaryRequests = array_filter( $reqs, function ( $req ) {
+ return $req->required === AuthenticationRequest::PRIMARY_REQUIRED;
+ } );
+ $sharedRequiredPrimaryFields = array_reduce( $primaryRequests, function ( $shared, $req ) {
+ $required = array_keys( array_filter( $req->getFieldInfo(), function ( $options ) {
+ return empty( $options['optional'] );
+ } ) );
+ if ( $shared === null ) {
+ return $required;
+ } else {
+ return array_intersect( $shared, $required );
+ }
+ }, null );
+
foreach ( $reqs as $req ) {
$info = $req->getFieldInfo();
if ( !$info ) {
}
foreach ( $info as $name => $options ) {
- if ( $req->required !== self::REQUIRED ) {
+ if (
// If the request isn't required, its fields aren't required either.
+ $req->required === self::OPTIONAL
+ // If there is a primary not requiring this field, no matter how many others do,
+ // authentication can proceed without it.
+ || $req->required === self::PRIMARY_REQUIRED
+ && !in_array( $name, $sharedRequiredPrimaryFields, true )
+ ) {
$options['optional'] = true;
} else {
$options['optional'] = !empty( $options['optional'] );