Merge "Relax phpdoc of PermissionError to match actual usage"
[lhc/web/wiklou.git] / includes / specialpage / AuthManagerSpecialPage.php
index 85b8dc3..bdf7638 100644 (file)
@@ -43,7 +43,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
         * Change the form descriptor that determines how a field will look in the authentication form.
         * Called from fieldInfoToFormDescriptor().
         * @param AuthenticationRequest[] $requests
-        * @param string $fieldInfo Field information array (union of all
+        * @param array $fieldInfo Field information array (union of all
         *    AuthenticationRequest::getFieldInfo() responses).
         * @param array $formDescriptor HTMLForm descriptor. The special key 'weight' can be set to
         *    change the order of the fields.
@@ -205,6 +205,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
        /**
         * Return custom message key.
         * Allows subclasses to customize messages.
+        * @param string $defaultKey
         * @return string
         */
        protected function messageKey( $defaultKey ) {
@@ -536,7 +537,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
                $form->setAction( $this->getFullTitle()->getFullURL( $this->getPreservedParams() ) );
                $form->addHiddenField( $this->getTokenName(), $this->getToken()->toString() );
                $form->addHiddenField( 'authAction', $this->authAction );
-               $form->suppressDefaultSubmit( !$this->needsSubmitButton( $formDescriptor ) );
+               $form->suppressDefaultSubmit( !$this->needsSubmitButton( $requests ) );
 
                return $form;
        }
@@ -554,24 +555,46 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
        }
 
        /**
-        * Returns true if the form has fields which take values. If all available providers use the
-        * redirect flow, the form might contain nothing but submit buttons, in which case we should
-        * not add an extra submit button which does nothing.
+        * Returns true if the form built from the given AuthenticationRequests needs a submit button.
+        * Providers using redirect flow (e.g. Google login) need their own submit buttons; if using
+        * one of those custom buttons is the only way to proceed, there is no point in displaying the
+        * default button which won't do anything useful.
         *
-        * @param array $formDescriptor A HTMLForm descriptor
+        * @param AuthenticationRequest[] $requests An array of AuthenticationRequests from which the
+        *  form will be built
         * @return bool
         */
-       protected function needsSubmitButton( $formDescriptor ) {
-               return (bool)array_filter( $formDescriptor, function ( $item ) {
-                       $class = false;
-                       if ( array_key_exists( 'class', $item ) ) {
-                               $class = $item['class'];
-                       } elseif ( array_key_exists( 'type', $item ) ) {
-                               $class = HTMLForm::$typeMappings[$item['type']];
+       protected function needsSubmitButton( array $requests ) {
+               $customSubmitButtonPresent = false;
+
+               // Secondary and preauth providers always need their data; they will not care what button
+               // is used, so they can be ignored. So can OPTIONAL buttons createdby primary providers;
+               // that's the point in being optional. Se we need to check whether all primary providers
+               // have their own buttons and whether there is at least one button present.
+               foreach ( $requests as $req ) {
+                       if ( $req->required === AuthenticationRequest::PRIMARY_REQUIRED ) {
+                               if ( $this->hasOwnSubmitButton( $req ) ) {
+                                       $customSubmitButtonPresent = true;
+                               } else {
+                                       return true;
+                               }
                        }
-                       return !is_a( $class, \HTMLInfoField::class, true ) &&
-                               !is_a( $class, \HTMLSubmitField::class, true );
-               } );
+               }
+               return !$customSubmitButtonPresent;
+       }
+
+       /**
+        * Checks whether the given AuthenticationRequest has its own submit button.
+        * @param AuthenticationRequest $req
+        * @return bool
+        */
+       protected function hasOwnSubmitButton( AuthenticationRequest $req ) {
+               foreach ( $req->getFieldInfo() as $field => $info ) {
+                       if ( $info['type'] === 'button' ) {
+                               return true;
+                       }
+               }
+               return false;
        }
 
        /**
@@ -646,6 +669,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
         * Maps an authentication field configuration for a single field (as returned by
         * AuthenticationRequest::getFieldInfo()) to a HTMLForm field descriptor.
         * @param array $singleFieldInfo
+        * @param string $fieldName
         * @return array
         */
        protected static function mapSingleFieldInfo( $singleFieldInfo, $fieldName ) {