Manual:SessionManager and AuthManager/Adding fields to the registration form

From Linux Web Expert

The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

This is a simple (and somewhat silly) example showing how to use AuthManager to add extra fields to the registration form.

Step 1: define the fields with an authentication request object.

<?php

use MediaWiki\Auth\AuthenticationRequest;

class MyExtraFieldsAuthenticationRequest extends AuthenticationRequest {
    // Mark this AuthenticationRequest as optional.
    public $required = self::OPTIONAL;

    /** @var string */
    public $eyeColor;

    /** @var string */
    public $favoriteFood;

    public function getFieldInfo() {
        return [
            'eyeColor' => [
                'type' => 'string',
                'label' => wfMessage( 'eyecolor-label' ),
            ],
            'favoriteFood' => [
                'type' => 'string',
                'label' => wfMessage( 'favoritefood-label' ),
                'help' => wfMessage( 'favoritefood-help' ),
                // Marking the field as optional means the AuthenticationRequest can
                // be created if it's not present. Marking the AuthenticationRequest
                // as optional means authentication can proceed if it was not created.
                'optional' => true,
            ],
        ];
    }
}

Step 2: add a secondary authentication provider (a handler that is called when the User object representing the user becomes available) that signals the need for the request, and processes it:

<?php
use MediaWiki\Auth\AuthManager;
use MediaWiki\Auth\AbstractSecondaryAuthenticationProvider;
use MediaWiki\Auth\AuthenticationRequest;
use MediaWiki\Auth\AuthenticationResponse;

class MyExtraFieldsSecondaryAuthenticationProvider
    extends AbstractSecondaryAuthenticationProvider
{
    public function getAuthenticationRequests( $action, array $options ) {
        if ( $action === AuthManager::ACTION_CREATE ) {
            return [ new MyExtraFieldsAuthenticationRequest() ];
        }
        return [];
    }

    public function beginSecondaryAuthentication( $user, array $reqs ) {
        return AuthenticationResponse::newAbstain();
    }

    public function beginSecondaryAccountCreation( $user, $creator, array $reqs ) {
        $req = AuthenticationRequest::getRequestByClass( $reqs,
            MyExtraFieldsAuthenticationRequest::class );
        if ( !$req ) {
            // fields were left empty
            return AuthenticationResponse::newPass();
        }

        if ( $req->eyeColor === 'pink' ) {
            return AuthenticationResponse::newFail(
                wfMessage( 'error-wrong-eyecolor', $req->eyeColor ) );
        }

        // At this point, the user has been written into the database; $user->getId() is safe to use.
        MyExtraFieldsHandler::saveExtraFields( $user, $req->eyeColor, $req->favoriteFood );

        return AuthenticationResponse::newPass();
    }
}

Step 3 (optional): add a hook for customizing the presentation of the fields (see HTMLForm for the syntax of $formDescriptor):

<?php

class MyExtraFieldsHooks {
    public static function onAuthChangeFormFields(
        array $requests, array $fieldInfo, array &$formDescriptor, $action
    ) {
        if ( isset( $formDescriptor['eyeColor'] ) ) {
            $formDescriptor['eyeColor']['cssclass'] = 'eye-color';
        }
    }
}

Step 4: register the provider (and the hook if it was added):

    ...
    "AuthManagerAutoConfig": {
        "secondaryauth": {
            "MyExtraFieldsSecondaryAuthenticationProvider": {
                "class": "MyExtraFieldsSecondaryAuthenticationProvider",
                "sort": 0
             }
        }
    },
    "Hooks": {
        ...
        "AuthChangeFormFields": "MyExtraFieldsHooks::onAuthChangeFormFields"
    },
    ...